vue组件通信,子组件向父组件通信
前置知识vue也实现了观察者模式,提供了订阅消息,发布消息,注销消息等方法。
$on(type, fn) 订阅消息方法
type:消息名称,
fn:消息回调函数,参数是由$emit方法传递的。
$emit(type, ...args) 发布消息方法
type:消息名称,
...args:从第二个参数开始,表示传递的数据
$off(type, fn) 注销消息方法
type:消息名称
fn:消息回调函数
组件是一个完整独立的个体,因此彼此之间数据不会共享,所以发布消息与订阅消息必须是同一个组件。
两种方式 模拟DOM事件, 传递属性方法
模拟DOM事件 :自定义事件名=”fn“
1.在父组件模板中,为子组件绑定自定义事件
消息名称 字母小写- 绑定事件不要添加参数集合
绑定事件没有添加参数集合(),可以接收所有数据 包含事件对象
添加了参数集合(e)不能接收数据,即使传递了$event也只能接收一条数据
2.在子组件中 通过$emit发布消息,传递子组件中数据
消息名称 字母小写- 唯一不用驼峰式命名
3.在父组件事件回调函数中接收数据并存储数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 定义视图 --> <div id="app"> <h1>app: {{msg}}</h1> <hr> <!-- 组件 --> <!-- 1 模拟dom事件 --> <!-- 如果没有添加参数集合,可以接收所有的数据 --> <demo @demo-method="parentMethod"></demo> <!-- 如果添加了参数集合,不能接收数据,即使传递了$event也只能接收一条数据 --> <!-- 因此 我们不要添加参数集合 --> <!-- <demo @demo-method="parentMethod($event, $event)"></demo> --> </div> <script src="./dist/xx.js"></script> </body> </html>
// 引入vue import Vue from 'vue'; // 关闭生产提示 Vue.config.productionTip = false; // 定义首页组件 let Demo = Vue.extend({ // 定义模板 template: ` <div> <input type="text" v-model="msg"> <h1>demo component--{{msg}}</h1> </div> `, // 定义静态数据 data() { return { msg: 'child msg' } }, // 创建完成之后 created() { // 2 在子组件中,通过$emit发布消息,并传递子组件中的数据。 // 这里是唯一一个不需要转为驼峰命名的地方 // this.$emit('demo-method', 100, true, 'abc') // 传递自己的数据 this.$emit('demo-method', this.msg); }, // 监听数据的变化 watch: { msg() { // 传递自己的数据 this.$emit('demo-method', this.msg); } } }) // 实例化 new Vue({ // 局部注册 components: { Demo }, // 绑定视图 el: '#app', // 绑定数据 data: { msg: '', }, // 定义方法 methods: { parentMethod(val) { // console.log('parent', this, arguments); this.msg = val; } } })
2.传递属性方法
1.在父组件模板中, 为子组件传递父组件中的方法
2.在子组件中,接收方法, 执行方法并传递数据
3.在父组件的方法中,接收数据,并存储数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 定义视图 --> <div id="app"> <h1>app: {{msg}}</h1> <hr> <!-- 组件 --> <!-- 传递父组件的方法 --> <demo :parent-method="parentMethod"></demo> </div> <!-- 引入发布之后的文件 --> <script src="./dist/xx.js"></script> </body> </html>
// 引入vue import Vue from 'vue'; // 关闭生产提示 Vue.config.productionTip = false; // 定义首页组件 let Demo = Vue.extend({ // 通过props接收 props: ['parentMethod'], // 定义模板 template: ` <div> <input type="text" v-model="msg"> <h1>demo component--{{msg}}</h1> </div> `, // 定义静态数据 data() { return { msg: 'child msg' } }, // 创建完成之后 created() { // 执行接收的方法 this.parentMethod(this.msg); }, // 监听数据的变化 watch: { msg() { // 执行接收的方法 this.parentMethod(this.msg); } } }) // 实例化 new Vue({ // 局部注册 components: { Demo }, // 绑定视图 el: '#app', // 绑定数据 data: { msg: '', }, // 定义方法 methods: { parentMethod(val) { // console.log('parent', this, arguments); this.msg = val; } } })

浙公网安备 33010602011771号