组件通信
Prop和$emit
💡 主要用于父子组件通信,父组件单向传输数据给子组件,子组件不能修改`props`父传子的过程
父组件在子组件上面绑定 (v-bind
)自身的属性 msg ,子组件通过props
属性接收msg。
子传父的过程
子传父 子组件通过this.$emit(事件名,参数)
,触发父组件事件。同时父组件通过(v-on
)监听事件 然后触发父组件事件
-
父组件
<template> <div class="father"> father1 props传输 <Son :msg=msg @son1="logSon"></Son> </div> </template> <script> import Son from './son' export default { components: { Son }, data() { return { msg: 'this is father1 msg' } }, methods: { logSon(emitData) { console.log(emitData) } } } </script>
<template> <div class="father"> <Son :msg=msg @son1=logSon></Son> </div> </template> <script> import Son from './son' export default { components: { Son }, data() { return { msg: 'this is father1 msg' } }, methods: { logSon(emitData) { console.log(emitData) } } } </script>
-
子组件
<template> <div class="son"> <button @click="$emit('son1',{a:1})"> touch</button> </div> </template> <script>z export default { props: { msg: { type: String } }, } </script>
Provide& Inject
💡 祖孙元素传值,不能响应式更新值,但是如果值是可监听对象,那么还是可以响应祖先元素定义provide
data() {
return {
msg: 'i can change',
reactiveObjMsg: {
msg: 'reactiveObjMsg'
}
}
},
provide() {
return {
provideMsg: 'this is provide', //写死的元素 无法响应式
reactiveProvideMsg: this.reactiveObjMsg, // this.reactiveObjMsg.msg 改变子孙元素也能改变
thisVM: this // 直接传递当前实例下去 可以直接在祖孙元素调用 thisVM.msg
}
},
methods: {
changed() {
this.msg = 'changed'
this.reactiveObjMsg.msg = 'changed'
console.log(this.msg)
}
},
孙子元素接收inject
export default {
name: "index",
inject: ['reactiveProvideMsg', 'provideMsg', 'thisVM'],
}
$attrs
& $listeners
💡 主要用于隔代传值,且不用在中间组件写更多的`props` 能传输方法和数据
只需要在中间元素绑定$attrs
和监听$listeners
子孙元素就可以调用祖先元素的数据和调用方法
祖先元素
<template>
<div>
<h2>组件A 数据项:{{ num }}</h2>
<B @change-num="changeNum" :num="num"></B>
</div>
</template>
<script>
import B from "./b";
export default {
data() {
return {
num: 100
};
},
components: {B},
methods: {
changeNum(val) {
this.num =val;
}
}
};
</script>
中间元素
<template>
<div>
<h3>组件B</h3>
<C v-bind="$attrs" v-on="$listeners"></C>
</div>
</template>
<script>
import C from "./c";
export default {
components: { C },
};
</script>
子孙元素
<template>
<div>
<h5>组件C</h5>
<input v-model="nums" @input="$emit('change-num', nums)"/>
</div>
</template>
<script>
export default {
props: ['num'],
data() {
return {
nums: 0
}
},
created() {
this.nums = this.num;
console.log(this.$attrs, this.$listeners);
},
};
</script>
$children
& $parent
💡 直接调用父元素的实例和子元素的实例
调用方式
// 父组件调用子元素实例
this.$children[第几个子组件]
//子组件调用父组件
this.$parent
ref & refs
💡 `ref`主要用于访问实例数据,如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据<template>
<div class="father">
<B ref="comB" ></B>
</div>
</template>
<script>
import B from "./b";
export default {
components: {B},
mounted() {
console.log(this.$refs['comB'])
}
};
</script>
eventBus
💡 主要用于简单的数据共享传输// 创建 eventbus 实例 并且在需要他的地方引入
import Vue from 'vue'
export const EventBus = new Vue()
//A组件 引入Bus使用$emit派发事件
import {EventBus} from './bus.js'
EventBus.$emit(事件名, 参数)
//B组件 引入Bus使用$on监听事件
import {EventBus} from './bus.js'
EventBus.$on(事件名, fn)
//移除监听
EventBus.$off(事件名, {})