Vue3.4 中 v-model 双向数据绑定新玩法详解

随着 Vue3.4 版本的发布,defineModel 也正式转正了。它可以简化父子组件之间的双向绑定,是目前官方推荐的双向绑定实现方式。

之前在 Vue3.3 中,该方法还是实验性方法,使用 defineModel 需在 vite.config.ts 里面配置 defineModeltrue,配置如下:

javascript 复制代码
export default defineConfig({
  plugins: [
    vue({
      script: {
        defineModel: true,
      },
    }),
  ],
});

Vue3.4 版本中已经是稳定特性了!!!

正式介绍 defineModel

defineModel 是一个新的 <script setup> 宏,旨在简化支持 v-model 的组件的实现, 这个宏用来声明一个双向绑定 prop,通过父组件的 v-model 来使用。

它之前作为实验性功能在 Vue3.3 中发布,并在 Vue3.4 中升级为稳定状态。现在,它还为 v-model修饰符的使用提供了更好的支持。

defineModel 使用

例举一个最简单的使用场景: 自定义组件中使用 v-model 来进行数据的双向绑定。

javascript 复制代码
<!-- 父组件 -->
<template>
  <div>
    <!-- 自定义子组件 CustomComponent 使用 v-model 指令绑定 userName -->
    <CustomComponent v-model="userName" />
  </div>
</template>

<script setup>
import { ref } from "vue";
import CustomComponent from "./CustomComponent.vue";

const userName = ref("前端开发爱好者");
</script>

在 Vue3.3 版本之前,我们通常通过 props 接收 modelValue,然后在更新时,我们会将更新后的值传递给 emitupdate:modelValue 并执行:

javascript 复制代码
<!-- 子组件 CustomComponent  -->
<template>
  <input
    :value="props.modelValue"
    @input="emit('update:modelValue', $event.target.value)"
  />
</template>

<script setup>
import { defineProps, defineEmits } from "vue";

const props = defineProps(["modelValue"]);

const emit = defineEmits(["update:modelValue"]);
</script>

Vue3.4 版本之后,我们将使用 defineModel 替代子组件中的 propsemit

javascript 复制代码
<!-- 子组件 CustomComponent  -->
<template>
  <input type="text" v-model="modelValue" />
</template>

<script setup>
const modelValue = defineModel();
</script>

带参数/定义多个 v-model

组件中可以支持定义多个 defineModel,可以满足绑定多个双向绑定的属性。

javascript 复制代码
<!-- 父组件 -->
<template>
  <div>
    <!-- 自定义子组件 CustomComponent 使用 v-model 指令绑定 userName -->
    <CustomComponent
      v-model="userName"
      v-model:title="title"
      v-model:subTitle="subTitle"
    />
  </div>
</template>

<script setup>
import { ref } from "vue";
import CustomComponent from "./CustomComponent.vue";

const userName = ref("前端开发爱好者");
const title = ref("前端开发爱好者_title");
const subTitle = ref("前端开发爱好者_subTitle");
</script>

修饰符和转换器

为了获取 v-model 指令使用的修饰符,我们可以像这样解构 defineModel() 的返回值:

javascript 复制代码
const [modelValue, modelModifiers] = defineModel()

// 对应 v-model.trim
if (modelModifiers.trim) {
  // ...
}

当存在修饰符时,我们可能需要在读取或将其同步回父组件时对其值进行转换。我们可以通过使用 getset 转换器选项来实现这一点:

javascript 复制代码
const [modelValue, modelModifiers] = defineModel({
  // get() 省略了,因为这里不需要它
  set(value) {
    // 如果使用了 .trim 修饰符,则返回裁剪过后的值
    if (modelModifiers.trim) {
      return value.trim()
    }
    // 否则,原样返回
    return value
  }
})
相关推荐
excel6 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子13 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构20 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep21 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss25 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风26 分钟前
html二次作业
前端·html
江城开朗的豌豆29 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵29 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae
画月的亮32 分钟前
前端处理导出PDF。Vue导出pdf
前端·vue.js·pdf
江城开朗的豌豆38 分钟前
拆解Redux:从零手写一个状态管理器,彻底搞懂它的魔法!
前端·javascript·react.js