v-model 可以在组件上使用以实现双向绑定。
Vue3
从 Vue 3.4 开始,推荐的实现方式是使用 defineModel() 宏:
Parent Component
<template>
<Child v-model="count"></Child>
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const count = ref(0)
</script>
<style scoped>
</style>
Child Component
<template>
<div class="count-box">
<button class="reduce" @click="reduce">-</button>
<input type="number" v-model="defaultCount" >//
<button class="add" @click="add">+</button>
</div>
</template>
<script setup>
//`defineModel()` 返回的值是一个 ref
//可以像其他 ref 一样被访问以及修改,
//可以在父组件和当前变量之间实现双向绑定的作用
const defaultCount = defineModel({
default: 1,
type: Number
})
const reduce = () => {
if(defaultCount.value <= 1){
return
}
defaultCount.value -= 1
}
const add = () => {
defaultCount.value += 1
}
</script>
<style scoped>
.count-box{
width: 158px;
display: flex;
height: 36px;
button{
width: 36px;
}
.reduce{
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
.add{
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
input{
width: 72px;
background-color: #efefef;
border: none;
margin: 0 5px;
text-align: center;
}
}
在 3.4 版本之前
Parent Component
<template>
<Child v-model="count"></Child>
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const count = ref(0)
</script>
<style scoped>
</style>
Child Component
<template>
<div class="count-box">
<button class="reduce" @click="reduce">-</button>
<input type="number" :value="props.modelValue" @input="emit('update:modelValue',$event.target.value)" >
<button class="add" @click="add">+</button>
</div>
</template>
<script setup>
const props = defineProps({
modelValue: {
type: Number,
default:1
}
})
console.log(props.modelValue);
const emit = defineEmits(['update:modelValue'])
const reduce = () => {
if(props.modelValue <= 1){
return
}
emit('update:modelValue',props.modelValue - 1)
}
const add = () => {
emit('update:modelValue',props.modelValue + 1)
}
</script>
Vue2
Parent Component
<template>
<Child v-model="count"></Child>
</template>
<script >
import Child from './Child.vue'
export default {
data(){
return {
count: 1
}
},
components: {
Child
}
}
</script>
<style scoped>
</style>
Child Component
<template>
<div class="count-box">
<button class="reduce" @click="reduce">-</button>
<input type="number" :value="value" >
<button class="add" @click="add">+</button>
</div>
</template>
<script>
export default {
props:{
value:{
type:Number,
default:1
}
},
methods:{
reduce(){
if(this.value <= 1){
return
}
this.emit('update:modelValue', this.value - 1)
},
add(){
this.emit('update:modelValue', this.value + 1)
}
}
}
</script>
<style scoped></style>