Vue.js 2:在事件处理程序的函数调用中转换字符串



在Vue.js 2中,我想将字符串转换为函数调用,以便它可以设置为事件处理程序。我相信这将是非常实用的,特别是在基于对象列表动态创建大量元素(例如按钮)时。

new Vue({
el: "#app",
data: {
myArray: [
{ value: 1, fn: "firstMethod" },
{ value: 2, fn: "secondMethod" },
],
},
methods: {
firstMethod() {
console.log("'firstMethod' was executed.");
},
secondMethod() {
console.log("'secondMethod' was executed.");
},
},
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<template v-for="elem in myArray">
<button @click="elem.fn">  <!-- Here is where I am stucked. -->
<!-- <button> -->
{{elem.value}}
</button>
</template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="script.js"></script>
</body>
</html>

我这样做的第一次尝试是将myArray中的fn属性设置为指向this(例如fn: this.firstMethod)相应函数的指针。问题是,我相信,在定义的时候,这些函数仍然是未知的,因为我得到:[Vue warn]: Invalid handler for event "click": got undefined.

我想要达到的是可能的吗?这个策略是否有我忽略了的缺点?

尝试创建一个方法,它将与所有按钮工作

new Vue({
el: "#app",
data: {
myArray: [
{ value: 1, fn: "firstMethod" },
{ value: 2, fn: "secondMethod" },
],
},
methods: {
basicMethod(name) {
console.log(`'${name}' was executed.`);
if(name === 'firstMethod') {
//some logic, and so on for other methods if u need
}
},
},
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<template v-for="elem in myArray">
<button @click="basicMethod(elem.fn)">  <!-- Here is where I am stucked. -->
<!-- <button> -->
{{elem.value}}
</button>
</template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="script.js"></script>
</body>
</html>

可以使用函数名提供的泛型方法调用this[ fn ]();

但是出于安全原因,您可能希望这些自定义方法存在于对象中,而不仅仅是在主this中,这样其他方法就不能被调用了。

同时,你需要在调用方法之前检查它是否存在。

它看起来像这样:

new Vue({
el: "#app",
data: {
myArray: [
{ value: 1, fn: "firstMethod" },
{ value: 2, fn: "secondMethod" },
{ value: 3, fn: "nonExistingMethod" }, // Won't throw an error
{ value: 4, fn: "someImportantSecureMethod" }, // Won't be called
],
customMethods: {
firstMethod: function() {
console.log("'firstMethod' was executed.");
},
secondMethod: function() {
console.log("'secondMethod' was executed.");
},
},
},
methods: {
callCustomMethod(fn) {
// Make sure it exists
if (typeof this.customMethods[fn] === "function") {
// Only methods inside the customMethods object are available
this.customMethods[fn]();
}
},
someImportantSecureMethod() {
console.log('The method may not be exposed to dynamic calling!');
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template v-for="elem in myArray">
<button @click="callCustomMethod(elem.fn)">
<!-- <button> -->
{{elem.value}}
</button>
</template>
</div>

作为旁注:您也可以考虑使用自定义事件(请参阅文档)。使用$emit('custom-event-name')作为v-on:click处理程序,并使用自定义方法作为事件侦听器。(当您以后可能想要将这些项放入单独的组件中时,这会使它变得容易。)