Hello,
I am still in the process of refactoring everything to use Composition API, I'm getting there. I am trying to refactor a category checkbox which is responsible for filtering stuff. The problem is that it doesn't not work with an array prop. I found this post on SO, and while it's exactly what I am looking for, none of the examples provided (not tried #3 though surely it should work without having to use a custom handler) work.
https://stackoverflow.com/questions/70101927/why-is-vue-v-model-not-working-for-an-array-prop
const selectedCategories = ref([]);
<Category v-model="selectedCategories" :category="category" />
Category.vue:
script setup
defineProps({
modelValue: Array,
category: Object,
});
let emit = defineEmits([
"update:modelValue",
]);
const updateSelectedCategories = (e) => {
emit("update:modelValue", e.target.value.slug); // it doesn't matter what type of value I give, I even tried wrapping it inside an array []
};
<input :id="category.id" :name="category.id" :value="category.slug" class="h-4 w-4 border-black rounded text-black focus:ring-black" type="checkbox" v-on:change="updateSelectedCategories">
Just tried #3 from the SO post, still no dice. I'm clearly doing something wrong, I just don't see it.
I can get it working by doing this, but I don't know, it just doesn't feel "right"?
const updateSelectedCategories = (e) => {
emit("update:modelValue", [...props.modelValue, e.target.value]);
};
I guess this is solved, though it would be good to understand why I need to do this, since I didn't have to do this when using the Options API. @alex 👀
Solved, solution at bottom of thread!
OK, this isn't actually solved. Let's try again. Note: I also posted this in the Vue Discord in hopes it can get some attention.
Hey, I am in the process of moving over to the Composition API (getting there), though I have become slgihtly stuck. I have a simple Category component, the component emits data to the parent, the problem is I'm facing weird behaviour that I've not seen seen before (might be related to Composition API?). Hopefully someone can help get me unstuck!
(simplified, no classes, no non-related code)
<script setup>
defineProps({
modelValue: Array,
category: Object,
});
let emit = defineEmits([
"update:modelValue",
]);
</script>
<template>
<div>
<p v-text="modelValue"></p>
<label :for="category.id" class="text-sm text-black">
<input :id="category.id" :name="category.id" :value="category.id" type="checkbox" v-on:change="emit('update:modelValue', $event.target.value)">
<span class="ml-3">{{ category.name }}</span>
</label>
<div v-for="child in category.children" class="ml-4">
<Category :category="child" />
</div>
</div>
</template>
The problem with this is that modelValue doesn't respect that it's an array, checking a checkbox overrides the previous value
Some hacky attempt to resolve it:
v-on:change="emit('update:modelValue', [...modelValue, $event.target.value])"
This works to some extent, but doesn't respect unchecking, I don't want to continue down this rabbit hole where I'm having to continually hack at it by first checking if it exists or not - That's just not right, I need to understand what's exactly going on and how I can implement a fix.
Here's the related snippet for the parent component...
<div v-for="category in categories" :key="category.id">
<Category v-model="selectedCategories" :category="category" />
</div>
Any help is highly appreciated!
https://i.imgur.com/E3p1XWl.png
https://i.imgur.com/j1tGbPD.png
Solution:
Huge thanks to skirtle who helped me sort it on the Vue Discord.
https://i.imgur.com/dOaComa.png
In case anyone was wondering how the code looks:
const selectedCategories = computed({
get() {
return props.modelValue;
},
set(newSelectedCategories) {
emit("update:modelValue", newSelectedCategories);
},
});
v-model="selectedCategories"