this.$children 表现得好像是反应性的
this.$children is behaving as if it were reactive
官方doc说this.$children
没有反应,
The direct child components of the current instance. Note there’s no order guarantee for $children, and it is not reactive...
因此,任何更改都不应触发任何重新渲染。 [this.$children
api 已从 vuejs v3 中删除,因此它仅适用于 v2.x
。]
我发现这很有趣... https://codepen.io/tatimblin/pen/oWKdjR
上面沙箱中的代码是使用 slot
& this.$childen
api 实现的选项卡 UI 的演示。
最初 tabs
组件持有对 this.$children
数组的引用,这是它的日志:
有趣的是,tab
的 isActive
道具正在使用该数组进行更改,但它反映在每个组件中,导致重新渲染..
我不确定这里发生了什么……也许我遗漏了什么。
模板:
<div id="root" class="container">
<tabs>
<tab name="Services" :selected="true">
<h1>What we do</h1>
</tab>
<tab name="Pricing">
<h1>How much we do it for</h1>
</tab>
<tab name="About Us">
<h1>Why we do it</h1>
</tab>
</tabs>
</div>
JS:
Vue.component('tabs', {
template: `
<div>
<div class="tabs">
<ul>
<li v-for="tab in tabs" :class="{ 'is-active': tab.isActive }">
<a :href="tab.href" @click="selectTab(tab)">{{ tab.name }}</a>
</li>
</ul>
</div>
<div class="tabs-details">
<slot></slot>
</div>
</div>
`,
data() {
return {tabs: [] };
},
created() {
this.tabs = this.$children;
},
methods: {
selectTab(selectedTab) {
this.tabs.forEach(tab => {
tab.isActive = (tab.name == selectedTab.name);
// this is how the isActive prop is changed, using this.$children
});
}
}
});
Vue.component('tab', {
template: `
<div v-show="isActive"><slot></slot></div>
`,
props: {
name: { required: true },
selected: { default: false}
},
data() {
return {
isActive: false
};
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g, '-');
}
},
mounted() {
this.isActive = this.selected;
}
});
new Vue({
el: '#root'
});
子元素是反应式的,因为它们本身就是 Vue 组件,除了 tabs
父元素之外,它们已经具有全部的反应能力。
文档引用意味着内容本身不会反应。这种区别可能会更清楚一些。另一方面,如果插槽内容不是具有 isActive
属性 的组件,则 tabs
将无法正常工作,这形成了紧密耦合。它不能与原始 HTML 插槽内容一起正常工作,例如:
<tabs>
<div>
Hi, I'm not a component
</div>
</tabs>
官方doc说this.$children
没有反应,
The direct child components of the current instance. Note there’s no order guarantee for $children, and it is not reactive...
因此,任何更改都不应触发任何重新渲染。 [this.$children
api 已从 vuejs v3 中删除,因此它仅适用于 v2.x
。]
我发现这很有趣... https://codepen.io/tatimblin/pen/oWKdjR
上面沙箱中的代码是使用 slot
& this.$childen
api 实现的选项卡 UI 的演示。
最初 tabs
组件持有对 this.$children
数组的引用,这是它的日志:
有趣的是,tab
的 isActive
道具正在使用该数组进行更改,但它反映在每个组件中,导致重新渲染..
我不确定这里发生了什么……也许我遗漏了什么。
模板:
<div id="root" class="container">
<tabs>
<tab name="Services" :selected="true">
<h1>What we do</h1>
</tab>
<tab name="Pricing">
<h1>How much we do it for</h1>
</tab>
<tab name="About Us">
<h1>Why we do it</h1>
</tab>
</tabs>
</div>
JS:
Vue.component('tabs', {
template: `
<div>
<div class="tabs">
<ul>
<li v-for="tab in tabs" :class="{ 'is-active': tab.isActive }">
<a :href="tab.href" @click="selectTab(tab)">{{ tab.name }}</a>
</li>
</ul>
</div>
<div class="tabs-details">
<slot></slot>
</div>
</div>
`,
data() {
return {tabs: [] };
},
created() {
this.tabs = this.$children;
},
methods: {
selectTab(selectedTab) {
this.tabs.forEach(tab => {
tab.isActive = (tab.name == selectedTab.name);
// this is how the isActive prop is changed, using this.$children
});
}
}
});
Vue.component('tab', {
template: `
<div v-show="isActive"><slot></slot></div>
`,
props: {
name: { required: true },
selected: { default: false}
},
data() {
return {
isActive: false
};
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g, '-');
}
},
mounted() {
this.isActive = this.selected;
}
});
new Vue({
el: '#root'
});
子元素是反应式的,因为它们本身就是 Vue 组件,除了 tabs
父元素之外,它们已经具有全部的反应能力。
文档引用意味着内容本身不会反应。这种区别可能会更清楚一些。另一方面,如果插槽内容不是具有 isActive
属性 的组件,则 tabs
将无法正常工作,这形成了紧密耦合。它不能与原始 HTML 插槽内容一起正常工作,例如:
<tabs>
<div>
Hi, I'm not a component
</div>
</tabs>