Vue中的v-model

1.什么是v-model

v-model是Vue框架的一种内置的API指令,本质是一种语法糖写法,它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。在Vue中,v-model是用于在表单元素和组件之间创建双向数据绑定的指令。它可以简化表单元素的绑定,使得在用户输入时能够自动更新数据。

v-modelvalue+input的语法糖,是v-bindv-on的简洁写法。v-model就实现了双向数据绑定,实际上它就是通过Vue提供的事件机制。即在子组件通过$emit()触发一个事件,在父组件使用v-model即可。

2.什么是语法糖

在计算机科学中,语法糖(syntactic sugar)是指编程语言中可以更容易地表达一个操作的语法。它可以使程序员更加容易地使用这门语言,使操作变得更加清晰、方便,或者更加符合程序员的编程习惯。

具体来说,语法糖是语言中的一个构件,当去掉该构件后并不影响语言的功能和表达能力。例如,C语言中的标记a[i]就是*(a+i)的语法糖。

语言的处理器,包括编译器,静态分析器等,经常会在处理之前把语法糖构件转换成更加基础的构件,这个过程通常被称为"desugaring"。

简而言之,语法糖就是一种便捷写法。例如:input.map(a => a-8); 去掉语法糖就是:input.map(function (a) { return a - 8; }); 通过例子你可以看出来,语法糖的使用其实就是让我们的写的代码更简单,看起来也更容易理解。

3.v-model常见的用法

单向数据绑定:
在Vue中,我们可以使用v-bind实现单项的数据绑定,也就是通过父组件向子组件传入数据 ,但是反过来,子组件不可以修改父组件传递过来的数据 ,这也就是所谓的单向数据绑定。

双向数据绑定
v-bindv-on实现了双向绑定实现了双向数据绑定。

3.1 输入框(input)

<input type="text" v-bind:value="value" v-on:input="value = $event.target.value" />
//或者
<input type="text" :value="value" @input="value = $event.target.value" />

v-modelv-bindv-on的语法糖,即,v-model算是v-bindv-on的简洁写法。

<input type="text" v-model="value" />

在这个例子中,v-model将输入框的值与数据对象中的value属性进行了绑定。当用户输入时,value的值会自动更新。

3.2 复选框(checkbox)

<input v-model="checked" type="checkbox">

在这个例子中,v-model将复选框的选中状态与数据对象中的checked属性进行了绑定。当用户选中或取消选中复选框时,checked的值会自动更新。

3.3 选择框(select)

<select v-model="selected">  
  <option value="option1">Option 1</option>  
  <option value="option2">Option 2</option>  
</select>

在这个例子中,v-model将选择框的值与数据对象中的selected属性进行了绑定。当用户选择一个选项时,selected的值会自动更新为所选选项的value值。

除了以上的例子,v-model还可以用于其他表单元素和组件,如文本域(textarea)、开关(switch)等。它的工作原理是监听表单元素的输入事件,将输入值同步到绑定的数据属性上,同时当数据属性的值发生变化时,也会自动更新表单元素的值。

需要注意的是,v-model使用的数据属性通常应该是响应式对象或数组,这样才能够实现数据的双向绑定。如果使用非响应式对象或数组,v-model可能无法正常工作。

4.组件中的v-model

父组件:

<template>
    <div>
        <child-component v-model="message"></child-component>
        <p>Message from parent component: {{ message }}</p>
    </div>
</template>  
    
<script>
import ChildComponent from './childComponent.vue';

export default {
    data() {
        return {
            message: 'hello world'
        };
    },
    components: {
        ChildComponent
    }
};
</script>

子组件:

<template>
    <div>
        <p>Message from parent component: {{ value }}</p>
        <button type="button" @click="updateValue">更新</button>
    </div>
</template>  
    
<script>
export default {
    props: {
        value: {
            type: String,
            default: ""
        }
    },
    methods: {
        updateValue() {
            this.$emit("input", 'update message');
        }
    }
};
</script>

在这个例子中,父组件将message属性绑定到子组件的value属性上,并使用v-model指令来实现双向数据绑定。子组件内部点击按钮更新message,并使用$emit()触发一个事件,从而更新父组件的message属性。

由上可知:默认情况下,一个组件上的 v-model 会把value用作props且把 input用作event。

5.model选项

一些输入类型比如单选框和复选框按钮可能想使用valueprop 来达到不同的目的。这时候可以使用 model 选项回避这些情况产生的冲突。

下面来看一个例子:在父组件展示一个子组件弹框,在子组件里面有关闭整个组件的功能。

  • 之前:
    我们是在子组件中通过$emit触发父组件对应的方法,改变父组件上v-if对应的变量来控制显示隐藏。
  • 现在:
    有了v-model,这一切都变得很简单,最主要的是完全少了自定义对外暴露的关闭的方法,如果你关闭之后需要回调,那么通过监听你的是否显示的flag即可,所以大可放心使用。

下面来看代码:

//父组件
<template>
  <div id="app">
    <HelloWorld v-model="showFlag" v-if="showFlag"></HelloWorld>
    <button @click="showFlag=true">打开组件</button>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld'

export default {
  name: 'App',
  data(){
    return {
      showFlag: false
    }
  },
  components: {
    HelloWorld
  }
}
</script>
<template>
  <div class="hello">
    <h1>这是组件里面的内容</h1>
    <button @click="close">关闭组件</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: {
      type: Boolean
    }
  },
  methods: {
    close(){
      this.$emit('change', false)
    }
  }
}
//对于子组件来说,允许自定义使用v-model时定制prop和event,
//v-model中的prop就是把value用作prop,input用作event,
//但是为了避免冲突,我们使用model的选项可以回避这些冲突,
//当然,你也得使用props声明checked这个prop。

6.vue2中v-model和vue3的v-model有什么区别?

用在组件上(vue2):

  • v-model只能使用一次
  • 默认传递value属性,接受input事件
  • 默认传递的属性和事件可通过model选项进行修改

用在组件上(vue3):

  • v-model只能使用一次,但可以在v-model后添加参数可使用多次
  • 默认传递modelValue属性(默认绑定的不是value),接受update:modelValue事件(接收的方法不是input);当在v-model后添加参数时如v-model:myPropName,则传递为myPropName属性,接受 update:myPropName事件
  • 默认传递的属性和事件无法修改,必须是modelValueupdate:modelValue

7.vue2中v-model和.sync修饰符的区别?

两者都是父子组件双向绑定的语法糖。vue3中去除了 .sync修饰符,但把相应功能合并到了 v-model 上,所以在 vue3 中,v-model 可以使用多次。

不同点:

  • v-model 背后是 value 属性 和 input 事件
  • myPropName.sync 背后是 myPropName 属性 和 update:myPropName 事件
  • 在组件上 v-model只可使用一次,.sync可以有多个
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值