vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式。
vue组件中关系说明:
如上图所示, a与b、a与c、b与d、c与e组件之间是父子关系; b与c之间是兄弟关系;a与d、a与e之间是隔代关系; d与e是堂兄关系(非直系亲属) 针对以上关系我们归类为:
父子组件之间通信
非父子组件之间通信(兄弟组件、隔代关系组件等)
一、props / $emit
父组件通过props的方式向子组件传递数据,而通过$emit 子组件可以向父组件通信。
1、父组件向子组件传值
父组件如何向子组件传递数据:在子组件article.vue中如何获取父组件section.vue中的数据articles
// section父组件<template> <p class="section"> <com-article :articles="articlelist"></com-article> </p></template><script>import comarticle from './test/article.vue'export default { name: 'helloworld', components: { comarticle }, data() { return { articlelist: ['one', 'two', 'three','four','fives'] } }}</script>// 子组件 article.vue<template> <p> <span v-for="(item, index) in articles" :key="index">{{item}}</span> </p></template><script>export default { props: ['articles']}</script>总结: prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop 只读,不可被修改,所有修改都会失效并警告。
2. 子组件向父组件传值
对于$emit 我自己的理解是这样的: $emit绑定一个自定义事件, 当这个语句被执行时, 就会将参数arg传递给父组件,父组件通过v-on监听并接收参数。 通过一个例子,说明子组件如何向父组件传递数据。 在上个例子的基础上, 点击页面渲染出来的ariticle的item, 父组件中显示在数组中的下标
// 父组件中<template> <p class="section"> <com-article :articles="articlelist" @onemitindex="onemitindex"></com-article> <p>{{currentindex}}</p> </p></template><script>import comarticle from './test/article.vue'export default { name: 'helloworld', components: { comarticle }, data() { return { currentindex: -1, articlelist: ['one', 'two', 'three','four','fives'] } }, methods: { onemitindex(idx) { this.currentindex = idx } }}</script><template> <p> <p v-for="(item, index) in articles" :key="index" @click="emitindex(index)">{{item}}</p> </p></template><script>export default { props: ['articles'], methods: { emitindex(index) { this.$emit('onemitindex', index) } }}</script>// 父组件中<template> <p class="hello_world"> <p>{{msg}}</p> <com-a></com-a> <button @click="changea">点击改变子组件值</button> </p></template><script>import coma from './test/coma.vue'export default { name: 'helloworld', components: { coma }, data() { return { msg: 'welcome' } }, methods: { changea() { // 获取到子组件a this.$children[0].messagea = 'this is new value' } }}</script>// 子组件中<template> <p class="com_a"> <span>{{messagea}}</span> <p>获取父组件的值为: {{parentval}}</p> </p></template><script>export default { data() { return { messagea: 'this is old' } }, computed:{ parentval(){ return this.$parent.msg; } }}</script> 要注意边界情况,如在#app上拿$parent得到的是new vue()的实例,在这实例上再拿$parent得到的是undefined,而在最底层的子组件拿$children是个空数组。也要注意得到$parent和$children的值不一样,$children 的值是数组,而$parent是个对象
总结
上面两种方式用于父子组件之间的通信, 而使用props进行父子组件通信更加普遍; 二者皆不能用于非父子组件之间的通信。
三、provide/ inject
概念:
provide/ inject 是vue2.2.0新增的api, 简单来说就是父组件中通过provide来提供变量, 然后再子组件中通过inject来注入变量。
注意: 这里不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中回去数据
举例验证
接下来就用一个例子来验证上面的描述: 假设有三个组件: a.vue、b.vue、c.vue 其中 c是b的子组件,b是a的子组件
// a.vue<template> <p> <comb></comb> </p></template><script> import comb from '../components/test/comb.vue' export default { name: "a", provide: { for: "demo" }, components:{ comb } }</script>// b.vue<template> <p> {{demo}} <comc></comc> </p></template><script> import comc from '../components
行高和列宽在哪里设置 行高和列宽的设置方法云服务器能挂网页游戏吗腾讯云一元服务器怎么续费生鲜电商:一半海水,一半火焰什么是云服务器ecs 云服务器到底好不好用制作品牌网站时要凸出几大特点七字母域名竟以六位数价格交易 买家果真是终端!阿里云服务器租用1t一年多