v-model的基本使用

每天对自己多问几个为什么,总是有着想象不到的收获。 一个菜鸟小白的成长之路(copyer)

v-model的使用场景分为两种,一种在表单中,一种在组件


表单中使用

v-model的使用原理: 利用v-bind动态绑定value值,v-on监听触发的input事件,来修改value值

<template id="james">
    // v-bind: value   拿到data中的初始数据
    // v-on:input  监听changeMessage事件
   <input type="text" :value="message" @input="changeMessage">
   <div>{{message}}</div>
</template>

<script>
   Vue.createApp({
       template: "#james",
       data() {
           return {
            message: 'james'
           }
       },
       methods: {
        changeMessage(e) {   //拿到input的value值,修改message
            this.message = e.target.value
        }
       }
   }).mount("#app")
</script>

表单中的使用场景:

1、input输入框

<template>
    <input v-model="message" />
</template>

<script>
   data() {
        return {
            message: 'james'
        }
    }
</script>

2、复选框

单选框

<template>
    <label for="agree">
        //当value为true的时候,复选框就被选中了
       <input type="checkbox" id="agree" v-model="agree">同意协议
    </label>
</template>

<script>
    data() {
       return {
            agree: false
       }
    }
</script>

多选框

<template>
    <label for="james">
       <input type="checkbox" id="james" v-model="people" value="james">james
    </label>
    <label for="kobe">
        <input type="checkbox" id="kobe" v-model="people" value="kobe">kobe
    </label>
    <label for="curry">
        <input type="checkbox" id="curry" v-model="people" value="curry">curry
    </label>
    <div>{{people}}</div>
</template>

<script>
    data() {
        return {
            people: []
        }
        },
</script>

多选框: 一定要注意, 每个input必须要要对应一个value值,不然v-model不知道把什么数据添加在数组里面

3、单选框

<template>
    <label for="male">
       <input type="radio" v-model="gender" value="male" id="male"></label>
    <label for="female">
        <input type="radio" v-model="gender" value="female" id="female"></label>
    <div>{{gender}}</div>
</template>

<script>
    data() {
        return {
            gender: 'male'
        }
     },
</script>

注意: type 为radio, v-model绑定同一值,那么他们就是互斥的

4、选择框

<select v-model="lover">   //想要多选: multiple
    <option value="james">james</option>
    <option value="curry">curry</option>
    <option value="kobe">kobe</option>
</select>
<div>{{lover}}</div>

<script>
    data() {
        return {
            lover: 'james'
        }
     },
</script>

5、修饰符

//懒加载
<input type="text" v-model.lazy="agree">   
//绑定类型
<input type="text" v-model.number="agree">
//去掉空格
<input type="text" v-model.trim="agree">

组件中使用

组件之间进行双向绑定,也可以使用v-model

比如:下面自定义了一个my-input的组件, 把父组件中的message传递给子组件

<my-input v-model="message"></my-input>
//等价于
<my-input :modelValue="message" @update:model-value="message = $event">
</my-input>

//modelValue 默认绑定的值,需要在子组件中props注册
//@update:model-value监听model-value事件的更新,然后把$event赋值给message
//这里因为是组件,所以是$event,这是组件中$emit,传递过来的参数,而不是$event.target.value
实例代码:
//App.vue

<template>
    <div>
        <my-input v-model="message"></my-input>
    </div>
</template>
    
<script lang="ts">
    import { defineComponent } from 'vue'
    import MyInput from './MyInput.vue'
 
    export default defineComponent({
        data() {
            return {
                message: 'kobe'
            }
        },
        components: {
            MyInput
        }
    })
</script>

上面的代码中,我们注册了一个子组件my-input,然后通过 v-model把父组件中的message传递给子组件

//MyInput.vue

<template>
    <div>
        <input :value="modelValue" @input="inputEvent"/>
        <h2>{{modelValue}}</h2>
    </div>
</template>
    
<script lang="ts">
    import { defineComponent } from 'vue'
    
    export default defineComponent({
        props: {  //v-model传递下来的默认modelValue
            modelValue: String
        },
        //注册emit事件 (可以使用驼峰命名)
        emits: ['update:modelValue'],  
        methods: {
            inputEvent(e: any) {
                //$emit传递给父组件方法,和输入的input值
                this.$emit('update:modelValue', e.target.value)
            }
        }
    })
</script>

在子组件my-input内部有个input输入框,动态绑定传递下来的 props, 然后监听input事件,通过emit事件来触发update:modelValue,把修改的值传递给父元素,通知父元素修改。

在上面的子组件中的

<input :value="modelValue" @input="inputEvent"/>

//这不就相当于表单中的v-model嘛,那么我们可以直接使用v-model吗

<input v-model="modelValue" />

//很显然是不行的
//原因: 子组件直接修改了props的值,这违背了数据的单向流
//就算修改了,但是没有触发@update:model-value这个函数,父组件就不会更新

那如果,就是想在子组件中使用v-model ,那么该怎么处理呢?

这样就需要重新定义变量,来保存props传递过来的,这里建议是computed计算属性

<input v-model="modelValue" />


props: {  //v-model传递下来的默认modelValue
    modelValue: String
},
computed: {
    value: {
        get() {
            return this.modelValue   //getter函数直接返回modelvalue属性值
        },
        //使用setter方法,当值修改的时候,就触发update这个函数
        set(value) {
            this.$emit('update:modelValue', value)
        }
    }
}

完成目标

在组件中使用多个v-model
<MyInput v-model:message="message" v-model:title="title" />
//message 和 title就是新的名字, 去掉modelValue

//MyInput.vue
props: {
    message: String,
    title: String
}
emits:['update:message', 'update:title']

//然后接下来的逻辑跟上面一样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值