在上一篇 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>