VueJs манипулирует встроенным шаблоном и повторно инициализирует его

этот вопрос похож на VueJS перекомпилировать HTML в компоненте встроенного шаблона, а также Как сделать Vue js, работающая в добавленном html-элементе

К сожалению, решение в этом вопросе больше не может быть использовано для текущей реализации VueJS при удалении $compile.

Мой пример использования:

Мне нужно использовать сторонний код, который манипулирует страницей и затем запускает событие. Теперь после того, как это событие было уволено, я хотел бы сообщить 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)

Ответ 1

После дальнейшего расследования я обратился к команде VueJs и получил обратную связь, что следующий подход может быть допустимым решением:

/**
 * 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

Ответ 2

Обычно, когда я слышу такие вопросы, они кажутся всегда решаемыми, используя некоторые из Vue более интимной и скрытой внутренней красоты:)

Я использовал довольно много сторонних библиотек, которые "настаивают на владении данными", которые они используют для изменения DOM, но если вы можете использовать эти события, вы можете проксировать изменения в принадлежащем Vue объекте - или, если вы не можете иметь объект, принадлежащий vue, вы можете наблюдать независимую структуру данных через вычисленные свойства.

window.someObjectINeedtoObserve = {...}

yourLib.on('someEvent', (data) => {
  // affect someObjectINeedtoObserve...
})

new Vue ({
  // ...
  computed: {
    myObject () {
      // object now observed and bound and the dom will react to changes
      return window.someObjectINeedtoObserve 
    }
  }
})

Если бы вы могли прояснить прецедент и библиотеки, мы могли бы помочь больше.