2.2.6
https://jsbin.com/mugosexini/edit?html,css,js,output
const child = {
name: "child",
render: function () {
console.log(this.$slots.default)
return 1
}
}
const parent = {
template: "<div>\
<child>\
<p>1</p>\
<p>2</p>\
</child>\
</div>",
components: {
child: child
}
}
the child component console the $slots.default
is a vnodes list which length is 3.
It also reproduce when I wrote parent
template in <template>
element
this.$slots.default
DO NOT INCLUDE empty vnodes
this.$slots.default include a empty vnode between two <p>
element
this.$slots.default seems different from React's this.props.children...
This is expected. Vue preserves whitespaces between elements unless you use vue-loader
with preserveWhitespace: false
.
Please consider mentioning this in the docs somewhere, because people normally do not expect this behavior. I personally for one spent considerable time just to find out here that this is what is causing my code to deviate from expected behavior. Thanks.
Ditto that. This behavior is quite confusing, especially when we need to determine if a slot is simply receiving empty strings. In this example, you can see that the slot is being rendered even thought it receives nothing: http://jsfiddle.net/teddyrised/p07fgw54/3/
Given the following template:
<div id="root">
<custom desc="Slot with string"><template slot="test-slot">aaa</template></custom>
<custom desc="Slot with `data` defined content"><template slot="test-slot">{{ this.emptyContent }}</template></custom>
<custom desc="Slot with `data` defined empty content"><template slot="test-slot">{{ this.emptyContent }}</template></custom>
<custom desc="Slot that is empty"><template slot="test-slot"></template></custom>
<custom desc="No slot defined"></custom>
</div>
<template id="template">
<div>
<span>Always here.</span>
<strong v-if="hasSlotData">
Displayed only when slot passed: <slot name="test-slot"></slot>.
</strong>
<span>{{ this.desc }}</span>
</div>
</template>
And the following JS setup:
Vue.component('Custom', {
template: '#template',
props: {
desc: String
},
computed: {
hasSlotData() {
return this.$slots['test-slot'];
},
hasSlot() {
return true;
}
}
});
new Vue({
el: '#root',
data: {
content: 'Has random content',
emptyContent: ''
}
});
I would expect the last 3 <custom>
elements to not render the <strong>
element at all, but it does not work as intended.
好吧... 我也觉得这点应该提一下 不然有点坑
Most helpful comment
Please consider mentioning this in the docs somewhere, because people normally do not expect this behavior. I personally for one spent considerable time just to find out here that this is what is causing my code to deviate from expected behavior. Thanks.