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>
相关推荐
小毛驴8509 小时前
Vue 路由示例
前端·javascript·vue.js
TT哇11 小时前
【实习 】银行经理端两个核心功能的开发与修复(银行经理绑定逻辑修复和线下领取扫码功能开发)
java·vue.js
星光不问赶路人12 小时前
vue3使用jsx语法详解
前端·vue.js
weixin79893765432...13 小时前
Vue 组件的更新过程(编译系统 + 响应式系统 + 虚拟 DOM & Diff)
vue.js
我是伪码农14 小时前
Vue 智慧商城项目
前端·javascript·vue.js
小书包酱15 小时前
在 VS Code中,vue2-vuex 使用终于有体验感增强的插件了。
vue.js·vuex
Zhencode15 小时前
Vue3 响应式依赖收集与更新之effect
前端·vue.js
天下代码客15 小时前
使用electronc框架调用dll动态链接库流程和避坑
前端·javascript·vue.js·electron·node.js
weixin79893765432...16 小时前
Vue 渲染体系“三件套”(template 模板语法、h 函数和 JSX 语法)
vue.js·h函数·template 模板·jsx 语法
xkxnq17 小时前
第五阶段:Vue3核心深度深挖(第74天)(Vue3计算属性进阶)
前端·javascript·vue.js