从外部来源(例如api),我得到了一个组件定义:
{
"component": "b-btn",
"content": "Button",
"attr": {
"title": "Edit"
},
"events": {
"click": "doSomething"
}
}
此定义与动态组件一起使用:
<component :is="item.component" v-bind="item.attr">
{{ item.content }}
</component>
,并且按预期方式工作(显示了vue-bootstrap按钮,标题为“ Edit”,按钮文本为“ Button”)。
现在我也想添加事件。从VueJS 2.4(https://vuejs.org/v2/api/#v-on)开始,您可以使用<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
之类的对象语法来定义事件,我认为,仅添加v-on="item.events"
可能会起作用:
<component :is="item.component" v-bind="item.attr" v-on="item.events">
{{ item.content }}
</component>
但这不是,因为对象属性click
的值是一个字符串("doSomething"
)而不是可调用的。
// Just to make it clear
{"click": "doSomething"} != {"click": doSomething}
是否可以将动态事件(从JSON)绑定到组件?
答案 0 :(得分:1)
是的,有可能。您必须以编程方式检查组件中是否存在具有给定名称的函数,如果存在,则使用该函数代替字符串。
因此,您需要操作JSON。
我在CodeSandbox中构建了一个测试用例,其中使用一个计算字段来更新events
属性,方法是检查events
对象中每个键是否存在具有给定名称的函数,并将该值替换为该函数
说我的子组件有一个事件clicked
,该事件会在单击按钮时触发。
我的父组件如下所示:
data() {
return {
item: {
component: "TestComponent",
content: "Button",
attr: {
title: "Edit"
},
events: {
clicked: "alertText"
}
}
};
},
computed: {
componentItem() {
let item = this.item;
if (item.hasOwnProperty("events")) {
let events = item.events;
for (let i in events) {
if (events.hasOwnProperty(i)) {
let functionName = events[i];
if (
this.hasOwnProperty(functionName) &&
typeof this[functionName] === "function"
) {
// function exists
item.events[i] = this[functionName];
}
}
}
}
return item;
}
},
methods: {
alertText() {
console.log("I was clicked");
}
}
在这里查看工作示例: https://codesandbox.io/s/oo9zj8qy9y