对比一下v-model和.sync的使用
首先是v-model
// 父组件
<template>
<div class="xxxx">
<div class="xx">
<!--
完整写法
<son :value="num" @input="e => num = e" />
-->
<son v-model="num" />
</div>
</div>
</template>
<script>
import son from './son.vue'
import syncSon from './syncSon.vue'
export default {
components: {
son,
syncSon
},
data() {
return {
num: 0
}
}
}
</script>
// 子组件
<template>
<div>
点击次数 {{ value }}
<!-- props 单向数据流 所以直接value-- 会报错-->
<el-button @click="$emit('input', value + 1)">+1</el-button>
</div>
</template>
<script>
export default {
props: {
value: {
type: Number,
required: true
}
},
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
</style>
从代码我们可以看出,v-model 是一个语法糖, 它本质上做了两件事情:
1. 绑定一个 value 属性给子组件
2. 绑定一个 input 事件, 子组件触发后重新赋值。
再来看.sync
// 父组件
<template>
<div class="xxxx">
<div class="xx">
<!--
完整写法
<syncSon :count="num" @update:count="e => num = e" />
-->
<syncSon :count.sync="num" />
</div>
</div>
</template>
<script>
import son from './son.vue'
import syncSon from './syncSon.vue'
export default {
components: {
son,
syncSon
},
data() {
return {
num: 0
}
}
}
</script>
// 子组件
<template>
<div>
点击次数: {{ count }}
<el-button @click="$emit('update:count', count - 1)">-1</el-button>
</div>
</template>
<script>
export default {
props: {
count: {
type: Number,
required: true
}
}
}
</script>
<style lang="scss" scoped>
</style>
可以看出来
.sync 帮我们省去了事件绑定, 事件名必须是 update:属性名
总结一下
v-model 有一些限制:
1. 绑定的属性必须要叫 value
2. 事件必须要叫 input
3. 组件只能用一个 v-model 指令
.sync 可以解决了 v-model 的三点限制,绑定的属性可以自定义,事件名前需添加update:,可以添加多个。