看博之前复习一遍关于组件数据通讯的官方文档:https://vuefe.cn/v2/guide/components.html
vue的官方文档本身写的算是比较清楚的,此博作为要点总结和深入补充
关键词:父组件通过props传递数据给子组件,子组件通过event传递数据给父组件
(一)props
1. 基本用法
prop 是父组件用来传递数据的一个自定义属性
//父组件<template> <div id="app"> <myHeader :msg="msg" my="nnn"></myHeader> </div> </template> <script> export default { name: ‘app‘, data () { return { msg: ‘from parent‘ } }, components: { myHeader } }
注意::msg="msg" my="my" 前者是动态绑定的父组件的数据,即data中的msg值‘from parent‘,后者的值是一个字符串直接量‘nnn‘
//子组件使用父组件传过来的值<template> <div id="header"> {{msg+my}} </div> </template> <script> export default { name: ‘myHeader‘, props: [‘msg‘,‘my‘], created(){console.log(this.msg)}, data () { return {} } }
子组件使用父组件传递过来的值:
1.先要定义好接受的 props,这里接受了两个prop: [‘msg‘,‘my‘]
2.像在子组件data中定义的数据一样使用,即可以在template中通过{{...}}使用,也可以在子组件的选项对象函数中通过this.的方式使用
在vue dev-tools中可以观察到
2. 补充
2.1 prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
以上这段文字是照搬官方文档,也就是说,props的功能只是:父组件传递数据给子组件,而不要试图去直接修改prop值,比如:
export default { name: ‘myNav‘, props: [‘msg‘], created(){ this.msg = ‘new‘ } }
结果就像官方文档所说一样,修改不成功并且报了个警告,英文不太好,不过应该能猜到它的意思:老子官网上说的清清楚楚不能改不能改你还特么乱搞
如果在子组件中需要对父组件传过来的值做处理,比如父组件传过来一个时间戳,需要格式化怎么办呢?官网截图大法:
2.2 在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态
这句话的结果就是,其实prop的值还是可以改的(我怎么有打脸的感觉),前提是prop值必须是对象
export default { name: ‘app‘, data () { return { msg: {a:‘b‘} } } }
如果将该msg作为prop传递给子组件,子组件则可以通过 this.msg.a = ‘我就是要改!‘,是能够成功修改父组件的msg值的,这样可以达到双向数据传递的目的。
但是有两点注意:
1. 只能改对象的属性,而不能重新给prop赋值,也就是说还是不能直接this.msg = ...,所以其实并没有打脸吧
2. 这样子虽然能实现双向传递,但是是否要这样用还要慎重小心
(二)event(自定义事件)
1. 基本用法:父组件可以在使用子组件的地方直接用 v-on
来监听子组件触发的事件
//父组件 <template> <div id="app"> <myHeader @myEvent=‘parentListener‘></myHeader> </template> <script> export default { name: ‘app‘, methods:{ parentListener(){ console.log(1) } }, components: { myHeader} }
子组件直接通过 this.$emit(‘myEvent‘,param1,param2,....) 触发事件即可,传递的数据通过后面的参数传递
很明显,通过event传递数据,对数据的控制能力明显比通过prop对象的方式要强的多,而且也能判别数据传递的来源
2. 非父子组件通讯
官网给出了Bus方案解决该问题,但讲的很简单我这里给出完整的使用例子
//首先实现一个bus模块,就是提供一个共用的mv实例 import Vue from ‘vue‘ var bus = new Vue() export default bus
import bus from ‘../lib/bus‘ ... //组件A注册时间,这里直接写在生命周期钩子函数中 created(){ bus.$on(‘aEvent‘, function (id) { alert(id) }) } ...
import bus from ‘../lib/bus‘ ... //组件B触发事件 created(){ bus.$emit(‘aEvent‘, 99) } ...