开发者问题收集

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

2021-09-24
2121

在 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 .

我试图实现的目标是否可行?我是否忽略了这种策略的缺点?

2个回答

尝试创建一个适用于所有按钮的方法

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>
Aliaksandr Pitkevich
2021-09-24

您可以使用函数名提供的通用方法调用 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 处理程序,并将您的自定义方法作为事件侦听器。 (当您以后想要将这些物品分成单独的组件时,这会变得很容易。)

Philip
2021-09-24