Javascript Vue.js 2.0中同级组件之间的通信 概述
在Vue.js 2.x中 那么,在中的兄弟组件之间进行通信的正确方式是什么Javascript Vue.js 2.0中同级组件之间的通信 概述,javascript,vue.js,vuejs2,vue-component,vuex,Javascript,Vue.js,Vuejs2,Vue Component,Vuex,在Vue.js 2.x中 那么,在中的兄弟组件之间进行通信的正确方式是什么 背景 根据我对Vue.js 2.x的理解,兄弟通信的首选方法是使用存储或事件总线 根据(Vue.js的创建者)的说法: 还值得一提的是,“在组件之间传递数据”是 通常这是一个坏主意,因为最终数据流变得 不可跟踪且很难调试 如果一段数据需要由多个组件共享,请选择 或者 [] 以及: .once和.sync不推荐使用。道具现在总是单向下降。到 在父范围内产生副作用,组件需要 显式地发出事件,而不是依赖隐式绑定 因此,使用$
背景 根据我对Vue.js 2.x的理解,兄弟通信的首选方法是使用存储或事件总线 根据(Vue.js的创建者)的说法: 还值得一提的是,“在组件之间传递数据”是 通常这是一个坏主意,因为最终数据流变得 不可跟踪且很难调试 如果一段数据需要由多个组件共享,请选择 或者 [] 以及:
.once
和.sync
不推荐使用。道具现在总是单向下降。到
在父范围内产生副作用,组件需要
显式地发出事件,而不是依赖隐式绑定
因此,使用$emit()
和$on()
担心 我担心的是:
- 每个
和存储
都具有全局可见性(如果我错了,请纠正我)李>事件
- 为每一次小交流创建一个新店太浪费了李>
事件
或存储同级组件的可见性。(或许我不明白上面的意思。)
问题:
那么,兄弟组件之间通信的正确方式是什么呢?如果我想“破解”Vue.js中的正常通信模式,特别是现在.sync
被弃用,我通常会做的是创建一个简单的EventEmitter来处理组件之间的通信。来自我最近的一个项目:
import {EventEmitter} from 'events'
var Transmitter = Object.assign({}, EventEmitter.prototype, { /* ... */ })
使用此变送器
对象,您可以在任何组件中执行以下操作:
import Transmitter from './Transmitter'
var ComponentOne = Vue.extend({
methods: {
transmit: Transmitter.emit('update')
}
})
import Transmitter from './Transmitter'
var ComponentTwo = Vue.extend({
ready: function () {
Transmitter.on('update', this.doThingOnUpdate)
}
})
以及创建“接收”组件:
import Transmitter from './Transmitter'
var ComponentOne = Vue.extend({
methods: {
transmit: Transmitter.emit('update')
}
})
import Transmitter from './Transmitter'
var ComponentTwo = Vue.extend({
ready: function () {
Transmitter.on('update', this.doThingOnUpdate)
}
})
同样,这是真正的特定用途。不要将整个应用程序基于此模式,而是使用类似于Vuex
的方式。好的,我们可以使用v-on
事件通过父级在同级之间进行通信
Parent
|-项目列表//同级1-“列表”
|-所选项目的详细信息//同级2-“详细信息”
我们假设,当我们单击列表中的某个元素时,需要更新详细信息组件
在父项中
:
模板:
<list v-model="listModel"
v-on:select-item="setSelectedItem"
></list>
<details v-model="selectedModel"></details>
<ul>
<li v-for="i in list"
:value="i"
@click="select(i, $event)">
<span v-text="i"></span>
</li>
</ul>
在列表中
:
模板:
<list v-model="listModel"
v-on:select-item="setSelectedItem"
></list>
<details v-model="selectedModel"></details>
<ul>
<li v-for="i in list"
:value="i"
@click="select(i, $event)">
<span v-text="i"></span>
</li>
</ul>
在这里:
this.$emit('select-item',item)
将直接通过父级中的选择项发送一个项。家长会将其发送到详细信息
视图
对于Vue.js 2.0,我正在使用演示的eventHub机制
定义集中式事件中心
const eventHub = new Vue() // Single event hub
// Distribute to components using global mixin
Vue.mixin({
data: function () {
return {
eventHub: eventHub
}
}
})
现在,在组件中,您可以使用
this.eventHub.$emit('update', data)
听你这么说
this.eventHub.$on('update', data => {
// do your thing
})
更新
请参阅,它描述了一个更简单的解决方案。您甚至可以将其缩短,并使用Vue
实例作为全局事件中心:
构成部分1:
this.$root.$emit('eventing',data);
构成部分2:
mounted(){
此.$root.$on('eventing',data=>{
控制台日志(数据);
});
}
状态范围
在设计Vue应用程序(或者实际上,任何基于组件的应用程序)时,有不同类型的数据,这取决于我们处理的关注点,并且每个都有自己的首选通信通道
- 全局状态:可能包括登录用户、当前主题等
- 本地状态:表单属性、禁用按钮状态等
请注意,全局状态的一部分可能在某个点上以局部状态结束,并且可以像任何其他局部状态一样传递给子组件,可以是完全的,也可以是稀释的,以匹配用例
沟通渠道
通道是一个松散的术语,我将用来指围绕Vue应用程序交换数据的具体实现
每个实现都针对特定的通信信道,包括:
- 全球国家
- 亲子
- 子女父母
- 兄弟姐妹
不同的关注点涉及不同的沟通渠道
:直接父母子女
Vue中用于单向数据绑定的最简单通信通道
:直接子-父
$emit
和$on
。直接子-父通信的最简单通信通道
:全局或远程本地状态
添加到Vue 2.2+中,与React的上下文API非常相似,可以作为事件总线的可行替代品
在组件树中的任何一点上,组件都可以提供一些数据,该行中的任何子级都可以通过inject
组件的属性访问这些数据
app.component('todo-list', {
// ...
provide() {
return {
todoLength: Vue.computed(() => this.todos.length)
}
}
})
app.component('todo-list-statistics', {
inject: ['todoLength'],
created() {
console.log(`Injected property: ${this.todoLength.value}`) // > Injected property: 5
}
})
这可用于在应用程序的根目录下提供全局状态,或在树的子集内提供局部状态
集中存储(全局状态)
是Vue.js应用程序的状态管理模式+库。
它作为一个数据库中所有组件的集中存储
应用程序,规则确保状态只能在
一种可预测的时尚
现在:
[S] 我是否应该为每个次要通信创建vuex存储
在处理全球国家问题时,这一点非常突出,包括但不限于:
- 从后端接收的数据
- 全局UI状态就像一个主题
- 任何数据持久层,例如保存到后端或与本地存储接口
- toast消息或通知
- 等等
因此,您的组件可以真正专注于它们的本意,管理用户界面,而全局存储可以管理/使用通用业务逻辑,并通过和提供清晰的API
这并不意味着您不能将其用于组件逻辑,但我个人会研究它