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>
相关推荐
你很易烊千玺44 分钟前
JS 异步 从零讲(大白话 + 真实场景 + 可运行案例)
前端·javascript·vue.js
Lkstar5 小时前
Vue keep-alive 原理全解:LRU 缓存策略、源码级理解
前端·vue.js·面试
代码煮茶7 小时前
Vue3 埋点实战 | 从 0 搭建前端用户行为埋点系统
vue.js
鱼樱前端9 小时前
我做了一个不止有基础组件的 Vue 3 UI 库,还把 AI 组件也做进去了
前端·vue.js·ai编程
徐小夕10 小时前
面试官:AI生成到90%突然断了,你的解决方案是什么?(万字长文深度剖析)
前端·vue.js·算法
ljt272496066111 小时前
Vue笔记(六)--响应式
javascript·vue.js·笔记
天蓝色的鱼鱼12 小时前
尤雨溪亲自点赞!用 Vue 3 写原生 App,这个框架终于来了!
前端·vue.js
你听得到1113 小时前
从 Figma 走查到 AI 可验证产物:我如何重构客户端 UI 交付链路
前端·vue.js·flutter
卤蛋fg613 小时前
vxe-select 下拉框实现人员选择
vue.js
用户8417948145613 小时前
vxe-select 下拉框实现带单选框/复选框勾选功能
vue.js