一、介绍 $listeners(自下而上传递数据), $attrs(自上而下多组件传递数据)
在vue组件化开发过程中,涉及到多层组件嵌套,但如果仅仅是传递数据,而不做中间处理,使用Vuex层架复杂度这时候使用。
代码参考地址:https://gitee.com/ligeyihayou/attrs-listeners

二、设计文件结构

// juejin.vue 路由组件入口
// com-one.vue 子组件
// com-two.vue 子组件
// 嵌套关系如下: juejin->com-one->com-two
// juejin.vue
<template>
    <div id="juejin">
        <com-one
                :foo="foo"
                :boo="boo"
                :coo="coo"
                :doo="doo"
                v-on:test1="onTest1"
                v-on:test2="onTest2"
        ></com-one>
    </div>
</template>

<script type="text/ecmascript-6">
    import ComOne from './template/com-one';
    export default {
        props: {},
        computed: {},
        name: 'juejin',
        data () {
            return {
                foo: "Javascript",
                boo: "Html",
                coo: "CSS",
                doo: "Vue"
            };
        },
        created () {
        },
        methods: {
            onTest1 (value) {
                console.log('test1 running...', value);
            },
            onTest2 (value) {
                console.log('test2 running', value);
            }
        },
        mounted () {
            this.$Event.$on('chagne-zyn', value => {
                console.log(value, '来自 juenjin 组件')
            })
        },
        components: { ComOne },
        destroy () {
        }
    };
</script>
// com-one.vue
<template>
    <div id="com-one">
        <p>foo: {{ foo }}</p>
        <p>childCom1的$attrs: {{ $attrs }}</p>
        <com-two v-bind="$attrs" v-on="$listeners"></com-two>
    </div>
</template>

<script type="text/ecmascript-6">
    import ComTwo from './com-two';
    export default {
        props: {
            foo: String // foo作为props属性绑定
        },
        computed: {},
        name: 'com-one',
        data () {
            return {};
        },
        inheritAttrs: false, // 设置为false,父组件传递过来的 数据 不会以html属性的形式出现在当前组件的根元素上面
        created () {
        },
        methods: {

        },
        mounted () {
            this.$emit('test1', 'com-one-$emit');
            this.$Event.$on('chagne-zyn', value=> {  /// 通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级
                console.log(value, '来自 com-one 组件')
            })
        },
        components: {ComTwo},
        destroy () {
        }
    };
</script>
// com-two.vue
<template>
    <div id="com-two">
        <p>boo: {{ boo }}</p>
        <p>childCom2: {{ $attrs }}</p>
        <button @click="test">$emit触发事件</button>
    </div>
</template>

<script type="text/ecmascript-6">
    export default {
        props: {
            boo: String
        },
        computed: {},
        inheritAttrs: false, // 设置为false,父组件传递过来的 数据 不会以html属性的形式出现在当前组件的根元素上面
        name: 'com-two',
        data () {
            return {};
        },
        created () {
        },
        methods: {
            test(){
                this.$Event.$emit('chagne-zyn', '32');
            },
            link(){
                console.log('$listeners==com-two');
            }
        },
        mounted () {
            this.$emit('test2', 'com-two-$emit'); // 
        },
        components: {},
        destroy () {
        }
    };
</script>
// main.js 
/* eslint-disable */
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.prototype.$Event = new Vue();; // 通过一个空的Vue实例作为中央事件总线(事件中心)
/// +++
let isDisable = true;
 new Vue({
        router,
        render: h => h(App)
    }).$mount('#app');

// 测试结果展示
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐