vue3 组件响应式v-model 失效,实践踩坑,一文搞懂组件响应式原理,对初学者友好

Posted Min.Mr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3 组件响应式v-model 失效,实践踩坑,一文搞懂组件响应式原理,对初学者友好相关的知识,希望对你有一定的参考价值。

文章目录

前情提要

vue3的v-model已经有了变化,假如你还不知道其中细节,看完这篇文章你就完全明白了,我以踩坑的场景来进行解析。起因是在我的项目中需要一个输入框组件,这个组件用来根据输入异步查询系统内已有人员,而且在多个地方需要用到这个输入框,所以必须要封装成组件,但是我还是本着学习的态度认真的读完了官方文档相关的内容,结果问题还是出现了;


实战解析

首先我读了有关的内容比如这段官方文档

有了官方文档的基础知识,我大概的了解了如果你想封装一个响应式组件,那么基础是你需要这样写:

<!-- CustomInput.vue -->
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

这是个最基本的例子,我看完后感觉很简单,于是有了以下写法:

//father
<InputUser :modelValue="fatherValue"></InputUser>
//childe
<el-select v-model="modelValue">
        <el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.value" />
</el-select>

<script setup>
defineProps(
    modelValue: String,
)
</script>

这里我就简单列下dom可以说明问题就行,以上写法会导致双向绑定失败;因为vue3的组件v-model是有说法的,只有俩种写法是正确的,父组件处:

  1. v-model=“item.value”
  2. v-model:modelValue = “item.value” //注意之间使用:modelValue不可以

🤔为什么?

1、默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。所以我们的响应式生效了,也就是说你的props属性如果有一个叫modelValue,vue3的v-model会默认与它匹配

2、我们可以通过给 v-model 指定一个参数来更改这些名字,例如: v-model:title,就会匹配props中的title,这里也就是为什么我们可以v-model:modelValue这样写;

3、为什么:modelValue = "item.value" 不可以,因为v-model是vue语法糖,背后原理是利用emit(‘update:modelValue’)来修改,所以可以,而:简写不具备组件通信中的语法糖功能;所以在vue3中,为了更好的对组件进行双向响应式,就只能用v-model这种写法。


最后

📚 vue3专栏
☃️ 个人简介:一个喜爱技术的人。
🌞 励志格言: 脚踏实地,虚心学习。
❗如果文章还可以,记得用你可爱的小手点赞👍关注✅,我会在第一时间回、回访,欢迎进一步交流。

vue2 v-model—绑定事件—深度响应式

参考技术A     在表单标签中,v-model双向绑定的用法有所区别。

首先在data中定义好数据:

    在默认情况下,v-model在每次input 事件触发后将输入框的值与数据进行同步(除了上述输入法组合文字时)。可以添加lazy 修饰符,从而转为在change事件之后进行同步:

    如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

    如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

     v-on:指令用来绑定事件,简写为 @ 可以指定一个事件方法,事件方法要在methods里面定义。

指定事件方法时,如果没有给方法传递参数,默认会传递一个事件对象参数

如果我们传递了一个参数,还想再传递事件对象参数,就要通过$event关键字设置:

如果事件处理的逻辑比较简单,可以直接在行内编写:

    在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

可以直接将  KeyboardEvent.key  暴露的任意有效按键名转换为 kebab-case 来作为修饰符:

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。

对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。例如:

您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:

用delete方法,删除指定对象的属性或数组的成员

您还可以使用 vm.$delete实例方法,这也是全局 Vue.delete方法的别名:

// 针对数组,只能通过以下方法,才能实现响应式:push() pop() unshift() shift() splice() reverse() sort()

如果不使用以上方法,那么也可以使用set和delete方法

以上是关于vue3 组件响应式v-model 失效,实践踩坑,一文搞懂组件响应式原理,对初学者友好的主要内容,如果未能解决你的问题,请参考以下文章

简单对比vue2.x与vue3.x响应式及新功能

Vue3 在子组件中使用 v-model

Vue3中 v-model 语法糖详解

Vue3中 v-model 语法糖详解

Vue3.0更优雅的使用v-model

vue3 watch 监听响应式数据变化