【发布时间】:2021-08-14 14:59:10
【问题描述】:
下面给出的代码您可以看到v-model 的魔力,选中/取消选中复选框后,数组checkedNames 将自动添加/删除名称。我们不需要写任何东西来从数组中推送/切片/过滤名称,对吧?
const { ref } = Vue;
const App = {
setup () {
const checkedNames = ref([])
return { checkedNames }
}
}
Vue.createApp(App).mount("#app");
<script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script>
<div id="app">
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
我的问题是:如何使用自定义组件实现相同的功能?
您可以看到,在下面给出的代码 sn-ps 中,我尝试了但我不喜欢它,因为我们缺少 v-model 的魔力,而是在我的函数 addOrRemoveItem() 中处理它
提醒:在您看来,我解释得太多了 :) 抱歉。
我遵循this 教程获得了一些想法,但没有太大帮助,然后参考了 vue 官方文档here。下面是功能代码,但有点矫枉过正。
const { ref, createApp } = Vue;
const app = createApp({
setup() {
const itemsSelected = ref([]);
const items = ref([
{ id: '1', name: 'Jack' },
{ id: '2', name: 'John' },
{ id: '3', name: 'Mike' },
]);
const addOrRemoveItem = (itemId) => {
const exists = itemsSelected.value.includes(itemId);
if (exists) {
itemsSelected.value = itemsSelected.value.filter((id) => id !== itemId);
} else {
itemsSelected.value.push(itemId);
}
};
return {
items,
itemsSelected,
addOrRemoveItem,
};
},
});
app.component('custom-checkbox', {
props: {
item: { type: Object, default: () => ({}) },
modelValue: { type: Array, default: () => [] },
},
template: `
<div>
<input
type="checkbox" :value="item.id"
@change="$emit('update:model-value', $event.target.checked)"
> {{ item.name }}
</div>
`
})
app.mount("#app");
<script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script>
<div id="app">
<div><code>itemsSelected: {{ itemsSelected }}</code></div>
<hr />
<custom-checkbox
v-for="item in items"
:key="item.id"
:item="item"
:model-value="itemsSelected"
@update:model-value="addOrRemoveItem(item.id)"
></custom-checkbox>
</div>
如上所述,当我按照doc $emit('update:model-value', ...) 中提到的那样进行操作时,代码有点过头了$emit 的长度。
const { ref, createApp } = Vue;
const app = createApp({
setup() {
const itemsSelected = ref([]);
const items = ref([
{ id: '1', name: 'Jack' },
{ id: '2', name: 'John' },
{ id: '3', name: 'Mike' },
]);
const addOrRemoveItem = (itemId) => {
const exists = itemsSelected.value.includes(itemId);
if (exists) {
itemsSelected.value = itemsSelected.value.filter((id) => id !== itemId);
} else {
itemsSelected.value.push(itemId);
}
};
return {
items,
itemsSelected,
addOrRemoveItem,
};
},
});
app.component('custom-checkbox', {
props: {
item: { type: Object, default: () => ({}) },
},
template: `
<div>
<input
type="checkbox" :value="item.id"
@change="$emit('val-updated')"
> {{ item.name }}
</div>
`
})
app.mount("#app");
<script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script>
<div id="app">
<div><code>itemsSelected: {{ itemsSelected }}</code></div>
<hr />
<custom-checkbox
v-for="item in items"
:key="item.id"
:item="item"
@val-updated="addOrRemoveItem(item.id)"
></custom-checkbox>
</div>
【问题讨论】:
-
我推荐阅读本教程。使用 v-model 的想法很棒。结果也很棒。 vuejs.org/v2/guide/components.html#Using-v-model-on-Components 代码也会减少(我们不需要函数来处理子组件中的值)
-
@leonheess 不,这对我没有帮助,因为它在做同样的事情。您建议的链接有一个我的问题开始的答案:)
-
@Syed 如果对你没有帮助,你为什么投票结束这个问题作为你/这个的副本?
-
@MichalLevý 但是第二个和第三个不会 ping 任何人,因为他们没有制作任何 cmets。
-
@MichalLevý 我收到了这个问题的警告,因为提问者试图关闭另一个问题作为这个问题的副本。如果他自己决定这两个问题是相互重复的——我该反对谁?我只是翻转了副本,因为另一个问题更受欢迎而且更老。如果您能向我解释 Vue 2 与 Vue 3 之外的任何区别,我将很乐意投票重新开放自己。如果不是,我建议您将答案移至另一个问题。
标签: javascript vue.js vue-component vuejs3 vue-composition-api