Vue SFC Playground个
对于<input type="checkbox">
,您必须使用value
属性:
应用视图
<script setup>
import { ref } from 'vue'
import Checkbox from './Checkbox.vue';
const arr = ref([]);
</script>
<template>
<checkbox v-model="arr" name="first" />
<checkbox v-model="arr" name="second" />
<checkbox v-model="arr" name="third" />
<div> {{ arr }} </div>
</template>
Checkbox.vue
<script setup>
import { computed } from "vue";
const props = defineProps({name: String, modelValue: [Array, Boolean]});
const emit = defineEmits(['update:modelValue']);
const value = computed({
get(){
return props.modelValue?.includes?.(props.name) ?? props.modelValue;
}, set(val){
emit('update:modelValue', Array.isArray(props.modelValue) ?
props.modelValue.includes(props.name) ? props.modelValue.filter(item => item !== props.name) : [...props.modelValue, props.name]
: val);
}});
</script>
<template>
<label>
<button type="button" @click.prevent="value = !value">
<span v-if="value">✔️</span>
<span v-else> </span>
</button>
</label>
</template>
你可以保持Checkbox.vue
就像处理一个布尔值一样简单.为此,您使用computed
从绑定到复选框的对象属性中获取相同的数组:
Vue SFC Playground个
应用视图
<script setup>
import { ref } from 'vue'
import Checkbox from './Checkbox.vue';
const arr = ref([]);
</script>
<template>
<checkbox v-model="arr" value="first" />
<checkbox v-model="arr" value="second" />
<checkbox v-model="arr" value="third" />
<div> {{ arr }} </div>
</template>
Checkbox.vue
可以保持不变(同时处理数组和布尔值),但在下面的场景中可以简化:
<script setup>
import { computed } from "vue";
const props = defineProps({value: String, modelValue: [Array, Boolean]});
const emit = defineEmits(['update:modelValue']);
const value = computed({
get(){
return props.modelValue?.includes?.(props.value) ?? props.modelValue;
}, set(val){
emit('update:modelValue', Array.isArray(props.modelValue) ?
props.modelValue.includes(props.value) ? props.modelValue.filter(item => item !== props.value) : [...props.modelValue, props.value]
: val);
}});
</script>
<template>
<label>
<button type="button" @click.prevent="value = !value">
<span v-if="value">✔️</span>
<span v-else> </span>
</button>
</label>
</template>