vue 3 组合 api 组件,带有复选框数组并切换所有
P粉670838735
P粉670838735 2023-08-30 20:55:11
[Vue.js讨论组]

我们决定逐渐从淘汰赛转向使用 typescript 的 vue 3 组合 api,并且我正在尝试了解变异道具的反模式。我有一个正在执行其预期工作的工作组件,但基本上我想确认它的编写方式是建议的方法。

一个相当简单的例子是一个复选框列表组件,上面有一个切换开关:

我最大的问题是我在 AppList.vue 中所做的是否正确,我正在做 const internalModel = toRef(props.selected ?? []); 以获得不可变的组件中的变量和 selectedHandler - 事件和 toggleAll - 计算为发出 OUT,但在这里我手动保留 selected 和 <代码>内部模型同步。对于同一件事使用两个变量感觉很麻烦,但同时它确实有意义,因为内部模型不需要干扰视图。

我知道 vuejs.org 上有一个示例,其中可以在 v-model 上使用数组来表示多个复选框,但它不在组件内部或作为道具,因此它不完全是同样,这感觉更复杂。我花了一天中的大部分时间试图让它正确,但没有那么多 vue 3 搜索结果,对于这个特定问题我根本没有找到任何结果。

HomeView.vue:

<script set lang="ts">
import { ref } from 'vue';
import AppList, { type Item } from '@/components/AppList.vue';

const fooItems = ref<Item[]>([
    { id: 1, name: 'foo 1' },
    { id: 2, name: 'foo 2' },
    { id: 3, name: 'foo 3' },
    { id: 4, name: 'foo 4' },
    { id: 5, name: 'foo 5' },
]);
const fooSelected = ref<number[]>([]);
</script>

<template>
  <AppList :items="fooItems" v-model:selected="fooSelected"></AppList>
  <div>fooselected: {{ fooSelected }}</div>
</template>

组件/Applist.vue:

<script setup lang="ts">
import { computed, toRef } from 'vue';

export interface Item {
    id: number;
    name: string;
}

const props = defineProps<{
    items: Item[];
    selected?: number[];
}>();

const internalModel = toRef(props.selected ?? []);

const emit = defineEmits<{
    'update:selected': [selected: number[]];
}>();

const selectedHandler = (e: Event) => {
    const target = <HTMLInputElement>e.target;
    if (props.selected && target) {
        if (target.checked) {
            emit('update:selected', [...props.selected, Number(target.value)]);
        } else {
            emit(
                'update:selected',
                props.selected.filter((i: number) => i !== Number(target.value))
            );
        }
    }
};

const toggleAll = computed({
    get: () => internalModel.value.length === props.items.length && internalModel.value.every((s) => props.items.map((item) => item.id).includes(s)),
    set: (value) => {
        if (value) {
            emit(
                'update:selected',
                props.items.map((i) => i.id)
            );
            internalModel.value = props.items.map((i) => i.id);
        } else {
            emit('update:selected', []);
            internalModel.value = [];
        }
    },
});
</script>

<template>
    <label>
        <input type="checkbox" v-model="toggleAll" />
        toggle all
    </label>
    <ul>
        <li v-for="item in items" :key="item.id">
            <label>
                <input type="checkbox" :value="item.id" v-model="internalModel" @change="selectedHandler" />
                <span>id {{ item.name }}</span>
            </label>
        </li>
    </ul>
    internalModel: {{ internalModel }}
</template>

P粉670838735
P粉670838735

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号