我有一个像这样的文件组件:
<template>
<div>
<template v-if="offers.length > 3">
<a href="#">View all offers here</a>
</template>
<template v-else-if="offers.length > 1">
<offer v-for="offer in offers" :data="offer"></offer>
</template>
<template v-else-if="offers.length == 1">
<offer :title="The offer" :data="offers[0]"></offer>
</template>
</div>
</template>
根据offers
的数量,我选择要渲染的数量。
问题:如何有效获取/计算<offer>
组件的数量?我还需要这个号码来反应。
答案 0 :(得分:1)
我的回答完全基于你想要计算Offer
组件的实例化和破坏的想法。我不确定你为什么不算offers.length
。也许其他事情可以触发实例化。
让组件在创建和销毁时发出事件,并相应地设置父轨道。
或者(也许是矫枉过正)你可以使用Vuex并创建一个Offer
提交创建和销毁的商店。这意味着,每次在标记中添加@offer-created/destroyed
时,您都不必手动附加<offer>
指令。
以下示例中包含这两种方法:
const store = new Vuex.Store({
strict: true,
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
}
});
const Offer = {
props: ["data"],
template: "<div>{{data.name}}</div>",
created() {
console.log("Created");
this.$emit("offer-created");
this.$store.commit("increment");
},
destroyed() {
console.log("Destroyed");
this.$emit("offer-destroyed");
this.$store.commit("decrement");
}
};
const app = new Vue({
el: "#app",
store,
components: {
offer: Offer
},
data() {
return {
offers: [],
offerCount: 0
};
},
computed: {
offerCountFromStore() {
return this.$store.state.count;
}
},
methods: {
offerCreated() {
this.offerCount++;
},
offerDestroyed() {
this.offerCount--;
},
addOffer() {
this.offers.push({
name: `Item: ${this.offers.length}`
});
},
removeOffer() {
this.offers.pop();
}
}
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<div id="app">
<div>Offer instances: {{offerCount}}</div>
<div>Offer instances (from store): {{offerCountFromStore}}</div>
<div>
<div v-if="offers.length > 3">
<a href="#">View all offers here</a>
</div>
<div v-else-if="offers.length > 1">
<offer @offer-created="offerCreated" @offer-destroyed="offerDestroyed" v-for="offer in offers" :data="offer"></offer>
</div>
<div v-else-if="offers.length == 1">
<offer @offer-created="offerCreated" @offer-destroyed="offerDestroyed" :data="offers[0]"></offer>
</div>
</div>
<div>
<button @click.prevent="addOffer">Add</button>
<button @click.prevent="removeOffer">Remove</button>
</div>
</div>
&#13;
尝试使用$children
的问题在于,它本身并不是被动的:
当前实例的直接子组件。 注意没有
$children
的订单保证,并且不是被动的。如果你找到了 您自己尝试使用$children
进行数据绑定,请考虑使用 数组和v-for
生成子组件,并使用数组作为 事实的来源。
答案 1 :(得分:1)
没有干净的方式。
您可以计算当前实例的特定类型的子项。但你必须打电话给&#34;重新计算&#34; update
挂钩上的逻辑(以及mounted
)。
示例:
Vue.component('offer', {
name: 'Offer',
template: '<span> offer </span>'
})
new Vue({
el: '#app',
data: {
offers: [1, 2],
offerCount: 0
},
methods: {
updateOfferCount() {
this.offerCount = this.$children.filter(child => child.constructor.options.name === 'Offer').length;
}
},
updated() {
this.updateOfferCount()
},
mounted() {
this.updateOfferCount()
}
})
&#13;
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div>
<template v-if="offers.length > 3">
<a href="#">View all offers here</a>
</template>
<template v-else-if="offers.length > 1">
<offer v-for="offer in offers" :data="offer"></offer>
</template>
<template v-else-if="offers.length == 1">
<offer :data="offers[0]"></offer>
</template>
</div>
<br>
<button @click="offers.push(123)">Add Offer</button> offerCount: {{ offerCount }}
</div>
&#13;