vue 组件间的通讯
通常组件传参是有两种情况
1.父子组件进行传参,这时候通常利用props
1)props ,$emit父子组件通讯
2)自定义事件
父组件rights, 子组件inp和item,自定义事件引入的event.js
2.非父子组件传参,这时候一般利用vuex
3.隔代组件传参,这时候可以利用props一层一层传递下去,但是代码就比较乱了,最好使用provide/inject
进行隔代组件传递
对于使用场景,基础组件应该使用props,我个人觉得一般用于比较复杂业务,提供基础数据,比如最近的基金详情页。可以直接在最顶层提供基金的基本信息,然后子组件都可以访问的到,不用每个单独提供detail的props 属性
4.跨组件的全局通信 $bus
生命周期
生命周期有父子组件的情况,是如何执行的,看下面效果图
<template>
<div class="header">
<!-- rights组件 -->
<!-- 子组件触发的this.emit事件必须与父组件的自定义事件name一致!!! -->
<Inp @add='addHandler'></Inp>
<Item :list='list' @delete= 'deleteHandler'></Item>
</div>
</template>
<script type="text/ecmascript-6">
import Inp from './inp'
import Item from './item'
export default {
data() {
return {
list:[
{id:1, title:'标题一'},
{id:2, title:'标题二'},
]
}
},
components:{
Inp,
Item
},
beforeCreate() {
console.log('rights beforeCreate');
},
created() {
console.log('rights created');
},
beforeMount() {
console.log('rights beforeMount');
},
mounted() {
console.log('rights mounted');
},
beforeUpdate() {
console.log('rights beforeUpdate');
},
updated() {
console.log('rights updated');
},
beforeDestroy() {
console.log('rights beforeDestroy');
},
destroyed() {
console.log('rights destroyed');
},
methods: {
// 父组件接收到触发add的事件,并执行addHandler函数,title(可自定义)为携带过来的数据
addHandler(title) {
console.log(title);
// 解构
const {list} = this
// 对象简写 key 与value一样时可直接写 key
list.push({id:list.length+1, title})
},
deleteHandler(id) {
console.log(id);
// filter是返回满足条件的数据,假如点击的是id=2的元素,这里就是返回list中id不等于2的数据
this.list = this.list.filter((item)=>item.id !== id)
}
},
}
</script>
<template>
<div>
<!-- inp组件 -->
<input type="text" name="" id="" v-model="title">
<button @click="addTitle">添加</button>
</div>
</template>
<script>
// event是vue 自带的能力
import event from './event'
export default {
data() {
return {
title: ''
}
},
methods: {
addTitle() {
// 向父组件触发add 事件,并携带参数this.title
this.$emit('add', this.title)
// 触发自定义事件onAddTitle
event.$emit('onAddTitle', this.title)
// 清空输入框
this.title = ''
}
},
}
</script>
<template>
<div>
<!-- item组件 -->
<ul>
<li v-for="item in list" :key="item.id">
{{item.title}}
<button @click="del(item.id)">删除</button>
</li>
</ul>
</div>
</template>
<script>
// event是vue 自带的能力
import event from './event'
export default {
// 或者写成props: ['list']
props:{
list:{
type: Array,
default() {
return []
}
}
},
data() {
return {
}
},
beforeCreate() {
console.log('item beforeCreate');
},
created() {
console.log('item created');
},
beforeMount() {
console.log('item beforeMount');
},
mounted() {
// 监听自定义事件onAddTitle
event.$on('onAddTitle',this.addTitleHandler)
console.log('item mounted');
},
beforeUpdate() {
console.log('item beforeUpdate');
},
updated() {
console.log('item updated');
},
beforeDestroy() {
// 自定义事件或addEventListener的事件需及时销毁,否则可能会造成内存泄漏
console.log(121414124);
event.$off('onAddTitle',this.addTitleHandler)
console.log('item beforeDestroy');
},
destroyed() {
console.log('item destroyed');
},
methods: {
del(id) {
// 子组件触发delete事件,并携带参数id
this.$emit('delete',id)
},
// 自定义事件onAddTitle后,马上执行addTitleHandler函数
addTitleHandler() {
console.log(`emit自定义触发的事件,再由on监听的事件,
自定义事件不管隔多少层,都能监听到
`);
}
},
}
</script>
import Vue from 'vue'
// 直接new了一个 vue的实例
export default new Vue()
生命周期有父子组件的情况
挂载阶段:先是父组件(rights)vue 实例化完成也就是先js 建模完成,在子组件(item) js建模完成至整个页面渲染完成,后才是父组件页面渲染
更新阶段:也同上
3.依赖注入 隔代组件,即多层嵌套组件
父组件:
provide() {
return {
name: "Garrett",
};
},
子组件:
export default {
inject: ["name"],
data() {
return {};
},
components: {
RCScene,
},
mounted() {
console.log("this.name", this.name);
},
}
传对象:
export default {
data() {
return {
showIndex: 0,
obj: {
name: "obj",
},
};
},
provide() {
return {
map_nodeObj: { map_node: this.obj },
// 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
};
},
}
export default {
inject: {
map_nodeObj: {
default: () => {
return { map_node: "99" };
},
},
},
data() {
return {};
},
components: {
RCScene,
},
mounted() {
console.log(
" this.map_nodeObj.map_node",
this.map_nodeObj.map_node
)// {name:'obj'}
},
};
4.跨组件的全局通讯
main.js
let that = new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
beforeCreate() { //注册bus
Vue.prototype.$bus = this;
}
})
this.$bus.$emit("changchunHome_dateYM", this.value1); // 触发事件
this.$bus.$on("changchunHome_dateYM", data => { // 全局监听事件
this.changchunHome_dateYM = data;
});