Vue自定义组件中v-model的使用

107 阅读1分钟

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>