vuejs中组件之间的通信
Communication between components in vuejs
我知道,Vuejs >= 2.0 中组件之间的通信是通过三个概念完成的
- props - 外部上下文如何将数据传递给组件,
- 事件 - 组件如何让外部环境了解变化,
- slots - 这个对我的问题不重要。
我也知道中央状态模式及其周围的所有东西。但有时可以告诉子组件 "do something, what changes your internal state".
是常见的
以下是一些场景:
- TreeView(递归组件)和 "collapse all" 按钮 - 您需要告诉所有子组件折叠。我知道,这是适用的中央状态模式,但让我们假设节点状态 (expanded/collapsed) 是组件内部状态的一部分。
- 计数器 - 我可以在页面上有多个计数器,父组件有按钮 "increment all" - 同样,我需要在每个子组件上 "call" 递增方法。
问题是:如何实现"event based"组件之间父->子方向的通信。我觉得这有点普遍。
我做了一个例子jsbin。但是,我不确定它是否违反了vue js的一些基本思想。
https://jsbin.com/kakucuf/edit?html,js,output
const Foo = {
name: 'Foo',
template: '#a-template',
props: {
name: {
required: true,
type: String
},
},
data() {
return {
counter: 0
}
},
mounted() {
this.$on('increment', this.increment);
},
methods: {
increment() {
this.counter += 1;
}
}
}
new Vue({
el: "#app",
components: {
foo: Foo,
},
methods: {
incrementAll() {
this.$children.forEach((child) => child.$emit('increment'));
}
}
});
也许 computed properties and watchers 适合您。
在您的父组件中,您可以使用计算属性作为子组件的 props。一旦计算属性发生变化,您的子组件就会更新,这要归功于 Vue.js 反应功能。
并且,在您的子组件中,使用观察器来控制来自该组件上下文的更改。
从您的场景出发:
- 你可以在你的父组件上使用
collapse
prop,并且 "listen" (或者实际上 "watch")通过你的子组件中的观察者,观察者函数来改变它的值如果新值为 true
,将在每个子组件内完成折叠工作
- 您可以从您的父组件发送一个
increment
道具,并通过您的子组件中的观察器观察其值的变化
例如,对于第二种情况,使用父组件中的 increment
道具,并在子组件中像这样观看它:
watch: {
increment: function (newVal) {
if (newVal === true) {
this.counter++
}
}
}
在您的父组件中,将 this.increment
设置为 true
将触发子组件中的观察器。如果您需要增加更多,请注意您必须将其设置回另一个值,例如 re-assigning true
.
之前的 null
这是一种 hack,应该代表您开始考虑 Vuex 等状态管理解决方案的时间!
我知道,Vuejs >= 2.0 中组件之间的通信是通过三个概念完成的
- props - 外部上下文如何将数据传递给组件,
- 事件 - 组件如何让外部环境了解变化,
- slots - 这个对我的问题不重要。
我也知道中央状态模式及其周围的所有东西。但有时可以告诉子组件 "do something, what changes your internal state".
是常见的以下是一些场景:
- TreeView(递归组件)和 "collapse all" 按钮 - 您需要告诉所有子组件折叠。我知道,这是适用的中央状态模式,但让我们假设节点状态 (expanded/collapsed) 是组件内部状态的一部分。
- 计数器 - 我可以在页面上有多个计数器,父组件有按钮 "increment all" - 同样,我需要在每个子组件上 "call" 递增方法。
问题是:如何实现"event based"组件之间父->子方向的通信。我觉得这有点普遍。
我做了一个例子jsbin。但是,我不确定它是否违反了vue js的一些基本思想。
https://jsbin.com/kakucuf/edit?html,js,output
const Foo = {
name: 'Foo',
template: '#a-template',
props: {
name: {
required: true,
type: String
},
},
data() {
return {
counter: 0
}
},
mounted() {
this.$on('increment', this.increment);
},
methods: {
increment() {
this.counter += 1;
}
}
}
new Vue({
el: "#app",
components: {
foo: Foo,
},
methods: {
incrementAll() {
this.$children.forEach((child) => child.$emit('increment'));
}
}
});
也许 computed properties and watchers 适合您。
在您的父组件中,您可以使用计算属性作为子组件的 props。一旦计算属性发生变化,您的子组件就会更新,这要归功于 Vue.js 反应功能。
并且,在您的子组件中,使用观察器来控制来自该组件上下文的更改。
从您的场景出发:
- 你可以在你的父组件上使用
collapse
prop,并且 "listen" (或者实际上 "watch")通过你的子组件中的观察者,观察者函数来改变它的值如果新值为true
,将在每个子组件内完成折叠工作
- 您可以从您的父组件发送一个
increment
道具,并通过您的子组件中的观察器观察其值的变化
例如,对于第二种情况,使用父组件中的 increment
道具,并在子组件中像这样观看它:
watch: {
increment: function (newVal) {
if (newVal === true) {
this.counter++
}
}
}
在您的父组件中,将 this.increment
设置为 true
将触发子组件中的观察器。如果您需要增加更多,请注意您必须将其设置回另一个值,例如 re-assigning true
.
null
这是一种 hack,应该代表您开始考虑 Vuex 等状态管理解决方案的时间!