我们知道v-model是用来进行双向数据绑定,通常可以用在表单元素中或者可以用在组件中,但在Vue2和Vue3中的组件上使用时是有差别的,现在我们来介绍它在Vue2和Vue3中是如何使用的。
这里也附上我的博客网站。
一、v-model在Vue2中的使用
1. 默认使用实现自➕1 等价于 :value + @input
<!-- 父组件 -->
<template>
<MyInput v-model="count" />
<!-- 等价于 -->
<MyInput :value="count" @input="count=$event" />
</template>
<script>
import MyInput from './components/MyInput.vue'
export default {
components: { MyInput },
data() {
return {
count: 1
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<span>{{value}}</span>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyInput',
props: {
value: {
type: Number,
default: 0
}
},
methods: {
add() {
this.$emit('input', this.value+1)
}
}
}
</script>
2. 使用model选项修改属性和事件名实现自➕1 等价于 :num + @change
<!-- 父组件 -->
<template>
<MyInput v-model="count" />
<!-- 等价于 -->
<MyInput :num="count" @change="count=$event" />
</template>
<script>
import MyInput from './components/MyInput.vue'
export default {
components: { MyInput },
data() {
return {
count: 1
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<span>{{num}}</span>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyInput',
model: {
prop: 'num', // 将默认value属性改为num
event: 'change' // 将默认input事件改为change
}
props: {
num: {
type: Number,
default: 0
}
},
methods: {
add() {
this.$emit('change', this.num+1)
}
}
}
</script>
3. 使用.sync语法糖实现v-model
<!-- 父组件 -->
<template>
<MyInput :num.sync="count" />
<!-- 等价于 -->
<MyInput :num="count" @update:num="count=$event" />
</template>
<script>
import MyInput from './components/MyInput.vue'
export default {
components: { MyInput },
data() {
return {
count: 1
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<span>{{num}}</span>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyInput',
props: {
num: {
type: Number,
default: 0
}
},
methods: {
add() {
this.$emit('update:num', this.num+1)
}
}
}
</script>
二、v-model在Vue3中的使用
1. 默认使用实现自➕1 等价于 :modelValue + @update:modelValue
<!-- 父组件 -->
<template>
<MyInput v-model="count" />
<!-- 等价于 -->
<MyInput :modelValue="count" @update:modelValue="count=$event" />
</template>
<script>
import MyInput from './components/MyInput.vue'
import { ref } from 'vue'
export default {
components: { MyInput },
setup() {
const count = ref(1)
return { count }
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<span>{{modelValue}}</span>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyInput',
props: {
modelValue: {
type: Number,
default: 0
}
},
setup(props, {emit}) {
const add = () => {
emit('update:modelValue', props.modelValue+1)
}
return { add }
}
}
</script>
2. 通过使用v-model:num修改属性和事件名实现自➕1 等价于 :num + @update:num
<!-- 父组件 -->
<template>
<MyInput v-model:num="count" />
<!-- 等价于 -->
<MyInput :num="count" @update:num="count=$event" />
</template>
<script>
import MyInput from './components/MyInput.vue'
import { ref } from 'vue'
export default {
components: { MyInput },
setup() {
const count = ref(1)
return { count }
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<span>{{num}}</span>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyInput',
props: {
num: {
type: Number,
default: 0
}
},
setup(props, {emit}) {
const add = () => {
emit('update:num', props.num+1)
}
return { add }
}
}
</script>
3. Vue3移除了.sync语法糖实现v-model
三、Vue3相比Vue2多了哪些特性
1. Vue3废除了model选项和sync修饰符
2. Vue3支持使用多个v-model
<!-- 父组件 -->
<template>
<MyInput v-model:num="count" v-model:title="title" />
</template>
<script>
import MyInput from './components/MyInput.vue'
import { ref } from 'vue'
export default {
components: { MyInput },
setup() {
const count = ref(1)
const title = ref('题目')
return { count, title }
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<span>{{ num }}</span>
<span>{{ title }}</span>
<button @click="add">+1</button>
<button @click="changeTitle">换题</button>
</div>
</template>
<script>
export default {
name: 'MyInput',
props: {
num: Number,
title: String
},
setup(props, { emit }) {
const add = () => {
emit('update:num', props.num + 1)
}
const changeTitle = () => {
emit('update:title', '红颜旧')
}
return { add, changeTitle }
}
}
</script>
4. 自定义v-model修饰符
在 Vue2 中的 v-model
上,我们用过 .trim
、.lazy
和 .number
这三个内置修饰符,而 Vue3 则在这个基础上增加了自定义修饰符,即开发者可以自定义修饰符,以按需处理绑定值。
比如下面自定义capitalize修饰符实现首字母大写
<!-- 父组件 -->
<template>
<MyInput v-model:title.capitalize="title" />
</template>
<script>
import MyInput from './components/MyInput.vue'
import { ref } from 'vue'
export default {
components: { MyInput },
setup() {
const title = ref('')
return { title }
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<input type="text" :value="title" @input="emitValue" />
</div>
</template>
<script>
import { onMounted } from 'vue'
export default {
name: 'MyInput',
props: {
title: String,
titleModifiers: {
type: Object,
default: () => ({})
}
},
// 默认情况下
// props: {
// modelValue: String,
// modelModifiers: {
// type: Object,
// default: () => ({})
// }
// },
setup(props, { emit }) {
onMounted(() => {
console.log(props.titleModifiers) // { capitalize: true }
})
const emitValue = (e) => {
let value = e.target.value
value = value.charAt(0).toUpperCase() + value.slice(1) // 实现输入首字母大写
if (props.titleModifiers.capitalize) {
emit('update:title', value)
}
}
return { emitValue }
}
}
</script>