1.单向通信
1)prop(父=>子)
父组件通过传递prop,子组件接受后不应该在组件中直接更改(数据不会响应变化),但是如果传递的是引用类型的值,在组件中更改仍然会影响父组件。
2)provide/inject(父=>子、孙)
父组件通过provide选项向子孙组件提供属性、方法,子孙组件通过inject选项注入。同样要避免在子孙组件中直接更改注入的数据。
provide和inject主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
3)emit(子=>父)
子组件通过emit触发事件,并传递向父组件传递值,父组件监听事件并接收值。
4)v-slot(子=>父)
通过插槽向父组件传递数据
5)直接访问父、子组件实例
实例方法:
- $parent
- $root
- $children
- $refs
6)其他特殊情况
实例方法:
-
$listeners:访问在父级作用域中给子组件绑定的事件对象{event:function}
-
$attrs:访问在父级作用域中给子组件绑定的非prop属性的数据对象{key:value}
-
$slots:访问父组件普通插槽分发的内容,返回的是VNODE
-
$scopedSlots:访问插槽作用域,也可访问普通插槽,返回的是返回VNODE的函数,在渲染函数编写组件时很有用
-
向父组件传递值:this.$scopedSlots.default({ text: this.message }),返回一个vnode,可用在createElement的第三个参数里
-
使用子组件传递来的数据:scopedSlots: { default: function (props) { return createElement('span', props.text) },为createElement函数第二个参数里的一个配置项
-
2.双向通信
1).sync修饰符号
其实是子组件触发事件更新父组件数据的一种简写方式,父组件传递prop时利用.sync修饰符,子组件更新值时利用$emit('update:prop-name',newValue)提交数据更新申请,父组件自动实现数据更新。
2)v-model
其实也是利用emit触发事件。子组件表单元素的value值绑定到叫value的prop属性上,向外触发input事件并提交更新的值。父组件利用v-model绑定数据。
v-model默认利用input事件和value属性,可以利用model选项更改事件和属性,以避免与需将value特性用于不同目的的表单元素冲突。比如单选框会用value特性代表单选框的值,此时就无法同时将value绑定到prop上。
总结
看网上还有一种方法,创建一个空的vue实例(或者直接用根组件),触发、监听事件来传递数据。总的来说vue中主要的通讯方式就是利用prop或者emit。项目大了可以用vuex做统一的状态管理,公用的方法、属性多了且与其他组件不产生依赖的的还可以直接混入(mixin)。