VueJs操作内联模板并重新初始化它 [英] VueJs manipulate inline template and reinitialize it

查看:146
本文介绍了VueJs操作内联模板并重新初始化它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题类似于 VueJS重新编译HTML in一个内联模板组件以及如何使Vue js指令在附加的HTML元素中工作



不幸的是,该问题的解决方案不能再用于当前作为 $ compile 的VueJS实现已被移除。



我的用例如下:

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


$ b (用纯javascript编写的第三方允许用户添加新的小部件到一个页面)



https:// jsfiddle .net / 5y8c0u2k /



HTML

 < ; div id =app> 
< my-input inline-template>
< div class =wrapper>
我的内联模板< 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',{
道具:{
值:字符串
},
方法:{
点击(){
console.log('点击按钮');
}
}
});

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

伪代码
setInterval(()=> {
//第三方库添加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)
$ b $ // b $ b //现在重新初始化应用程序或
//使用单击处理程序和值的包装组件?
//

},5000)


解决方案

经过进一步调查,我接触到了VueJs团队,并获得了 feedback 表示以下方法可能是一个有效的解决方案:

 / ** 
*内容更改处理程序
* /
函数handleContentChange(){
const inlineTemplates = doc ument.querySelector( [直列模板]);
(inlineTemplates的var inlineTemplate){
processNewElement(inlineTemplate);



$ b $ **
*告诉vue初始化一个新元素
* /
function processNewElement(元素){
const vue = getClosestVueInstance(element);
new Vue({
el:element,
data:vue。$ data
});

$ b $ **
*返回dom树中下一个元素的__vue__实例
* /
function getClosestVueInstance(element){
if(element){
return element .__ vue__ || getClosestVueInstance(element.parentElement);


$ / code $ / pre

你可以在下面试试小提琴


this question is similar to VueJS re-compile HTML in an inline-template component and also to How to make Vue js directive working in an appended html element

Unfortunately the solution in that question can't be used anymore for the current VueJS implementation as $compile was removed.

My use case is the following:

I have to use third party code which manipulates the page and fires an event afterwards. Now after that event was fired I would like to let VueJS know that it should reinitialize the current DOM.

(The third party which is written in pure javascript allows an user to add new widgets to a page)

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)

解决方案

After further investigation I reached out to the VueJs team and got the feedback that the following approach could be a valid solution:

/**
 * 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);
  }
}

You can try it in the following fiddle

这篇关于VueJs操作内联模板并重新初始化它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆