在我的插槽中包装动态添加的子元素
Wrapping dynamically added child elements in my slot
如果我有一个只有一个插槽的组件,而不是只渲染它的所有子元素,我想包装每个元素,我会这样做:
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);
新元素不会被包装,因为不会再次调用 render,我如何才能完全控制插槽中每个子元素的渲染?还是有更好的时间以编程方式将子项附加到组件中?
谢谢
如果您可以考虑为项目创建一个 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>
如果我有一个只有一个插槽的组件,而不是只渲染它的所有子元素,我想包装每个元素,我会这样做:
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);
新元素不会被包装,因为不会再次调用 render,我如何才能完全控制插槽中每个子元素的渲染?还是有更好的时间以编程方式将子项附加到组件中?
谢谢
如果您可以考虑为项目创建一个 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>