You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:02:55