vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue3 v-model语法变化导致出现警告

Vue 2迁移到Vue3时v-model语法不兼容出现警告问题的解决方案

作者:蜡台

你的Vue3项目中使用v-model时是否遇到过Extraneous non-props attributes警告,本文深入分析该警告产生的两大原因:v-model默认属性变为modelValue以及多根节点无法自动继承属性,并提供两种解决方案,推荐将组件改造为Vue3标准写法,彻底消除警告,让你的代码更干净

[Vue warn]: Extraneous non-props attributes (modelValue) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. 

这个警告的原因是 Vue 3 中 v-model 的语法变化组件存在多根节点(Fragment) 共同导致的。

错误原因分析:

  1. v-model 默认属性名改变:在 Vue 3 中,组件上的 v-model 默认绑定的 prop 是 modelValue,触发的事件是 update:modelValue。而你的 u-dialog 组件中定义的 prop 是 value,且触发的是 input 事件(这是 Vue 2 的语法)。
  2. 产生非 prop 特性:因为父组件使用了 v-model,实际上向子组件传递了 modelValue。但子组件的 props 中并没有 modelValue,所以 Vue 把它当成了“非 prop 的特性 (non-props attribute)”。
  3. 多根节点无法继承:你的 <template> 中有 <page-meta><view> 两个根节点(构成了 Fragment)。Vue 无法将未声明的非 prop 特性自动挂载到多个根节点上,因此抛出了这个警告。

方案一 : 将组件改造为符合 Vue 3 标准的v-model(推荐)

将组件的 value 改为 modelValue,并将触发的事件从 input 改为 update:modelValue

1. 修改 u-dialog 组件的 <template>

<template>
	<!-- 将 value 改为 modelValue -->
	<page-meta :page-style="modelValue ? 'overflow:hidden;height:100vh;position:fixed;' : ''" />
	<view v-if="modelValue">
		<!-- 下面的代码保持不变 -->
		<view class="dialog-model" @click="handleMaskClose" @touchmove.stop.prevent="()=>{}" @wheel.stop.prevent="()=>{}">
            <!-- ... -->

修改 u-dialog 组件的 <script>

	export default {
		name: "u-dailog",
		// 建议加上 inheritAttrs: false,防止以后传入 class/style 时因多根节点再次报错
		inheritAttrs: false, 
		props: {
			// 将 value 改为 modelValue
			modelValue: {
				type: Boolean,
				default: false
			},
			// ... 其他 props 保持不变
		},
		// 声明 emits (Vue 3 推荐做法)
		emits: ['update:modelValue', 'cancel', 'confirm'],
		data() {
			return {}
		},
		// ... computed 保持不变
		methods: {
			onCancel() {
				// 将 "input" 改为 "update:modelValue"
				this.$emit("update:modelValue", false)
				this.$emit('cancel')
			},
			onConfirm() {
				// 将 "input" 改为 "update:modelValue"
				this.$emit("update:modelValue", false)
				this.$emit('confirm')
			},
			handleMaskClose(){
				this.maskClose && this.onCancel()
			}
		}
	}

修改后,父组件的 <u-dialog v-model="showDialog"></u-dialog> 无需任何改动即可完美运行。

方案二:保留组件的value属性,修改父组件的用法

如果你不想修改 u-dialog 内部的 prop 名称,可以利用 Vue 3 支持的 v-model 自定义参数 特性。

1. 修改父组件的调用方式:v-model 加上参数 :value,明确告诉 Vue 绑定 value 属性。

<!-- 将 v-model 改为 v-model:value -->
<u-dialog v-model:value="showDialog"></u-dialog>

2. 修改 u-dialog 组件的 <script> 触发事件: 虽然属性名保持了 value,但 Vue 3 的事件触发机制变了,需要将 input 改为 update:value

		methods: {
			onCancel() {
				// 将 "input" 改为 "update:value"
				this.$emit("update:value", false)
				this.$emit('cancel')
			},
			onConfirm() {
				// 将 "input" 改为 "update:value"
				this.$emit("update:value", false)
				this.$emit('confirm')
			},
			handleMaskClose(){
				this.maskClose && this.onCancel()
			}
		}

你遇到的问题是典型的 Vue 2 迁移到 Vue 3 时的 v-model 语法不兼容 问题。建议直接采用 方案一,将组件彻底升级为 Vue 3 的标准写法,同时加上 inheritAttrs: false 来规避多根节点(Fragment)带来的潜在特性继承警告。

以上就是Vue 2迁移到Vue3时v-model语法不兼容出现警告问题的解决方案的详细内容,更多关于Vue3 v-model语法变化导致出现警告的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文