【问题标题】:Vue: Bind Change event to dynamically inserted contentVue:将更改事件绑定到动态插入的内容
【发布时间】:2021-07-24 01:06:45
【问题描述】:

我有一个 Vue 应用程序,它从 API 获取一个 html,其中包含一些代码,例如 <div class="play-video"> <input type="text" class="input-1"/></div>

使用 axios 通过 promise 调用 API,它被插入到 dom 中,如下所示:

<div v-if="content" v-html="content"></div>

如何使用 .input-1 类将更改事件绑定到子输入?

【问题讨论】:

    标签: javascript html css typescript vue.js


    【解决方案1】:

    对我来说,有两种方法可以达到顶峰:

    1. 在 vue 应用程序中,使用 vanilla javascript 将这些节点附加到 DOM,然后查询它们的输入并添加事件处理程序。由于您在 Vue 应用程序中,您可以编写处理程序来与 Vue 组件交互。或者,您可以使用返回这些元素的 vuex getter 做一些花哨的事情(如果它们仍然附加到文档中)。
    2. 使用Vue.compile 从html 创建渲染函数或添加async omponent。但是,这只有在您有一种可靠的方式将@change="doSomething" 添加到模板时才有效。因此,除非您控制模板的来源,否则我可能应该选择选项 1)。

    无论您做什么,都要牢记恶意注入。

    const someHtml = '<div class="play-video"><input type="text" class="input-1"/></div>'
    
    var app = new Vue({
      el: '#app',
      mounted() {
        const dynamicContent = document.createElement('div');
        dynamicContent.innerHTML = someHtml;
        dynamicContent.querySelector('input').addEventListener('change',
          e => this.inputValue = e.target.value);
        this.$refs.container.appendChild(dynamicContent);
      },
      data() {
        return {
          name: 'Vue',
          inputValue: ''
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <div>type something below then click this text</div>
      <div ref="container"></div>
      <div>The user entered: {{inputValue}}</div>
    </div>

    【讨论】:

      【解决方案2】:

      您可以在容器中查询这些输入,并为每个输入添加一个事件处理程序:

      1. 在容器div上应用template ref(命名为container):

        <div ref="container">
        
      2. content 上添加一个watcher,用于查询容器(通过this.$refs.container.querySelectorAll())以获取&lt;input class="input-1"&gt;,并为每个输入添加一个事件处理程序。请注意,处理程序需要等到$nextTick(),之后v-html 指令才有机会更新。

        export default {
          watch: {
            content: {
              async handler(content) {
                // wait til v-html directives takes effect
                await this.$nextTick()
        
                this.$refs.container
                  .querySelectorAll('.input-1')
                  .forEach((input) => input.addEventListener('change', this.onInputChange))
              },
              immediate: true,
            },
          },
          methods: {
            onInputChange(e) {
              console.log('input change')
            },
          },
        }
        

      demo

      【讨论】:

        猜你喜欢
        • 2019-05-21
        • 1970-01-01
        • 2017-04-13
        • 1970-01-01
        • 1970-01-01
        • 2018-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多