汇总
- 于$on系列的总结
2. 组件通信方式
- v-bind 父传子
- emit子传父
- 父传递给子一个函数, 子组件调用 子传父
- 上层传递后代 provide/inject
- 子孙传递根 $root
- 随意传传 eventBus
- vuex
1. provide/inject
- provide/inject是成对使用的,是为了解决深层次组件通信的;
- 父组件通过provide提供数据;
- 子组件通过inject注入值;
- 父组件向所有子孙组件广播;
- provide/inject传递数据的方式是非响应式的(即父组件值变化之后。子组件的值不会响应式的改变),但是对象形式的数据是响应式的;
- 父组件
// 2.6之后的新功能
data() {
return {
innerNum: 123,
obj: { innerNum: 123 }
}
},
provide() {
return {
num: this.innerNum,
obj: this.obj
}
}
- 子组件(从父组件接收的num是非响应式的,obj是响应式的)
inject:['num','obj']
2. $root + 监听和触发
2.1 相同对象使用emit
- 在父组件中使用$on绑定事件;
- 在子组件中使用$emit接收和触发父组件绑定的事件;
- 父组件
<template>
<div class="box">
<h2>SSon1</h2>
<button @click="bindRoot">root绑定事件</button>
</div>
</template>
<script>
export default {
inject:['num','obj'],
methods:{
bindRoot(){
this.$root.$on('rootEvent',(data)=>{
console.log('我是SSon1组件,事件触发了',data)
})
}
}
}
</script>
- 子组件
<template>
<div class="hello">
<div class="box">
<h2>Son1</h2>
<button @click="toggleRoot">root触发事件</button>
</div>
</div>
</template>
<script>
export default {
methods: {
toggleRoot() {
this.$root.$emit('rootEvent', '【【我是数据Son1】】')
}
},
name: 'Son1',
}
</script>
2.2 children
- $parent:获取临近父组件;
- children:获取临近子组件;
- 父组件(可以通过this.$children拿到子组件)
<template>
<div class="box">
<h2>App</h2>
<button @click="showChildren">输出children</button>
<!-- 测试ParentChildren -->
<ParentChildren />
</div>
</template>
<script>
import ParentChildren from './components/ParentChildren';
export default {
name: 'App',
methods: {
showChildren() {
console.log(this.$children);
}
},
components: {
ParentChildren
}
}
</script>
- 子组件(可以通过this.$parent拿到父组件)
<template>
<div class="box">
<h2>ParentChildren</h2>
<button @click="showParent">显示$parent</button>
</div>
</template>
<script>
export default {
name:'xxx',
methods:{
showParent(){
console.log(this.$parent)
}
}
}
</script>
2.3 eventBus
- 单独建一个new Vue()文件,用来进行组件间数据传递;
- 专做组件通信,解决各种组件间通信的问题;
- 具有高内聚、低耦合的优点;
- Connect.js文件(存放建立的new Vue()对象)
import Vue from "vue";
export default new Vue();
- 父组件(Connect.$on())
<template>
<div class="box">
<button @click="bindEventBus">EventBus绑定事件总线</button>
</div>
</template>
<script>
import Connect from './Connect'
export default {
methods:{
bindEventBus(){
Connect.$on('connectEvent',data=>{
console.log('触发了EventBus',data)
})
}
}
}
</script>
- 子组件(Connect.$emit())
<template>
<div class="hello">
<div class="box">
<h2>Son1</h2>
<button @click="emitEventBus">eventBus触发事件</button>
</div>
</div>
</template>
<script>
import Connect from './Connect'
export default {
methods: {
emitEventBus() {
Connect.$emit('connectEvent', '【【Son1的数据】】')
}
},
name: 'Son1',
}
</script>
2.4 $listeners绑定事件
- 父组件
<template>
<div class="box">
<h2>App</h2>
<button @click="showChildren">输出children</button>
{{ data1 }} || {{ data2 }}
<ReactiveVue v-model="data1" :show.sync="data2" />
</div>
</template>
<script>
import ReactiveVue from './components/Reactive.vue';
export default {
name: 'App',
methods: {
showChildren() {
console.log(this.$children);
}
},
components: {
ReactiveVue
}
}
</script>
- 子组件
<template>
<div class="box">
<h2>Reactive</h2>
<button @click="change2">变更2</button>
</div>
</template>
<script>
export default {
methods:{
output(){
console.log(this,'组件数据')
},
change2(){
this.$listeners['input'](999);
this.$listeners['update:show'](8888);
}
}
}
</script>
2.5 .sync同步修饰符 v-model
父组件 <ReactiveVue v-model="data1" :show.sync="data2" />
- 都是语法糖;
- 真正的底层实现是:
- :value=“xxx” :xxx.sync=“变量”;
- @input=“xxx” @update:xxx=“函数”;
<template>
<div class="box">
<h2>App</h2>
<button @click="showChildren">输出children</button>
{{ data1 }} || {{ data2 }}
<ReactiveVue v-model="data1" :show.sync="data2" />
</div>
</template>
<script>
import ReactiveVue from './components/Reactive.vue';
export default {
name: 'App',
methods: {
showChildren() {
console.log(this.$children);
}
},
components: {
ReactiveVue
}
}
</script>
- 子组件
<template>
<div class="box">
<h2>Reactive</h2>
<button @click="output">输出</button>
<button @click="change1">变更</button>
<button @click="change2">变更2</button>
</div>
</template>
<script>
export default {
methods:{
output(){
console.log(this,'组件数据')
},
change1(){
this.$emit('input',999);
this.$emit('update:show',8888);
},
change2(){
this.$listeners['input'](999);
this.$listeners['update:show'](8888);
}
}
}
</script>