Vue3.4版本新特性,更优雅的处理组件间的数据双向绑定

前言

本文主要描述Vue3.4新API defineModel,它在实际开发中使用场景非常广泛。主要替代了传统的prop + emit的方式,用更简短的代码来处理父子组件中的数据双向绑定。

写法对比

.sync修饰符
html 复制代码
/* 父组件 */
<template>
  <div>
    <Child-component :count.sync="count" />
  </div>
</template>

<script>
export default {
  components: {
    'ChildComponent': () => import('@/components/ChildComponent.vue')
  },
  data() {
    return {
      count: 0
    }
  }
}
</script>
html 复制代码
/* 子组件 */
<script>
export default {
  props: {
    count: {
      type: Number,
      default: 0
    }
  },  
  methods: {
    handleCountChange() {
    	this.count = 1
    }
  }
}
</script>
emit()
html 复制代码
/* 父组件 */
<template>
  <div>
    <Child-component :count="count" />
  </div>
</template>

<script>
export default {
  components: {
    'ChildComponent': () => import('@/components/ChildComponent.vue')
  },
  data() {
    return {
      count: 0
    }
  }
}
</script>
html 复制代码
/* 子组件 */
<script>
export default {
  props: {
    count: {
      type: Number,
      default: 0
    }
  },  
  methods: {
    handleCountChange() {
      this.$emit('update:count',1)
    }
  }
}
</script>
defineModel()
html 复制代码
/* 父组件 */
<template>
  <div>
    <Child-component v-model="count" />
  </div>
</template>

<script setup>
const count = ref(0)
</script>
html 复制代码
/* 子组件 */
<script setup>
const count = defineModel()
const handleCountChange = () => {
	count.value ++
}
</script>

修饰符

当遇到需要使用修饰符时,需要解构defineModel()的返回值,这里官方文档提供了示例

html 复制代码
/* 父组件 */
<script setup>
const [modelValue, modelModifiers] = defineModel()
// 为 true 时说明父组件使用了这个修饰符
if(modelModifiers.trim) {
	// 需要手写处理trim
}
</script>
html 复制代码
/* 子组件 */
<script setup>
const [modelValue, modelModifiers] = defineModel({
  // get() 省略了,因为这里不需要它
  set(value) {
    // 如果使用了 .trim 修饰符,则返回裁剪过后的值
    if (modelModifiers.trim) {
      return value.trim()
    }
    // 否则,原样返回
    return value
  }
})
</script>

绑定多个数据

html 复制代码
/* 父组件 */
<template>
  <Child-component
    v-model="count" 
	v-model:visible="visible" 
	v-model:arr="arr"
  />
</template>

<script setup>
const count = ref(0)
const visible = ref(false)
const arr = ref([])
</script>
html 复制代码
/* 子组件 */
<script setup>
const count = defineModel()
const visible = defineModel("visible", { default: false })
const arr= defineModel("arr", { default:() => [] })
</script>

typescript写法

html 复制代码
<script setup lang="ts">
const count = defineModel<number>()
const visible = defineModel<boolean>("visible", { default: false })
const arr= defineModel<[]>("arr", { default:() => [] })
</script>
相关推荐
weixin_422555423 小时前
el-menu子菜单点击就被激活,恢复之前的激活状态
javascript·vue.js·elementui
honkun65 小时前
vue 表格组件 vxe-table 实现拖拽列字段自动生成透视表汇总
前端·javascript·vue.js
leoZ2315 小时前
第 4 篇:布局骨架——页面壳、栅格、卡片
前端·javascript·vue.js·opencv·计算机视觉·数据挖掘·语音识别
何以解忧,唯有..6 小时前
Vue 3 模板语法详解:从插值到指令的完整指南
前端·javascript·vue.js
雪芽蓝域zzs8 小时前
第十四节:后端返回权限动态路由
前端·javascript·vue.js
Rain5098 小时前
谁动了我的 URL?——记一次微前端“灵异 Bug“的排查实录
前端·vue.js·人工智能·前端框架·bug·ai编程
何以解忧,唯有..8 小时前
Vue 3 响应式核心:ref() 与 reactive() 的深入解析与实战
前端·javascript·vue.js
宿67418 小时前
vue3-async
前端·javascript·vue.js
Dreams°1231 天前
【Java后端+Vue前后端分离:内网正常、公网访问异常|5个高频经典踩坑完整复盘】
java·开发语言·vue.js
小蒜学长1 天前
基于Springboot+Vue的环保行动志愿者招募系统设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端