【问题标题】:How to get onclick="vm.$refs.foo.addThing()" working in Vue when calling from external JS?从外部 JS 调用时如何让 onclick="vm.$refs.foo.addThing()" 在 Vue 中工作?
【发布时间】:2019-01-14 05:29:43
【问题描述】:

我正在尝试让我的代码看起来类似于 jsFiddle 工作。

代码基本上在Vue实例之外有onclick="vm.$refs.foo.addThing()"(我无法改变它的方式),它调用Vue的methods中的一个函数。

但是,它现在不起作用,我不明白为什么会这样。

HomeView.vue

var MyComponent = Vue.extend({
  template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>',
  data: function() {
    return {
      things: ['first thing']
    };
  },
  methods: {
    addThing: function() {
        this.things.push('another thing ' + this.things.length);
    }
  }
});

var vm = new Vue({
  el: '#app',
  components: {
  'my-component': MyComponent
  }
});

HTML

<div id="app">
<h1>Component Test</h1>
<my-component ref="foo"></my-component>
</div>

<button onclick="vm.$refs.foo.addThing()">External Button</button>

【问题讨论】:

  • @Andrew1325 不起作用,因为&lt;button&gt; ... 在 Vue 实例之外,也就是在纯 HTML 中(我无法改变它的方式)。
  • 奇怪的是,这个小提琴在 Codepen 中工作正常:codepen.io/tony19/pen/NeeEbm?editors=1010
  • 如果你在正文末尾链接你的js文件,这个问题可能不会出现。

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

您可以在模板处理之前访问$refs(检查docs)。

请看修改后的代码:https://jsfiddle.net/b5oset1w/17/

Javascript:

var MyComponent = Vue.extend({
  template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>',
  data: function() {
    return {
      things: ['first thing']
    };
  },
  methods: {
    addThing: function() {
      this.things.push('another thing ' + this.things.length);
    }
  }
});

var vm = new Vue({
  el: '#app',
  components: {
    'my-component': MyComponent
  },
  mounted: function() {
    console.log(this.$refs)
  },
  methods: {
    onAddThing: function() {
      this.$refs.foo.addThing()
    }
  }
});

模板:

<div id="app">
  <h1>Component Test</h1>
  <my-component ref="foo"></my-component>

  <button @click="onAddThing">External Button</button>

</div>

【讨论】:

    【解决方案2】:

    您可以将此方法公开给window 对象,但它被认为是一种反模式,您可能应该考虑以某种方式将此按钮移动到组件内部。

    或者,使用一些技巧:

    const MyComponent = Vue.extend({
      template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>',
      data: function() {
        return {
          things: ['first thing']
        };
      },
      methods: {
        addThing: function() {
          this.things.push('another thing ' + this.things.length);
        }
      }
    });
    
    const vm = new Vue({
      el: '#app',
    
      mounted() {
        var btn = document.getElementById('btn-external');
    
        btn.addEventListener('click', this.$refs.foo.addThing);
      },
    
      components: {
        'my-component': MyComponent
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
    <div id="app">
      <h1>Component Test</h1>
      <my-component ref="foo"></my-component>
    </div>
    
    <button id="btn-external">External Button</button>

    【讨论】:

      【解决方案3】:

      实现此目的的另一种方法是也为外部按钮创建一个 vue 实例。就像下面的示例代码。

          var MyComponent = Vue.extend({
              template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>',
              data: function() {
                  return {
                      things: ['first thing']
                  };
              },
              methods: {
                  addThing: function() {
                      this.things.push('another thing ' + this.things.length);
                  }
              }
          });
      
          var vm = new Vue({
              el: '#app',
              components: {
                  MyComponent: MyComponent
              }
          });
      
              var vm1 = new Vue({
              el: '#newapp',
              methods:{
              	clickAction:function(){
              		vm.$refs.foo.addThing();
              	}
              }
          });
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
      <div id="app">
      <h1>Component Test</h1>
      <my-component ref="foo"></my-component>
      </div>
      
      <div id="newapp">
         <button @click="clickAction">External Button</button>
      </div>

      【讨论】:

      • 除非你将在这个 additional Vue 实例中包含一些其他数据和方法(除了“外部按钮”),我认为这不会值得花费的所有资源(例如,必须经历完整的生命周期挂钩)。
      猜你喜欢
      • 1970-01-01
      • 2021-12-29
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多