父子通信
rops和emit
父组件通过props传递数据给子组件,子组件通过emit发送事件传递给父组件。
// 父组件 <div> <child :data="child" @send="getFromChild"></child> </div> ata(){ return{ toChild: '大儿子', fromChild: '' } }, methods: { getFromChild(val){ this.fromChild=val } } // 子组件 <div @click="toParent">{{data}}</div> prps:[data], methods: { toParent(){ this.$emit('send', '给父亲') } }
v-model
v-model其实是props,emit的语法糖,v-model默认会解析成名为value的prop和名为input的事件。
// 父组件 <children v-model="msg"></children> <p>{{msg}}</p> daa(){ return{ msg:'model' } } // 子组件 <input :value="value" @input="toInput" /> prop: ['value'], methods: { toInput(e){ this.$emit('input', e.target.value) } }
$children和$parent
在父组件使用$children访问子组件,在子组件中使用$parent访问父组件
// 父组件 <child /> data){ return { msg: '父组件数据' } }, methods: { test(){ console.log('我是父组件的方法,被执行') } }, mounted(){ console.log(this.$children[0].child_msg); // 执行子组件方法 } // 子组件 <div>{{$parent.msg}}</div> data() return{ child_msg: '子组件数据' } }, mounted(){ // 子组件执行父组件方法 this.$parent.test(); }
.sync方式
在vue1.x中是对prop进行双向绑定,在vue2只允许单向数据流,也是一个语法糖
// 父组件 <child :count.sync="num" /> data() return { num: 0 } } // 子组件 <div @click="handleAdd">add</div> data(){ return { counter: this.count } }, props: ["count"], methods: { handleAdd(){ this.$emit('update:count', ++this.counter) } }
跨多层次组件通信
依赖注入
可以使用provide/inject,虽然文档中不推荐直接使用在业务中。
假设有父组件A,然后有一个跨多层次的子组件B
// 父组件A export default{ provide: { data: 1 } } // 子组件B export default{ inject: ['data'], mounted(){ // 无论跨几层都能获取父组件的data属性 console.log(this.data); // 1 } }
$listeners和$attrs
$attrs--包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
inheritAttrs--默认值true,继承所有父组件属性(除props),为true会将attrs中的属性当做html的data属性渲染到dom根节点上
$listeners--包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,v-on="$listeners"将所有事件监听器指向这个组件的某个特定子元素
// 父组件 <children :child1="child1" :child2="child2" @test1="onTest1" @test2="onTest2"></children> data(){ return { child1: 'childOne', child2: 'childTwo' } }, methods: { onTest1(){ console.log('test1 running') }, onTest2(){ console.log('test2 running') } } // 子组件 <p>{child1}}</p> <child v-bind="$attrs" v-on="$listeners"></child> props: ['cild1'], mounted(){ this.$emit('test1') } // 孙组件 <p>{{hild2}</p> <p>{{$attrs}}</p> props: ['chid2'], mounted(){ this.$emit('test2') }
任意组件
可以用Vuex或Event Bus解决
Event Bus
1.新建一个bus.js文件
import Vue from 'vue'; export default new Vue();
2.使用它
<div @click="ddCart">添加</div> import Bus from 'bus.js'; export default{ methods: { addCart(event){ Bus.$emit('getTarget', event.target) } } } // 另一组件 export default{ created(){ Bus.$on('getTarget', target =>{ console.log(target) }) } }
Vuex方式
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。--- 官方文档
Vuex 相信大家都比较熟悉了,我不打算在这里把 API 再演示一遍。因为我觉得,官方文档 已经非常详细了。Vuex 的核心是单向数据流,并以相应规则保证所有的状态管理都可追踪、可预测。
我们需要知道什么时候该用 Vuex,如果你的项目比较小,状态管理比较简单,完全没有必要使用 Vuex,你可以考虑我们前文提到的几种方式。
者:江三疯
链接:https://juejin.im/post/5c776ee4f265da2da53edfad
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。