Reputation: 2645
I followed this guide while trying to make a custom form component in Vue 3 (composition api, script setup
mode).
When I load the page containing my component, I get a console warning like this one:
[Vue warn]: Missing required prop: "value" at <SwitchControl key=0 name="question-8" model=undefined ... >
My component (CSS omitted):
<template>
<input ref="switchElement"
v-bind="$attrs"
class="gui-switch"
@input="value = !value; emit('update:modelValue', value)"
type="checkbox"
role="switch"
:value="value" />
</template>
<script setup lang="ts">
import { defineEmit, defineProps, onMounted, ref } from "vue"
const props = defineProps<{
value: boolean | undefined,
}>()
const emit = defineEmit<{
(e: "update:modelValue", value: boolean | undefined): void,
}>()
const switchElement = ref<HTMLInputElement>()
onMounted(() => switchElement.value!.indeterminate = true)
</script>
The page that contains it uses it like so:
<!-- v-for question in questions -->
<switch-control :name="`question-${question.id}`"
:model="feedbackData[`question-${question.id}`]"
:id="`question-${question.id}`" />
I've tried various things such as changing the name of the emitted event to input
or using v-model
instead of :model
but I haven't managed to fix this yet and I don't know what else to try.
EDIT:
Editing the component to use modelValue
thusly:
<template>
<input ref="switchElement"
v-bind="$attrs"
class="gui-switch"
@input="modelValue = !modelValue; emit('update:modelValue', modelValue)"
type="checkbox"
role="switch"
:value="modelValue" />
</template>
<script setup lang="ts">
import { defineEmit, defineProps, onMounted, ref } from "vue"
const props = defineProps<{
modelValue: boolean | undefined,
}>()
const emit = defineEmit<{
(e: "update:modelValue", value: boolean | undefined): void,
}>()
const switchElement = ref<HTMLInputElement>()
onMounted(() => switchElement.value!.indeterminate = true)
</script>
Parent:
<!-- v-for question in questions -->
<switch-control :name="`question-${question.id}`"
v-model="feedbackData[`question-${question.id}`]"
:id="`question-${question.id}`" />
Leads to an outright error:
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next
at <SwitchControl key=0 name="question-8" modelValue=undefined ... >
Uncaught (in promise) TypeError: invalid 'instanceof' operand type
assertType runtime-core.esm-bundler.js:1877
validateProp runtime-core.esm-bundler.js:1841
validateProps runtime-core.esm-bundler.js:1817
initProps runtime-core.esm-bundler.js:1548
setupComponent runtime-core.esm-bundler.js:6500
mountComponent runtime-core.esm-bundler.js:4206
processComponent runtime-core.esm-bundler.js:4182
patch runtime-core.esm-bundler.js:3791
mountChildren runtime-core.esm-bundler.js:3975
EDIT2: I managed to zoom in on whereabouts the problem is, but I still can't quite figure out what's happening.
I changed the component so that @input
is now @input="emit('update:modelValue', !modelValue)"
. I'll include the relevant parts of the <script>
of the page that includes it:
import SwitchControl from "@/components/SwitchControl.vue"
import type { FeedbackQuestion } from "@/utils/api/story"
import { defineProps, ref } from "vue"
const props = defineProps<{
questions: {id: number}[],
}>()
const defaultModelValues = {
// These are hard-coded for debugging, ideally I'd want it to work with an empty initial object
"question-8": null,
"question-11": null,
}
const feedbackData = ref<Record<string, any>>(defaultModelValues)
Now the symptoms:
boolean | undefined
, I get the following error and the whole for loop is not rendered:[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next
at <SwitchControl modelValue=null onUpdate:modelValue=fn<onUpdateModelValue> name="question-8" ... >
Uncaught (in promise) TypeError: invalid 'instanceof' operand type
boolean
, the elements load, and I only get a warning (see below). If I then try to change the value by clicking on the element, I keep getting the same warning and the value doesn't change at all, instead of alternating true and false as would be expected. The value
attribute in the HTML if I inspect it, does behave correctly (is "" initially, then alternates between "true" and "false").[Vue warn]: Invalid prop: type check failed for prop "modelValue". Expected Boolean, got Null
at <SwitchControl modelValue=null onUpdate:modelValue=fn<onUpdateModelValue> name="question-8" ... >
Upvotes: 3
Views: 14365
Reputation: 567
use ref from vue can fix warning message
import { defineStore } from "pinia";
import { ref } from "vue";
export const usePosts = defineStore("posts", {
state: () => {
return {
data: [],
errors: [],
title: "",
content: "",
image: ref(),
};
},
});
vue file
<q-file color="primary" v-model="postsStore.image" label="Image">
<template v-slot:prepend>
<q-icon name="cloud_upload" />
</template>
</q-file>
Upvotes: 0
Reputation: 1
In the child component you should define value
as modelValue
:
<input ref="switchElement"
...
:value="modelValue" />
</template>
.....
const props = defineProps<{
modelValue : boolean | undefined,
}>()
and in parent use v-model
instead of :model
:
v-model="feedbackData[`question-${question.id}`]"
Upvotes: 3