this.$parent
可以访问到父组件 上所有的 data(){ 里的数据信息和生命周期方法,methods里的方法
// 子传父
this.$parent.datas = "val"
for(let i = 0; i < this.$children.length; i++) {
console.log(this.$children[i].msg)//输出子组件的msg数据;
}
$root
获取当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。通过 $root ,我们可以实现组件之间的跨级通信
$refs
我们通常会将 refs 绑定在子组件上,从而获取子组件实例
$attrs
a t t r s : 用 来 接 收 父 作 用 域 中 不 作 为 p r o p 被 识 别 的 a t t r i b u t e 属 性 , 并 且 可 以 通 过 v − b i n d = " attrs: 用来接收父作用域中不作为 prop 被识别的 attribute 属性,并且可以通过v-bind=" attrs:用来接收父作用域中不作为prop被识别的attribute属性,并且可以通过v−bind="attrs"传入内部组件——在创建高级别的组件时非常有用
$listeners
l i s t e n e r s : 包 含 了 父 作 用 域 中 的 v − o n 事 件 监 听 器 。 它 可 以 通 过 v − o n = " listeners:包含了父作用域中的 v-on 事件监听器。它可以通过 v-on=" listeners:包含了父作用域中的v−on事件监听器。它可以通过v−on="listeners" 传入内部组件——在创建更高层次的组件时非常有用,这里在传递时的使用方法和 $attrs 十分类似。
// A组件
<template>
<div class="compa">
<h3>this is A component</h3>
<input type="text" v-model="message" />
<p>收到来自{{ comp }}的消息:{{ messageFromComp }}</p>
<CompB :messageFromA="message" @keyup="receive" /> <!--监听子孙组件的keyup事件,将message传递给子孙组件-->
</div>
</template>
<script>
import CompB from './compB'
export default {
name: 'CompA',
data() {
return {
message: '',
messageFromComp: '',
comp: '',
}
},
components: {
CompB,
},
methods: {
receive(e) { // 监听子孙组件keyup事件的回调,并将keyup所在input输入框的值赋值给messageFromComp
this.comp = e.target.name
this.messageFromComp = e.target.value
},
},
}
</script>
// 2级组件B
<template>
<div class="compb">
<h4>this is B component</h4>
<input name="compB" type="text" v-model="message" v-on="$listeners" /> <!--将A组件keyup的监听回调绑在该input上-->
<p>收到来自A组件的消息:{{ $attrs.messageFromA }}</p>
<CompC v-bind="$attrs" v-on="$listeners" /> <!--将A组件keyup的监听回调继续传递给C组件,将A组件传递的attrs继续传递给C组件-->
</div>
</template>
<script>
import CompC from './compC'
export default {
name: 'CompB',
components: {
CompC,
},
data() {
return {
message: '',
}
},
}
</script>
// 3级组件C
<template>
<div class="compc">
<h5>this is C component</h5>
<input name="compC" type="text" v-model="message" v-on="$listeners" /> <!--将A组件keyup的监听回调绑在该input上-->
<p>收到来自A组件的消息:{{ $attrs.messageFromA }}</p>
</div>
</template>
<script>
export default {
name: 'Compc',
data() {
return {
message: '',
}
},
}
</script>
$bus
// main.js
Vue.prototype.$bus = new Vue()
```// 1级组件A
<template>
<div class="containerA">
<h2>this is CompA</h2>
<input type="text" v-model="message" @keyup="sendMessage" />
<p v-show="messageFromBus && sender !== $options.name">
收到{{ sender }}的消息:{{ messageFromBus }}
</p>
<CompB />
</div>
</template>
<script>
import CompB from './compB'
export default {
name: 'CompA',
components: {
CompB,
},
data() {
return {
message: '',
messageFromBus: '',
sender: '',
}
},
mounted() {
this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
const { sender, message } = obj
this.sender = sender
this.messageFromBus = message
})
},
methods: {
sendMessage() {
this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
sender: this.$options.name,
message: this.message,
})
},
},
}
</script>
// 2级组件B
<template>
<div class="containerB">
<h3>this is CompB</h3>
<input type="text" v-model="message" @keyup="sendMessage" />
<p v-show="messageFromBus && sender !== $options.name">
收到{{ sender }}的消息:{{ messageFromBus }}
</p>
<CompC />
<CompD />
</div>
</template>
<script>
import CompC from './compC'
import CompD from './compD'
export default {
name: 'CompB',
components: {
CompC,
CompD,
},
data() {
return {
message: '',
messageFromBus: '',
sender: '',
}
},
mounted() {
this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
const { sender, message } = obj
this.sender = sender
this.messageFromBus = message
})
},
methods: {
sendMessage() {
this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
sender: this.$options.name,
message: this.message,
})
},
},
}
</script>
// 3级组件C
<template>
<div class="containerC">
<p>this is CompC</p>
<input type="text" v-model="message" @keyup="sendMessage" />
<p v-show="messageFromBus && sender !== $options.name">
收到{{ sender }}的消息:{{ messageFromBus }}
</p>
</div>
</template>
<script>
export default {
name: 'CompC',
data() {
return {
message: '',
messageFromBus: '',
sender: '',
}
},
mounted() {
this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
const { sender, message } = obj
this.sender = sender
this.messageFromBus = message
})
},
methods: {
sendMessage() {
this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
sender: this.$options.name,
message: this.message,
})
},
},
}
</script>
// 3级组件D
<template>
<div class="containerD">
<p>this is CompD</p>
<input type="text" v-model="message" @keyup="sendMessage" />
<p v-show="messageFromBus && sender !== $options.name">
收到{{ sender }}的消息:{{ messageFromBus }}
</p>
</div>
</template>
<script>
export default {
name: 'CompD',
data() {
return {
message: '',
messageFromBus: '',
sender: '',
}
},
mounted() {
this.$bus.$on('sendMessage', (obj) => { // 通过eventBus监听sendMessage事件
const { sender, message } = obj
this.sender = sender
this.messageFromBus = message
})
},
methods: {
sendMessage() {
this.$bus.$emit('sendMessage', { // 通过eventBus触发sendMessage事件
sender: this.$options.name,
message: this.message,
})
},
},
}
</script>
Vuex
全局通信:代码的内容和eventBus也类似,不过要比eventBus使用方便很多。每个组件通过watch监听input输入框的变化,把input的值通过vuex的commit触发mutations,从而改变stroe的值。然后每个组件都通过computed动态获取store中的数据,从而实现全局通信。
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
message: {
sender: '',
content: '',
},
},
mutations: {
sendMessage(state, obj) {
state.message = {
sender: obj.sender,
content: obj.content,
}
},
},
})
// 组件A
<template>
<div class="containerA">
<h2>this is CompA</h2>
<input type="text" v-model="message" />
<p v-show="messageFromStore && sender !== $options.name">
收到{{ sender }}的消息:{{ messageFromStore }}
</p>
<CompB />
</div>
</template>
<script>
import CompB from './compB'
export default {
name: 'CompA',
components: {
CompB,
},
data() {
return {
message: '',
}
},
computed: {
messageFromStore() {
return this.$store.state.message.content
},
sender() {
return this.$store.state.message.sender
},
},
watch: {
message(newValue) {
this.$store.commit('sendMessage', {
sender: this.$options.name,
content: newValue,
})
},
},
}
</script>