Ahm*_*lam 3 javascript aem vue.js vuejs2
我有一个用例(如下),我需要mount(如果是正确的术语)一个通过jQuery插入DOM的Vue.js组件模板,我可以设置一个Mutation Observer或对某些事件做出反应,当发生突变。
我正在使用Vue.js v2
这是我整理来说明这一点的简单示例:
实时jsFiddle https://jsfiddle.net/w7q7b1bh/2/
以下HTML包含inlined-templates两个组件
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div id="app">
<!-- The use of inline-template is required for my solution to work -->
<simple-counter inline-template>
<button v-bind:style="style" v-on:click="add">clicks: {{ counter }}</button>
</simple-counter>
<simple-counter inline-template>
<button v-on:click="counter += 1">{{ counter }}</button>
</simple-counter>
</div>
<button id="mutate">Mutate</button>
Run Code Online (Sandbox Code Playgroud)
js:
// simple counter component
Vue.component('simple-counter', {
data: function() {
return {
counter: 0,
style: {
color: 'red',
width: '200px'
}
}
},
methods: {
add: function() {
this.counter = this.counter + 1;
this.style.color = this.style.color == 'red' ? 'green' : 'red';
}
}
})
// create the Vue instance
var initV = () => new Vue({
el: '#app'
});
// expose the instance for later use
window.v = initV();
// click handler that will add a new `simple-counter` template to the Vue.el scope
$('#mutate').click(function(){
$('#app').append(` <div is="simple-counter" inline-template>
<button v-bind:style="style" v-on:click="add">click to add: <span class="inactive" v-bind:class="{ active: true }">{{ counter }}</span></button></div>`)
// do something after the template is incerted
window.v.$destroy()
window.v = initV(); // does not work
})
Run Code Online (Sandbox Code Playgroud)
如代码中所述,销毁重新实例化的Vue实例不起作用,我理解为什么,在第一次Vue实例化时将组件的模板更改为其最终HTML,而当您尝试第二次实例化时,模板却没有那里,组件不 mounted
我希望能够在突变后找到新添加的组件并仅安装那些组件,这可能吗?如何?
更新:
我能够通过实例化一个新的Vue实例找到一种方法,该实例将el设置为DOM的特定突变部分而不是整个#app树:
$('#mutate').click(function(){
var appended =
$(`
<div is="simple-counter" inline-template>
<button v-bind:style="style" v-on:click="add">
click to add: {{ counter }}
</button>
</div>`
).appendTo($('#app'));
var newV = new Vue({el: appended[0]});
});
Run Code Online (Sandbox Code Playgroud)
似乎可以工作,但看起来也很丑陋,我不确定这可能还有其他含义。
用例:
我正在研究一种为称为Adobe Experience Manager(AEM)的CMS编写Vue.js组件的方法。
我编写组件时使用inlined-template它给我带来了SEO的优势,以及使用另一种称为HTL的模板语言在服务器端进行渲染的优势。
AEM创作的工作方式是,当编辑组件(通过对话框)时,该特定组件在服务器端重新呈现,然后注入回DOM以替换旧组件,所有这些都通过Ajax和jQuery完成(没有刷新浏览器)。
这是一个例子
AEM组件模板:
<button>${properties.buttonTitle}</button>
这是作者可能会做的事情:
保存后,将发送一个ajax,在服务器上重新呈现组件HTML,并返回新的HTML。现在,该HTML通过jQuery替换了旧的HTML(对DOM进行了更改)
这对于静态组件来说很好,但是如果这是Vue.js组件,那么我如何在保持其他组件挂载的同时动态挂载它。
一个简单的解决方案是刷新页面...但这只是糟糕的体验...必须有更好的方法。
感谢@liam,我能够找到解决我问题的合适方法
用HTML模板对DOM进行更改后,请保留对该模板的父元素的引用
例如:
var $template = $('<div is="simple-counter" inline-template> ..rest of template here.. <div>').appendTo('#app') // app is the Vue instance el or a child of it
Run Code Online (Sandbox Code Playgroud)
现在,您可以创建组件的新实例并将其添加$template为el属性
如果我的组件是:
var simpleCounterComponent = Vue.component('simple-counter', {
data: function() {
return {
counter: 0,
style: {
color: 'red',
width: '200px'
}
}
},
methods: {
add: function() {
this.counter = this.counter + 1;
this.style.color = this.style.color == 'red' ? 'green' : 'red';
}
}
})
Run Code Online (Sandbox Code Playgroud)
我可以:
var instance = new simpleCounterComponent({
el: $template.get(0) // getting an HTML element not a jQuery object
});
Run Code Online (Sandbox Code Playgroud)
这样,新添加的模板已成为Vue组件
看一下这个小提琴,它基于以下问题提供了工作示例:
| 归档时间: |
|
| 查看次数: |
4258 次 |
| 最近记录: |