Vue2 [Vue Basics 10] - Pasar valores entre componentes hermanos [Central Event Bus, suscripción y publicación de mensajes]
Vue2: [Vue Basics 9] - pasar valores entre componentes padre e hijo
1. Componentes hermanos
1-1 autobús de eventos
- Al usar Vue3, encontrará que el eventBus que originalmente era útil falla repentinamente
- Vue3 ya no proporciona funciones $on y emit, y las instancias de Vue ya no implementan la interfaz de eventos. La recomendación oficial es introducir herramientas externas para la implementación o crear una clase de evento usted mismo.
1-1-1 Usando EventBus
- Importar/escribir biblioteca de eventos
- Montar en el archivo de entrada
- Introducir y utilizar en el componente.
1-1-2 Uso nativo sin complementos
-
Importar/escribir biblioteca de eventos
- Método 1: Introducir el guante recomendado oficialmente
- Método 2: crear manualmente una clase de publicación/suscripción simple
// eventBus.js export default class EventBus{ constructor(){ this.events = { }; } emit(eventName, data) { if (this.events[eventName]) { this.events[eventName].forEach(function(fn) { fn(data); }); } } on(eventName, fn) { this.events[eventName] = this.events[eventName] || []; this.events[eventName].push(fn); } off(eventName, fn) { if (this.events[eventName]) { for (var i = 0; i < this.events[eventName].length; i++) { if (this.events[eventName][i] === fn) { this.events[eventName].splice(i, 1); break; } }; } } }
-
Ejecute el montaje en el archivo de entrada main.js
// main.js
import {
createApp } from 'vue'
import App from './App.vue'
// ① 引入事件类
// 自己编写的或者mitt皆可
import EventBus from 'lib/bus.js'
// 或者:import EventBus from 'mitt'
const $bus = new EventBus()
// ② 挂载
// 1.使用provide提供
app.provide('$bus', $bus)
// 2.挂载到this上
app.config.globalProperties.$bus = $bus
- Introducir y utilizar en el componente.
- utilizado en crea
// Button.vue export default { created() { this.$bus.emit('ButtonCreated') } }
- usar en la configuración
Nota: Debido a que no se puede acceder a la instancia de la aplicación (esta) en la configuración, si necesita usar eventBus en la configuración, debe introducirlo a través de proporcionar/inyectar.
// Button.vue import { inject } from 'vue' export default { setup() { const $bus = inject('$bus') $bus.emit('ButtonSetup') } }
2. Componentes del abuelo y el nieto
2-1 accesorios y $emitir
El método de comunicación del componente padre-hijo más utilizado, abuelo -> padre----> hijo
1. El componente principal transmite datos al componente secundario a través de accesorios, y el componente secundario transmite datos al componente principal a través de eventos de activación $emit
2. Existe un problema en el procesamiento de la transmisión de datos entre los componentes principal e secundario:
- Anidamiento multicapa, hay un componente secundario B debajo del componente principal A y un componente C debajo del componente B. ¿Qué debo hacer si A quiere pasarlo a C?
- Usando el primer método, el componente A debe pasar el mensaje al componente B a través de prop, y luego el componente B lo pasa a C.
- Después de Vue2.4, se introdujeron atributos y oyentes para resolver este problema.
2-2 atributos y oyentes
1. El proceso de atributos y oyentes:
Hay un componente secundario B debajo del componente principal A, un componente C debajo del componente B, el componente A pasa datos al componente B
- componente C
Vue.component('C', {
template: `
<div>
<input type="text" v-model="$attrs.messageC" @input="passCData($attrs.messageC)">
</div>
`,
methods: {
passCData(val) {
// 触发父组件A中的事件
this.$emit('getCData',val)
}
}
})
- componente B
Vue.component('B', {
data() {
return {
myMessage: this.message
}
},
template: `
<div>
<input type="text" v-model="myMessage" @input="passData(myMessage)">
<C v-bind="$attrs" v-on="$listeners"></C>
</div>
`
// 得到父组件传递过来的数据
props: ['message'],
methods: {
passData(val) {
// 触发父组件中的事件
this.$emit('getChildData',val)
}
}
})
- Un componente
Vue.component('A',{
template: `
<div>
<p>this is parent compoent!</p>
<B
:messageC="messageC"
:message="message"
v-on:getCData="getCData"
v-on:getChildData="getChildData(message)">
</B>
</div>
`,
data() {
return {
message: 'Hello',
messageC: 'Hello c'
}
},
methods: {
getChildData(val) {
console.log('这是来自B组件的数据')
},
// 执行C子组件触发的事件
getCData(val) {
console.log("这是来自C组建的数据:"+val)
}
}
})
var app = new Vue({
el: '#app',
template: `
<div><A></A></div>
`
})
2. Análisis:
- La razón por la que getData se puede activar directamente en el componente C: cuando el componente B llama al componente C, usa v-on para vincular la propiedad $listeners
- Al vincular el atributo $attrs a través de v-bind, el componente C puede obtener directamente los accesorios transmitidos desde el componente A (excepto los accesorios declarados en el componente B)
Tres, modelo v
1. Cuando el componente principal pasa el valor al componente secundario a través del modelo v, automáticamente pasará un atributo de propiedad de valor y el valor vinculado al modelo v se modificará automáticamente en el componente secundario a través de esto.$emit ('entrada', valor)
tendré que comprobarlo más tarde
- https://blog.csdn.net/m0_56986233/article/details/121405388
- https://www.zhihu.com/question/466846675