这个问题类似于VueJS re-compile HTML in an inline-template component,也类似于How to make Vue js directive working in an appended html element

不幸的是,由于删除了$compile,该问题的解决方案不能再用于当前的VueJS实现。

我的用例如下:

我必须使用第三方代码来操纵页面并随后触发事件。现在,在触发该事件之后,我想让VueJS知道它应该重新初始化当前DOM。

(使用纯JavaScript编写的第三方允许用户向页面添加新的小部件)

https://jsfiddle.net/5y8c0u2k/

的HTML

<div id="app">
    <my-input inline-template>
  <div class="wrapper">
  My inline template<br>
  <input v-model="value">
  <my-element inline-template :value="value">
    <button v-text="value" @click="click"></button>
  </my-element>
  </div>
    </my-input>
</div>

Javascript-VueJS 2.2
Vue.component('my-input', {
    data() {
        return {
            value: 1000
        };
    }
});

Vue.component('my-element', {
    props: {
        value: String
    },
    methods: {
        click() {
            console.log('Clicked the button');
        }
    }
});

new Vue({
    el: '#app',
});

// Pseudo code
setInterval(() => {
  // Third party library adds html:
  var newContent = document.createElement('div');
  newContent.innerHTML = `<my-element inline-template :value="value">
     <button v-text="value" @click="click"></button>
  </my-element>`;   document.querySelector('.wrapper').appendChild(newContent)

   //
   // How would I now reinialize the app or
   // the wrapping component to use the click handler and value?
   //

}, 5000)

最佳答案

经过进一步调查,我联系了VueJs团队并获得了feedback,以下方法可能是有效的解决方案:

/**
 * Content change handler
 */
function handleContentChange() {
  const inlineTemplates = document.querySelector('[inline-template]');
  for (var inlineTemplate of inlineTemplates) {
    processNewElement(inlineTemplate);
  }
}


/**
 * Tell vue to initialize a new element
 */
function processNewElement(element) {
  const vue = getClosestVueInstance(element);
  new Vue({
    el: element,
    data: vue.$data
  });
}

/**
 * Returns the __vue__ instance of the next element up the dom tree
 */
function getClosestVueInstance(element) {
  if (element) {
    return element.__vue__ || getClosestVueInstance(element.parentElement);
  }
}

您可以在以下fiddle中尝试

09-25 18:15