将 parent 组件的属性传递给 Vue 中所有嵌入的 children 组件
Pass properties from parent component to all transcluded children component in Vue
我想将一些属性从 parent 传递给他的所有 children,当这些属性被嵌入时(内容分发语法)。在这种情况下,parent 不知道(据我所知)他的 children,所以我不知道如何进行。
更具体地说,我想要一种写法:
<my-parent prop1="foo" prop2="bar">
<my-children></my-children> <!-- Must know content of prop1 and prop2 -->
<my-children></my-children> <!-- Must know content of prop1 and prop2 -->
</my-parent>
不必写这个:
<my-parent prop1="foo" prop2="bar">
<my-children prop1="foo" prop2="bar"></my-children>
<my-children prop1="foo" prop2="bar"></my-children>
</my-parent>
可能吗?谢谢
Props 只允许数据流一级。如果您想永久保留数据,可以改用事件总线。
在您的主文件中实例化一个带有空 Vue 实例的事件总线。
var bus = new Vue();
然后在您的父级中,发出带有要传递的数据的事件
bus.$emit('myEvent', dataToBePassed);
收听myEvent
任何您想获取数据的地方。在您的情况下,它是在您的子组件中完成的
bus.$on('myEvent', function(data) {
.....
});
此时(我不是vue专家)我只能在这个解决方案中思考。
分配每个组件的道具很无聊我同意,那么为什么不以编程方式进行呢?
// Create a global mixin
Vue.mixin({
mounted() { // each component will execute this function after mounted
if (!this.$children) {
return;
}
for (const child of this.$children) { // iterate each child component
if (child.$options._propKeys) {
for (const propKey of child.$options._propKeys) { // iterate each child's props
// if current component has a property named equal to child prop key
if (Object.prototype.hasOwnProperty.call(this, propKey)) {
// update child prop value
this.$set(child, propKey, this[propKey]);
// create a watch to update value again every time that parent property changes
this.$watch(propKey, (newValue) => {
this.$set(child, propKey, newValue);
});
}
}
}
}
},
});
这有效,但你会收到一条丑陋的 Vue 警告消息:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
我不确定这是否是一个好的解决方案,但它确实有效,所以如果您决定使用,请记住 Global-Mixin 建议:
Use global mixins sparsely and carefully, because it affects every
single Vue instance created, including third party components.
请在 https://github.com/aldoromo88/PropsConvention
查看完整示例
希望对您有所帮助
这是我的解决方案,可能不是很好,但这是我现在想做的最干净的解决方案。原则是创建计算属性,如果它们存在,将使用自己的组件属性,否则获取 $parent 值。然后可以在 this._prop.
中访问真正的道具
Vue.component('my-children', {
props: ["prop1", "prop2"],
template: "<div>{{_prop1}} - {{_prop2}}</div>",
computed: {
_prop1: function() {
return this.prop1 || this.$parent.prop1;
},
_prop2: function() {
return this.prop2 || this.$parent.prop2;
}
}
});
这是一个 mixin 生成器,它以更优雅的方式执行此操作,并且可能具有多个级别:
function passDown(...passDownProperties) {
const computed = {};
passDownProperties.forEach((prop) => {
computed["_" + prop] = function() {
return this[prop] || this.$parent[prop] || this.$parent["_" + prop];
};
});
return { computed };
}
Vue.component('my-children', {
props: ["prop1", "prop2"],
template: "<div>{{_prop1}} - {{_prop2}}</div>",
mixins: [passDown("prop1", "prop2")]
});
我想将一些属性从 parent 传递给他的所有 children,当这些属性被嵌入时(内容分发语法)。在这种情况下,parent 不知道(据我所知)他的 children,所以我不知道如何进行。
更具体地说,我想要一种写法:
<my-parent prop1="foo" prop2="bar">
<my-children></my-children> <!-- Must know content of prop1 and prop2 -->
<my-children></my-children> <!-- Must know content of prop1 and prop2 -->
</my-parent>
不必写这个:
<my-parent prop1="foo" prop2="bar">
<my-children prop1="foo" prop2="bar"></my-children>
<my-children prop1="foo" prop2="bar"></my-children>
</my-parent>
可能吗?谢谢
Props 只允许数据流一级。如果您想永久保留数据,可以改用事件总线。
在您的主文件中实例化一个带有空 Vue 实例的事件总线。
var bus = new Vue();
然后在您的父级中,发出带有要传递的数据的事件
bus.$emit('myEvent', dataToBePassed);
收听myEvent
任何您想获取数据的地方。在您的情况下,它是在您的子组件中完成的
bus.$on('myEvent', function(data) {
.....
});
此时(我不是vue专家)我只能在这个解决方案中思考。
分配每个组件的道具很无聊我同意,那么为什么不以编程方式进行呢?
// Create a global mixin
Vue.mixin({
mounted() { // each component will execute this function after mounted
if (!this.$children) {
return;
}
for (const child of this.$children) { // iterate each child component
if (child.$options._propKeys) {
for (const propKey of child.$options._propKeys) { // iterate each child's props
// if current component has a property named equal to child prop key
if (Object.prototype.hasOwnProperty.call(this, propKey)) {
// update child prop value
this.$set(child, propKey, this[propKey]);
// create a watch to update value again every time that parent property changes
this.$watch(propKey, (newValue) => {
this.$set(child, propKey, newValue);
});
}
}
}
}
},
});
这有效,但你会收到一条丑陋的 Vue 警告消息:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
我不确定这是否是一个好的解决方案,但它确实有效,所以如果您决定使用,请记住 Global-Mixin 建议:
Use global mixins sparsely and carefully, because it affects every single Vue instance created, including third party components.
请在 https://github.com/aldoromo88/PropsConvention
查看完整示例希望对您有所帮助
这是我的解决方案,可能不是很好,但这是我现在想做的最干净的解决方案。原则是创建计算属性,如果它们存在,将使用自己的组件属性,否则获取 $parent 值。然后可以在 this._prop.
中访问真正的道具Vue.component('my-children', {
props: ["prop1", "prop2"],
template: "<div>{{_prop1}} - {{_prop2}}</div>",
computed: {
_prop1: function() {
return this.prop1 || this.$parent.prop1;
},
_prop2: function() {
return this.prop2 || this.$parent.prop2;
}
}
});
这是一个 mixin 生成器,它以更优雅的方式执行此操作,并且可能具有多个级别:
function passDown(...passDownProperties) {
const computed = {};
passDownProperties.forEach((prop) => {
computed["_" + prop] = function() {
return this[prop] || this.$parent[prop] || this.$parent["_" + prop];
};
});
return { computed };
}
Vue.component('my-children', {
props: ["prop1", "prop2"],
template: "<div>{{_prop1}} - {{_prop2}}</div>",
mixins: [passDown("prop1", "prop2")]
});