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>
相关推荐
小*-^-*九4 小时前
Electron vue项目 打包 exe文件
javascript·vue.js·electron
老华带你飞12 小时前
机电公司管理小程序|基于微信小程序的机电公司管理小程序设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·微信小程序·小程序·机电公司管理小程序
jojo是只猫12 小时前
Vue 3 开发的 HLS 视频流播放组件+异常处理
前端·javascript·vue.js
小时前端15 小时前
Vue基础10题:答错一道,别说你熟悉Vue
vue.js
有梦想的攻城狮17 小时前
从0开始学vue:npm命令详解
前端·vue.js·npm
我是日安18 小时前
从零到一打造 Vue3 响应式系统 Day 23 - Watch:基础实现
前端·javascript·vue.js
rggrgerj1 天前
VUE3+element plus 实现表格行合并
javascript·vue.js·elementui
huangql5201 天前
UniApp + Vite + Vue3 + TypeScript 项目中 ESLint 与 Prettier 的完整配置指南
vue.js·typescript·团队开发·代码规范