一、介绍 $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');
// 测试结果展示