组件是如何使用v-model?

318 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

在vue中v-model的使用是非常方便的,一般我们都是在element标签上面使用,今天就说一下在组件标签上使用v-model

作用

封装表单组件非常实用

先说一下在标签上面使用v-model

HTML标签的v-model

大多数人在标签直接v-mode就可以了,但是我们要知道当我们添加v-mode时,其实vue还帮助我们添加了一个事件,

<input 
    v-model="title" 
    @update:model-value="title = event.target.value"
    >
</input>

我们v-model绑定了一个title属性,但是后面的@update:model-value="title=event.target.value"我们似乎没见过,这个就是vue帮助我们绑定的一个数据更新的事件update,当数据发生更新,把event.target.value的值赋给title。从而实现数据更新。

接下来据说一下组件的v-model

组件v-model

绑定单个值

我们的目录表结构

结构.png

App组件有个子组件MyComponent组件

App组件引入Mycomponent组件,并且创建title,在组件标签上面引入v-model:title

<my-component v-model="title"></my-component>

在组件通过props传入title,但是要记住,v-model导入的值,要用modelValue接收

MyComponent组件
<template>
      <h1>{{modelValue}}</h1>
</template>
<script>
export default {
    props:{
        modelValue:String              //v-mode传入的必须要用modelValue接收
    }
}
</script>

看一下浏览器

单项传值.png 正常显示,可以接收。

但是vue的组件是单项数据流,是不允许我们在组件中修改的,此时我们用v-mode绑定就会报错

报错.png

当然肯定有解决办法,这里我们使用计算属性computed

computed:{
        msg:{
            get(){
                return this.modelValue
            },
            set(value){
                this.$emit("update:modelValue",value)
            }
        }
    }

我们计算一个msg,给他添加set,get属性,让他的值未modelValue,之前我们说过,如果我们添加了v-model属性,vue会给我们添加一个@update的事件,我们在emits里面拿到这个事件,set里面直接调用这个事件,实现修改功能

这样界面上就实现了vue组件的v-model

我们看一下浏览器效果

ChromeCore_MBE8YWOAfj.gif

可以看到,当我们修改input框的值时,title也在变化,已经实现了

现在又有一个问题,当我们想要绑定两个值我们要怎么做?

绑定多个值

现在我们有title,message两个值想要绑定到子组件,首先我们在App组件中这样写

 <my-component 
     v-model:title="title" 
     v-model:message="message"
     >
 </my-component>

通过v-model:title="title"把title传过去,那么MyComponent如何接收

在子组件中直接使用props接受这两个参数

这是v-model后面跟参数的情况
props:{
    title:String,
    message:String
},

我们之前说过都会有一个@update事件,那么这两个的update事件怎么传出来呢,

直接使用update:title就可以了

emits:['update:title','update:message'],

这样就得到了这两个事件

然后再给他们俩添加计算属性

computed:{
    msg:{
        get(){
            return this.title
        },
        set(value){
            this.$emit("update:title",value)
        }
    },
    content:{
        get(){
            return this.message
        },
        set(value){
            this.$emit("update:message",value)
        }
    }
}

把title给msg,把message给content,让后在input上面绑定

<template>
  <div>
      <input type="text" v-model="msg">
      <input type="text" v-model="content">
  </div>
</template>

我们看一下此时浏览器是否能正常显示

2.gif

此时的浏览器正常显示,且无报错

这样就实现了在组件上面使用v-mode实现双向绑定,这个封装一些表单真的是非常的方便