目前在学习 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 的区别
参考文献: