vue 组件传值(一)$attrs,$listeners

vue 组件传值(一)$attrs,$listeners

$attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="../node_modules/vue/dist/vue.min.js"></script>  
    <title>父子传值</title>
</head>
<body>
    <div id="app"></div>
    <script>
        Vue.component('C',{
            data(){
                return  {
                    msg : 'CCCCCCCC',
                    cdata : '哈哈哈哈'
                }
            },
            methods : {
                changedata(val){
                    this.$emit('test2',val);
                    this.$emit('btest',val);
                }
            },
            template : `<div class="C">
                        <p>C组件:{{$attrs.app_data_c}}-{{$attrs}}</p>
                        输入:<input v-bind="$attrs" v-on="$listeners" @click="changedata(msg)" v-model="msg"></input>
                        <div>`,
            created(){
                console.log('C组件的$listeners:'); 
                console.log(this.$listeners); // 包含父级所有绑定的方法
            }
        });
         Vue.component('B',{
            data(){
                return  {
                    message_child : '我是子组件的值'
                }
            },
            template : `<div class="B">
                        <p>B组件:{{$attrs.app_data_b}}-{{$attrs}}</p>
                        <C v-bind="$attrs" v-on="$listeners" ></C>
                        <div>`,
            created(){
                console.log('B组件的$listeners:'); 
                console.log(this.$listeners); // 包含父级所有绑定的方法
            }
        });
        Vue.component('A',{
            data(){
                return  {
                    a : 'A的数据a',
                    b : 'A的数据b'
                }
            },
            methods : {
                changedata(val){
                    console.log('触发了btest事件'+val)
                }
            },
            // 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class  style 除外)
            // 当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class和 style 除外)
            // 并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
            // $listener:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。
            // 它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
            template : `<div class="A">
                        <p>A组件:{{$attrs.app_data_a}}-{{$attrs}}</p>
                        <B v-bind="$attrs" v-on="$listeners" :A_data_a="a" :A_data_b="b" @btest="changedata"></B>
                        <div>` ,
            created(){
                console.log('A组件的$listeners:'); 
                console.log(this.$listeners); // 包含父级所有绑定的方法
            }
        });
        Vue.component('Parent',{
            data(){
                return {
                    message_parent : '我是Parent组件的数据'
                }
            },
            props : ['app_data_a'],
            template : `<div class="parent">
                        <p>Parent组件:{{$attrs.app_data_a}}-{{$attrs}}</p>
                        <A v-bind="$attrs" v-on="$listeners"></A>
                        <div>`,
            created(){
                console.log('Parent组件的$listeners:'); 
                console.log(this.$listeners); // 包含父级所有绑定的方法
            }
        });
        var App = {
            data(){
                return {
                    a : '数据a',
                    b : '数据b',
                    c : '数据c',
                    message_app : '我是App组件的数据'
                }
            },
            methods : {
                changedata_a(val){

                },
                changedata_b(val){
                    this.b = val
                },
                changedata_c(val){
                }
            },
            template : `<div>
                            App中:
                            <span>a:{{a}}</span>
                            <span>b:{{b}}</span>
                            <span>c:{{c}}</span>
                            <Parent :app_data_a="a" :app_data_b="b" :app_data_c="c" @test1="changedata_a" @test2="changedata_b" @test3="changedata_c">
                            </Parent>
                        </div>`
        };
        new Vue({
            el : '#app',
            components : {
                App
            },
            template : '<App></App>'
        });
    </script>
</body>
</html>

为了便于理解,我画了个图:
在这里插入图片描述

注意

在这里插入图片描述
在这里插入图片描述

运行截图

在这里插入图片描述

总结

该传值方法适合直接嵌套多层的组件之间传值,$attrs用于父向子传值,$listeners用于通过触发父组件事件和传值来实现从子向父传值。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页