defineModel的行为与文档不一致

先来看看文档对defineModel的描述和使用例

html 复制代码
<script setup>
const model = defineModel()

function update() {
  model.value++
}
</script>

<template>
  <div>Parent bound v-model is: {{ model }}</div>
  <button @click="update">Increment</button>
</template>
html 复制代码
<Child v-model="countModel" />

不过这里的简单例子中 v-model的类型是数字类型 对它的变更自然也只有直接赋值这一种方式

那么 如果v-model是对象呢?

html 复制代码
<script setup lang="ts">
const countObj = defineModel<{ count: number }>()
</script>
<template>
  <div class="m-4">
    {{ countObj.count }}
    <el-button
      @click="
        () => {
          countObj.count++
        }
      "
    >
      +1
    </el-button>
  </div>
</template>
html 复制代码
<script setup lang="ts">
import { ref } from 'vue'
import Child from './Child.vue'

const countObj = ref({
  count: 1,
})
</script>
<template>
  <Child v-model="countObj" />
</template>

可以正常使用 v-model的value也是很正常的ref

然而如果改一下写法

html 复制代码
  <Child
    :model-value="countObj"
    @update:model-value="
      (val) => {
        debugger
        countObj = val
      }
    "
  />

就会发现@update:model-value根本没调用 这一点和文档是不一致的

如果countObj自身还是shallowRef(虽然一般也不会用) 那defineModel就会完全出错

这里的v-model甚至是一个完全没有响应性的变量 对它的变更不会触发渲染 也不会调用update事件

而如果使用之前的写法model-value + @update 就可以正常使用

html 复制代码
<script setup lang="ts">
const props = defineProps<{ modelValue: { count: number } }>()
const emit = defineEmits<{
  'update:modelValue': [val: { count: number }]
}>()
</script>
<template>
  <div class="m-4">
    {{ modelValue.count }}
    <el-button
      @click="
        () => {
          emit('update:modelValue', { count: modelValue.count + 1 })
        }
      "
    >
      +1
    </el-button>
  </div>
</template>

总结:1.defineModel的行为与文档不一致 2.shallowRef+defineModel会导致完全失效

相关推荐
北极星日淘27 分钟前
可买免税店货物与安耐晒——特殊商品代购技术方案
javascript·vue.js·elementui
youyu-youyu1 小时前
oss阿里云图片链接url高清图片设置为缩略图 vue 减少加载体积流量
前端·javascript·vue.js·阿里云·云计算
低保和光头哪个先来1 小时前
聊聊 CSS 编译和 scoped 实现
前端·css·vue.js
_codeOH16 小时前
Vue 3 vs React 19:框架还在卷,核心原理就这些
前端·vue.js
英勇无比的消炎药17 小时前
新手必看玩转TinyRobot一定要避开这些坑
前端·vue.js
英勇无比的消炎药17 小时前
别再盲目混用AI组件库和传统组件库差距原来这么大
前端·vue.js
英勇无比的消炎药19 小时前
前端提效神器全新AI组件库TinyRobot改写日常开发模式
前端·vue.js
英勇无比的消炎药20 小时前
前端提效神器TinyRobot
前端·vue.js
CDwenhuohuo20 小时前
uni 背景色渐变 全屏
前端·javascript·vue.js
爱怪笑的小杰杰20 小时前
Vue 项目交付第三方开发,如何隐藏核心 JS 源码?
前端·javascript·vue.js