问题描述
如果我有一个只有一个插槽的组件,而不是仅仅渲染它的所有子元素,我想包装每个元素,我会做这样的事情:
Vue.component('MyElement',{
render: function(createElement){
for (let i = 0; i < this.$slots.default.length; i++) {
//create a wrapper element
let wrappedElement = createElement("div",{},this.$slots.default[i]);
// replace the current element in this slot,with the wrapped element
this.$slots.default[i] = wrappedElement;
}
return createElement("div",this.$slots.default);
}
}
像这样使用:
<MyElement ref="myElement">
<p>Item 1</p>
<p>Item 2</p>
</MyElement>
最终看起来像这样
<div>
<div>
<p>Item 1</p>
</div>
<div>
<p>Item 2</p>
</div>
</div>
到目前为止一切都很好。
现在,当我想使用
将另一个<p>
元素插入到 <MyElement>
中时
// get reference to <MyElement>
const myElement = this.$refs["myElement"];
// create a new element
var newElement = document.createElement("div");
newElement.innerText = "Hiya";
myElement .$el.appendChild(newElement);
新元素不会被包装,因为不会再次调用渲染,我如何完全控制插槽中每个子元素的渲染?或者是否有更好的时间以编程方式将子项附加到组件中?
谢谢
解决方法
如果您可以考虑为项目创建一个 component
。因此,当您想要添加新项目时,您只需创建一个 method
来调用项目组件。
我为此示例制作了一个代码片段。
Vue.component('MyElement',{
template: '#element-container',});
Vue.component('MyElementItem',{
template: '#element-item',props: {
innerText: {
type: String,default: '',}
}
});
new Vue({
el: '#app',data() {
return {
items: ['Item 1','Item 2','Item 3'],}
},method: {
// you can add a method that will add more items,then the MyElementItem component will be invoked.
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<my-element>
<my-element-item v-for="(item,index) in items" :key="index" :inner-text="item" />
</my-element>
</div>
<script type="text/x-template" id="element-container">
<div>
<slot></slot>
</div>
</script>
<script type="text/x-template" id="element-item">
<div>
<p>{{ innerText }}</p>
</div>
</script>