v-model实际上就是一个语法糖,等同于props与emit的操作,只是vue帮我们做了这部分操作
vue2中的v-model
使用input事件
在vue2中封装组件时,我们使用v-model去给组件绑定数据,实际上组件内部等同于接收了一个属性为value的prop,然后在我们需要改变v-model绑定的值时,我们需要通过emit一个input事件去将新的值返回,从而达到数据绑定的效果。
示例
// src/components/Input.vue
<template>
<div>
<input type="text" :value="showValue" @input="handleInput($event)">
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
},
},
data() {
return {
showValue: ''
}
},
methods: {
handleInput($event) {
this.showValue = $event.target.value
this.$emit('input', $event.target.value)
}
}
}
</script>
页面中使用这个组件
<template>
<Input v-model="inputVal"></Input>
<button @click="handleClick">查看最新的inputVal</button>
</template>
<script>
import Input from '@/components/Input.vue';
export default {
name: 'HelloWorld',
data() {
return {
inputVal: ''
}
},
methods: {
handleClick() {
console.log(this.inputVal)
}
}
}
</script>
vue3中的v-model
在vue3中,v-model已经支持传递多个,且有了以下的改变:
- prop: 使用
modelValue - emit: 使用
updata:modelValue - v-bind的
.sync修饰符已经移除 - 支持自定义修饰符
Modifiers
单个v-model
示例
// /src/components/Input.vue
<template>
<div>
<input :value="inputValue" @input="($event) => handleInput($event)">
</div>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('')
const propData = defineProps({
modelValue: String
})
const emit = defineEmits(['update:modelValue'])
const handleInput = ($event) => {
inputValue.value = $event.target.value
emit('update:modelValue',$event.target.value)
}
</script>
页面中使用这个组件
<template>
<InputVue v-model="inputVal"></InputVue>
<button @click="handleClick">查看最新的inputVal</button>
</template>
<script setup>
import InputVue from './components/Input.vue'
import { ref } from 'vue';
const inputVal = ref('')
const handleClick = () => {
console.log(inputVal.value);
}
</script>
多个v-model
组件上的每一个 v-model 都会同步不同的 prop,因此我们可以创建多个 v-model 双向绑定
语法:
| 用法 | prop | emit |
|---|---|---|
| v-modle | modleValue | update:modleValue |
| v-modle:title | title | update:title |
示例
<template>
<div>
<input :value="inputValue" @input="($event) => handleInput($event)">
<p>
title: {{ title }}
<button @click="handleChangeTitle">更改title</button>
</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('')
const propData = defineProps({
modelValue: String,
title: String
})
const emit = defineEmits(['update:modelValue', 'update:title'])
const handleInput = ($event) => {
inputValue.value = $event.target.value
emit('update:modelValue',$event.target.value)
}
const handleChangeTitle = () => {
emit('update:title', 'title被组件更新了')
}
</script>
页面中使用
<template>
<InputVue v-model="inputVal" v-model:title='title'></InputVue>
<button @click="handleClick">查看最新的inputVal</button>
</template>
<script setup>
import InputVue from './components/Input.vue'
import { ref } from 'vue';
import { RouterLink, RouterView } from 'vue-router'
const inputVal = ref('')
const title = ref('title')
const handleClick = () => {
console.log(inputVal.value);
}
</script>