Vue3组件update:modelValue在Dev正常Build预览报错求助
问题描述
使用Vue 3 ^3.2.41与Vite ^4.2.1开发项目,自定义Input.vue组件供父组件调用。开发环境执行npm run dev时功能正常,但执行npm run build后用npm run serve预览时,出现Uncaught ReferenceError: modelValue is not defined错误。
Input.vue组件代码
<template> <div class="mb-6"> <label class="block uppercase tracking-wide text-grey-darker text-xs font-bold mb-2" :for="id"> {{ label }} <span class="text-red-600" v-if="isRequired">*</span> </label> <input :id="id" v-model="modelValue" @input="emit('update:modelValue', modelValue)" :class="inputClasses" :type="type" :placeholder="placeholder"> <ValidationMessage :validation="validation" :field="id" /> </div> </template> <script setup> import ValidationMessage from '@/components/ValidationMessage.vue' defineProps({ isRequired: { type: Boolean, default: false }, label: { type: String, required: true }, id: { type: String, required: true }, modelValue: { type: String, required: true, }, type: { type: String, required: true, }, placeholder: { type: String, default: '', }, validation: { type: Object, default: null, }, inputClasses: { type: String, default: 'appearance-none block w-full bg-grey-lighter text-grey-darker border border-red rounded py-3 px-4 mb-3', }, }) const emit = defineEmits(['update:modelValue']) </script>
父组件Create.vue使用代码
<template> <loading v-if="course.loading" /> <div class="pt-15"> <div class="grid gap-6 mb-8"> <div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800"> <h4 class="mb-4 font-semibold text-gray-600 dark:text-gray-300"> Add data </h4> <form @submit.prevent="store"> <Input isRequired label="Judul" id="title" v-model="course.fields.title" type="text" placeholder="Masukkan judul" :validation="validation" /> <BtnSubmit title="Simpan" /> <BtnCancel router-name="admin.courses.index" /> </form> </div> </div> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { useRouter } from 'vue-router' import Loading from '@/components/Loading.vue' import Input from '@/components/Form/Input.vue' import BtnSubmit from '@/components/Button/BtnSubmit.vue' import BtnCancel from '@/components/Button/BtnCancel.vue' import { useStore } from '@/stores' const { course } = useStore() const router = useRouter() let validation = ref([]) onMounted(async () => { course.resetFields() }) const store = async () => { try { await course.createCourse(router) } catch (error) { validation.value = error } } </script>
报错信息
Input-00fb8882.js:1 Uncaught ReferenceError: modelValue is not defined at i.onUpdate:modelValue.t.<computed>.t.<computed> [as _assign] (Input-00fb8882.js:1:969) at HTMLInputElement.<anonymous> (index-83e87120.js:1:63876)
package.json脚本配置
{ "name": "learn-vue", "version": "0.1.0", "private": true, "scripts": { "dev": "vite", "serve": "vite preview", "build-dev": "vite build --mode development", "build": "vite build", "lint": "vite lint" }, ---other depedencies--- }
解决方案
问题根源是直接对props中的modelValue使用v-model。Vue的props是单向数据流,不可直接修改,开发环境仅会给出警告,但生产环境打包时的严格优化会导致变量引用异常,抛出未定义错误。同时你手动绑定的@input事件属于冗余操作,v-model已自动处理update:modelValue的触发。
方案1:手动绑定value与input事件(最简方式)
无需本地变量,直接通过$event.target.value获取输入值并触发更新:
<template> <div class="mb-6"> <label class="block uppercase tracking-wide text-grey-darker text-xs font-bold mb-2" :for="id"> {{ label }} <span class="text-red-600" v-if="isRequired">*</span> </label> <!-- 替换v-model为手动绑定value和input事件 --> <input :id="id" :value="modelValue" @input="emit('update:modelValue', $event.target.value)" :class="inputClasses" :type="type" :placeholder="placeholder"> <ValidationMessage :validation="validation" :field="id" /> </div> </template> <script setup> // 其余代码保持不变 import ValidationMessage from '@/components/ValidationMessage.vue' defineProps({/* ...props定义不变... */}) const emit = defineEmits(['update:modelValue']) </script>
方案2:使用本地ref中转(适合复杂场景)
通过本地变量接收props值,监听双向变化同步数据:
<template> <div class="mb-6"> <label class="block uppercase tracking-wide text-grey-darker text-xs font-bold mb-2" :for="id"> {{ label }} <span class="text-red-600" v-if="isRequired">*</span> </label> <!-- 对本地变量使用v-model --> <input :id="id" v-model="localValue" :class="inputClasses" :type="type" :placeholder="placeholder"> <ValidationMessage :validation="validation" :field="id" /> </div> </template> <script setup> import { ref, watch } from 'vue' import ValidationMessage from '@/components/ValidationMessage.vue' const props = defineProps({/* ...props定义不变... */}) const emit = defineEmits(['update:modelValue']) // 定义本地变量接收初始值 const localValue = ref(props.modelValue) // 监听本地变量变化,触发父组件更新 watch(localValue, (newVal) => { emit('update:modelValue', newVal) }) // 监听父组件传来的modelValue变化,同步到本地变量 watch(() => props.modelValue, (newVal) => { localValue.value = newVal }) </script>
内容的提问来源于stack exchange,提问作者ASHafizullah
相关产品推荐
相关产品推荐

