【问题标题】:Missing required prop: "value" on model/value binding for custom input component in Vue缺少必需的道具:Vue 中自定义输入组件的模型/值绑定上的“值”
【发布时间】:2021-12-03 21:39:39
【问题描述】:

我在尝试在 Vue 3 中制作自定义表单组件时关注了this guide(组合 API,script setup 模式)。

当我加载包含我的组件的页面时,我收到如下控制台警告:

[Vue 警告]:缺少必需的道具:“值” 在

我的组件(CSS 省略):

<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>

包含它的页面像这样使用它:

<!-- v-for question in questions -->
<switch-control :name="`question-${question.id}`"
             :model="feedbackData[`question-${question.id}`]"
             :id="`question-${question.id}`" />

我尝试了各种方法,例如将发出的事件的名称更改为 input 或使用 v-model 而不是 :model 但我还没有设法解决这个问题,我不知道还有什么试试看。

编辑: 因此编辑组件以使用modelValue

<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>

家长:

<!-- v-for question in questions -->
<switch-control :name="`question-${question.id}`"
             v-model="feedbackData[`question-${question.id}`]"
             :id="`question-${question.id}`" />

导致彻底错误:

[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: 我设法放大了问题所在,但我仍然无法完全弄清楚发生了什么。

我更改了组件,使 @input 现在是 @input="emit('update:modelValue', !modelValue)"。我将包含包含它的页面的&lt;script&gt; 的相关部分:

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)

现在的症状:

  • 当代码如上所示,prop 和 emit 定义为 boolean | undefined 时,我收到以下错误并且整个 for 循环未呈现:
[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
  • 如果我将 prop 注释并作为 boolean 发出,则元素会加载,我只会收到警告(见下文)。如果我然后尝试通过单击元素来更改值,我会不断收到相同的警告,并且值根本不会改变,而不是像预期的那样交替 true 和 false。如果我检查 HTML 中的 value 属性,它的行为确实正确(最初是“”,然后在“真”和“假”之间交替)。
[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"  ... >

【问题讨论】:

  • 我无法重现此demo 中的问题。另请注意,道具是只读的,因此您的 @input 处理程序不应尝试切换 modelValue
  • @tony19 请参阅问题的 EDIT2,也许它会暗示我没有考虑的事情。感谢您抽出宝贵的时间。
  • 我无法在此demo 中重现 EDIT2 问题。你能分享一个复制的链接吗?
  • 我创建了这个demo,尽可能地复制了我的实际应用程序的结构,但即使我的应用程序出错,它仍然不会出错。您对可能导致问题的事情有任何建议吗?我已经没有东西可以尝试了。常量是错误Uncaught (in promise) TypeError: invalid 'instanceof' operand type,但我没有调用任何承诺,堆栈跟踪没有指向我自己代码中的任何地方,只有 esm-bundler。
  • 只有当我将modelValue 类型更改为删除undefined 时,该错误才会消失,但随后我会收到警告,因为该道具收到未定义而不是布尔值。然后我必须硬编码要给出的初始模型值,如果我尝试从道具动态派生它们,如下所示:feedbackData.value = Object.fromEntries(props.questions.map((q) =&gt; [question-${q.id}, false])) 我再次收到警告:生成的对象记录为完全是空的,props.questions 本身也是如此。如果我记录传递给:questions 的对象,它确实包含预期的问题数组...

标签: vue.js data-binding custom-controls vuejs3 vue-composition-api


【解决方案1】:

在子组件中,您应该将value 定义为modelValue

 <input ref="switchElement"
         ...
         :value="modelValue" />
</template>

.....
const props = defineProps<{
  modelValue : boolean | undefined,
}>()

在父母中使用 v-model 而不是 :model

  v-model="feedbackData[`question-${question.id}`]"

【讨论】:

  • 这听起来像是在正确的轨道上,但是进行这些编辑会导致错误,以至于组件及其父级现在根本无法加载。请检查原始问题的编辑。
猜你喜欢
  • 2021-02-09
  • 2019-11-11
  • 2019-04-23
  • 2021-10-22
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 2021-03-19
  • 2018-10-21
相关资源
最近更新 更多