当前位置: 首页 > news >正文

Vue 3.5 defineModel:让组件开发效率提升 10 倍

简介

defineModel 是 Vue 3.4 引入并在 Vue 3.5+ 中稳定的一个组合式 API,它简化了组件的双向数据绑定实现。在此之前,实现双向绑定需要手动定义 props 和 emits,而 defineModel 将这个过程自动化,让代码更加简洁和直观。

主要特性

  • 简化双向绑定:自动处理 props 和 emits 的定义
  • 类型安全:完整的 TypeScript 支持
  • 多模型支持:支持多个 v-model 绑定
  • 向后兼容:与现有的 props/emits 模式完全兼容

基础用法

传统方式 vs defineModel

传统方式(Vue 3.4 之前):

<script setup>
// 子组件
const props = defineProps(["modelValue"]);
const emit = defineEmits(["update:modelValue"]);const updateValue = (newValue) => {emit("update:modelValue", newValue);
};
</script><template><input :value="props.modelValue" @input="updateValue($event.target.value)" />
</template>

使用 defineModel:

<script setup>
// 子组件
const model = defineModel();
</script><template><input v-model="model" />
</template>

父组件使用

<script setup>
import { ref } from "vue";
import MyInput from "./MyInput.vue";const inputValue = ref("Hello World");
</script><template><MyInput v-model="inputValue" /><p>当前值:{{ inputValue }}</p>
</template>

高级用法

综合示例

<!-- 子组件 -->
<script setup>
// 定义 v-model
const modelValue = defineModel();// 带默认值
const count = defineModel("count", { default: 0 });// 多个 v-model
const firstName = defineModel("firstName");
const lastName = defineModel("lastName");
</script><template><div class="min-h-screen bg-gray-100 py-8 px-4"><div class="max-w-lg mx-auto"><div class="bg-white rounded-lg shadow-md p-6"><h2 class="text-xl font-semibold text-gray-800 mb-6 text-center">用户信息表单</h2><div class="space-y-4"><!-- Main Value Input --><div><label class="block text-sm font-medium text-gray-700 mb-2">主要信息</label><div class="flex items-center space-x-3"><inputv-model="modelValue"placeholder="请输入主要信息"class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-gray-500 focus:border-gray-500 transition-colors"/><span class="text-sm text-gray-600 min-w-0 flex-shrink-0">{{ modelValue || "未填写" }}</span></div></div><!-- Count Input --><div><label class="block text-sm font-medium text-gray-700 mb-2">数量</label><div class="flex items-center space-x-3"><inputv-model="count"type="number"placeholder="请输入数量"class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-gray-500 focus:border-gray-500 transition-colors"/><span class="text-sm text-gray-600 min-w-0 flex-shrink-0">{{ count }}</span></div></div><!-- Name Inputs --><div><label class="block text-sm font-medium text-gray-700 mb-2">姓名</label><div class="grid grid-cols-2 gap-3 mb-2"><inputv-model="firstName"placeholder="名字"class="px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-gray-500 focus:border-gray-500 transition-colors"/><inputv-model="lastName"placeholder="姓氏"class="px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-gray-500 focus:border-gray-500 transition-colors"/></div><div class="text-right"><span class="text-sm text-gray-600">{{firstName && lastName? `${firstName} ${lastName}`: "未完整填写"}}</span></div></div></div></div></div></div>
</template>
<!-- 父组件 -->
<script setup>
import { ref } from "vue";
import MyComponent from "./MyComponent.vue";const value = ref("Hello");
const count = ref(5);
const first = ref("John");
const last = ref("Doe");
</script><template><div class="min-h-screen bg-gray-50"><MyComponentv-model="value"v-model:count="count"v-model:firstName="first"v-model:lastName="last"/></div>
</template>

验证器

const count = defineModel("count", {default: 0,validator: (value) => {return typeof value === "number" && value >= 0;},
});

修饰符 (.trim, .lazy)

const text = defineModel("text", {default: "",// 使用 set 转换器自动去除空格set(value) {return typeof value === "string" ? value.trim() : value;},
});

与传统方式的对比

特性传统方式defineModel
代码量较多简洁
类型安全需手动定义自动推导
多模型支持复杂简单
学习成本较高较低
性能相同相同

注意事项

  1. Vue 版本要求:需要 Vue 3.4+ 版本
  2. 编译器支持:需要配置支持 defineModel 的编译器
  3. 向后兼容:可以与传统的 props/emits 方式混用
  4. SSR 支持:完全支持服务端渲染

总结

defineModel 是 Vue 3.5+ 中一个强大而简洁的 API,它大大简化了组件双向数据绑定的实现。通过减少样板代码、提供更好的类型支持和更直观的 API,它让开发者能够更专注于业务逻辑的实现。

无论是简单的表单输入还是复杂的自定义组件,defineModel 都能提供优雅的解决方案,是现代 Vue 开发中不可或缺的工具。

 Vue 3.5 defineModel:让组件开发效率提升 10 倍 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿技术分享

http://www.dtcms.com/a/309059.html

相关文章:

  • 自行实现log2对数运算
  • Pydantic模块学习
  • TDengine 中 TDgp 中添加机器学习模型
  • AT6668B芯片说明书
  • unity学习——视觉小说开发(一)
  • 51单片机入门:模块化编程
  • 用 TensorFlow 1.x 快速找出两幅图的差异 —— 完整实战与逐行解析 -Python程序图片找不同
  • forceStop流程会把对应进程的pendingIntent给cancel掉
  • ceph 14.2.22 nautilus Balancer 数据平衡
  • 通过CISSP考试,共答到第127题
  • 雷达微多普勒特征代表运动中“事物”的运动部件。
  • 机械手弧焊电源气体流量优化方法
  • 算法:分治-快速排序
  • IO流File类的基本使用
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第二天(CSS)
  • 《n8n基础教学》第三节:模拟一个自动化场景
  • CSS的2D转换
  • 【Shell脚本自动化编写——报警邮件,检查磁盘,web服务检测】
  • 了解Reddit自动化 社区营销更精准
  • CSS组件化样式新篇章:@scope
  • vi/vim跳转到指定行命令
  • 机器学习第二课之逻辑回归(二)LogisticRegression
  • LSTM网络从浅入深原理级讲解与Pytorch逐行讲解实现
  • [python][selenium] Web UI自动化8种页面元素定位方式
  • K8S周期性备份etcd数据实战案例
  • 番茄项目3:完成了项目的数据库设计
  • npm报错:npm install 出现“npm WARN old lockfile”
  • ZED 2/2i 相机安装与调试完整指南 | Ubuntu 20.04 + CUDA 11.8
  • k8s云原生rook-ceph pvc快照与恢复(下)
  • 前端SWR策略:优化数据请求