在上一篇 vue3.3 文章中,虽然写了 defineModel ,但并未考虑到写的时候3.4版本里 defineModel 才作为稳定的API正式加入( 两年没看vue3 更新的内容了... ),并增加了对支持修饰符相关的内容;
基于此,如果在vue3.3的版本里使用defineModel碰到某些错误的话,也许就会是该版本不支持,vue3.4也算是较为重要的一个小版本吧,建议还是使用3.4而不是3.3
defineModel是配合父子组件使用的,所以下面分为2个代码块作为案例演示用法:
<template>
<div>
<div>父组件</div>
<div>vue3.3新特性: defineModel </div>
<div :id>vue3.4新特性: v-bind同名简写 (ts eslint都会报错,暂时懒得研究是什么依赖版本的问题); defineModel 正式加入</div>
<div>
<child v-model:inputName.animation="data1"></child>
</div>
</div>
</template>
<script setup lang="ts">
import { ref,watch } from "vue";
import child from "./child.vue";
const id = ref('testID')
const data1 = ref(undefined)
// const data1 = ref('')
watch(data1,(val)=>{
console.log(val,'监听是否变化');
})
setTimeout(() => {
data1.value = '肥伦'
console.log('变更数据',data1.value);
}, 1000);
</script>
子组件:
<template>
<div>
<div>子组件</div>
<div><input type="text" v-model="modelValue"></div>
</div>
</template>
<script setup lang="ts">
// defineModel 是 props + emit 的语法糖, defineModel就只建议用运行时声明的写法了!
// defineModel([name], [prop])的参数说明
/**
* name 和 prop 选项都不是必填。
*/
/**
* prop {} 参数详解
* {
* type: String // 表示vmodel绑定的值类型,不符合控制台抛出警告。
* default: '芙莉莲' // 当父组件vmodel传入的是 undefine 将使用该默认值。
* set: function // 修改该 model 时触发
* get: function // 访问该 model 时触发
* }
*/
// const modelValue = defineModel() // 写法1,子组件这里等价于props.modelValue + update:modelValue ;(由父组件通过 v-model 使用)
// const modelValue = defineModel({ type: String,default:'芙莉莲' }) // 写法1的基础上,设置model的功能选项。
// const modelValue = defineModel('inputName') // 写法2,子组件这里等价于props.inputName + update:inputName ;(由父组件通过 v-model:inputName 使用)
// const modelValue = defineModel('inputName', { type: String, default: '芙莉莲' }) // 写法2的基础上,声明 prop 选项
// ↓ 写法3,如果v-model声明了修饰符,则需要通过解构返回值的方式获取;
const [modelValue, modelModifiers] = defineModel('inputName', {
type: String,
default: '芙莉莲',
set(val) {
if (modelModifiers.animation) {
return val.trim()
}
return val
},
// get(val){
// return val
// }
})
console.log(modelValue.value, modelModifiers);
// modelValue 在被修改时,触发 "update:inputName" 事件; 不声明model的name时,则是默认的 update:modelValue
// 总结就是根本不用管他是 update:xxx 什么玩意,这部分不重要,因为defineModel写法下,你不需要自己去调用了!
setTimeout(() => {
// emit('update:inputName','测试有用吗')
// 如果你非要自己手动调用,也是可以的!但会报TS错,因为emit没有声明该类型,解决方法就是你去声明一下就好了。
// 但是最终还不如 modelValue.value = xx 的方式去修改更好!
modelValue.value = '测试更改有效的!'
}, 5000);
</script>