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
}
}
})
Если бы вы могли прояснить прецедент и библиотеки, мы могли бы помочь больше.