Vue 3 的 v-model

1,830 阅读1分钟

目前在学习 Vue 3,使用了 v-model 实现父子组件的数据交流。发现 v-model 是 Vue 2 到 Vue 3 的一个 breaking change,因此记录了学习过程。

breaking change 1

  • 属性名任意,假设为 value
  • 事件名必须为 "update:value"
// 在组件中使用
<Button :value="x" @update:value="x = $event" />

// 简写
<Button v-model:value="x" />

breaking change 2

  • 新的 v-model 代替了 .sync 和以前的 v-model
  • 新的 v-model 可以在同一组件上进行多个绑定
// before 
<Button :value.sync="x" :title.sync="y" />

// after
<Button :value="x" @update:value="x = $event" :title="y" @update:title="y = $event" />

// 简写
<Button v-model:value="x" v-model:title="y" />

手写 Switch 组件通信实例

Switch 组件

<template>
    <button @click="toggle" :class="{checked:value}"><span></span></button>
</template>
<script lang="ts">
import { ref } from 'vue'
export default {
    props:{
        value:Boolean
    },
    setup(props,context){
        const toggle = ()=>{
            context.emit('update:value',!props.value)
        }
        return {toggle}
    }
}
</script>

SwitchDemo组件

<template>
    <div>
   // 	<Switch :value="bool" @update:value="bool = $event" />   等同于
        <Switch v-model:value="bool">
    </div>
</template>
<script lang="ts">
import { ref } from 'vue'
import Switch from '../lib/Switch.vue'
export default {
    components:{Switch},
    setup(){
        const bool = ref(false)
        return {bool}
    }
}
</script>
  • Switch 组件通过 :value="bool" 接收到 SwitchDemo 组件传来的属性
  • Switch 组件使用 context.emit('update:value',!props.value) 触发一个事件,并传给外部一个新值。
  • 即通知 SwitchDemo 组件要对外部属性进行更改
  • 第一个参数是事件,第二个参数是结果。与 :value="bool" @update:value="bool = $event" 一一对应
  • 最后 SwitchDemo 组件监听了 update:value 事件 ,通过 $event 拿到了新值后更新数据: @update:value="bool = $event"

Vue 2 与 Vue 3 的区别

  • 新 v-model 代替之前的 v-model.sync
  • 新增 context.emit 与 this.$emit 作用相同

参考文献:

  1. Vue 官方文档
  2. 深入理解 Vue 的 .sync 修饰符
  3. v-model 的本质是语法糖