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;
        }
    }
})

 

        

posted @ 2022-03-26 16:09  HaoyuSun  阅读(370)  评论(0)    收藏  举报