Javascript VueJs操作内联模板并重新初始化它

Javascript VueJs操作内联模板并重新初始化它,javascript,html,vue.js,Javascript,Html,Vue.js,这个问题类似于,也类似于 不幸的是,由于$compile已被删除,该问题中的解决方案无法再用于当前的VueJS实现 我的用例如下所示: 我必须使用第三方代码来操纵页面,然后触发事件。现在,在触发该事件之后,我想让VueJS知道它应该重新初始化当前DOM (使用纯javascript编写的第三方允许用户向页面添加新的小部件) HTML 我的内联模板 Javascript-vuejs2.2 Vue.component('my-input', { data() { ret

这个问题类似于,也类似于

不幸的是,由于
$compile
已被删除,该问题中的解决方案无法再用于当前的VueJS实现

我的用例如下所示:

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

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

HTML


我的内联模板
Javascript-vuejs2.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)
Vue.component('my-input'{
数据(){
返回{
价值:1000
};
}
});
Vue.component('my-element'{
道具:{
值:字符串
},
方法:{
单击(){
log('单击按钮');
}
}
});
新Vue({
el:“#应用程序”,
});
//伪码
设置间隔(()=>{
//第三方库添加html:
var newContent=document.createElement('div');
newContent.innerHTML=`
`;document.querySelector('.wrapper').appendChild(newContent)
//      
//我现在如何重新序列化应用程序或
//要使用单击处理程序和值的包装组件?
//
}, 5000)

在进一步调查后,我联系了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);
  }
}

你可以在下面尝试一下

通常当我听到这样的问题时,它们似乎总是通过使用Vue更亲密和模糊的内在美来解决:)

我使用了相当多的“坚持拥有数据”的第三方LIB,它们用来修改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 
    }
  }
})

如果您能澄清用例和库,我们可能会提供更多帮助

新代码是否可以完全显示在页面上的任何位置?是的,有多个位置是动态生成的。我找到了一个解决方案,但感觉更像是一个黑客行为:黑客行为是不可避免的:你违反了与Vue的合同,Vue将控制DOM。这就是大型项目和现有解决方案的痛苦所在-你无法控制一切:(你想让
my input
的当前状态被
my element
s共享吗?这可能不那么麻烦。只是想澄清一下,如果你能清楚地表达出总体功能需求,你可能会得到一个比上述“变通方法”更简洁的答案-在我与Vue的3年工作中,我从来没有这样做过。我真的我认为答案可能是采用不同的方法来链接数据、dom、vue实例和您的第三方库。关键问题是,我们不仅要构建一个简单的应用程序,还要尝试将vue与CMS结合使用
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 
    }
  }
})