v-model

2 篇文章 0 订阅

默认元素v-model:

vue 中的v-model 实现了对数据的双向绑定,即 数据->模版,模版-> 数据 的绑定, 例如:

<input type="text" v-model="message">
<p>{{message}}</p>

v-model 是经过vue封装后的一个指令,目的是方便我们使用,它内部真实的实现方式:

<input :value="message" @input="message = $event.target.value">

上面一共两个步骤:

  • 将输入框的值value 绑定到message 变量上,这样改变 message 的值可以改变输入框的值,但是改变输入框的值不能改变message 的值。

  • 监听输入框的input事件,当发生输入内容时,改变message变量的值,这样就实现了双向绑定。

官网上说,v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 使用 value 和 input事件
  • checkbox 和 radio 使用 checked 和 change事件
  • select 使用 value 和 change 事件

自定义组件双向绑定:

当我们知道这些后, 可以试着写自定义输入框组件的v-model:

Vue.component('default-input', {
  template: '<input :value="value" @input="updateVal($event.target.value)" type="text" />',
  props: ['value'],
  methods: {
    updateVal(val){
    this.$emit('input', val)
    }
  }
})
// 父组件部分
var app = new Vue({
  el: '#app',
  data: {
    price: ''
  },
  methods: {
    onInput (val) {
      this.price = val
    }
  }
})
// html部分
<div id="app">
  <default-input :value="price" @input="onInput"/>
</div>

默认情况下,一个组件上的v-model 会把value作为 prop ,并且把input作为event。 但是自定义组件中使用v-model并不能实现双向绑定,因为自定义组件没有默认的value 和 input事件,所以在实现的时候需要我们去显式的声明这些东西。而vue2中的model就解决了这个问题,它可以在定义组件的时候去指定prop的值 和 监听的事件。

自定义组件v-model双向绑定:

Vue.component('my-input', {
  // 指定v-model对应的prop值 和 event事件名称
  model: {
    prop: 'name',
    event: 'changeName'
  },
  props: ['name'],
  methods: {
    updateVal(val){
      // 抛出的事件名称 参数值默认修改prop name, 实现双向绑定
    	this.$emit('changeName', val)
    }
  }
})
// html部分
<template>
    <input type="text" :value="name" @input="updateVal($event.target.value)">
</template>

父组件调用时可以直接使用v-model就可以:

<template>
  // userName是父组件中的属性也可以是其他xxx
   <default-input v-model="userName"/>
  {{userName}}
</template>

等同于:

<default-input :name="userName" @changeName="(val) => {userName = val}"/>

vue3 中v-model:

v-model 对应的prop 和 事件名称已经修改为:modelValue 和 update:modelValue

<template>
  <div @click="updateValue(value)"></div>
</template>
// 子组件内部
export default defineComponent({
    name: "my-input3",
    props: {
       	modelValue:String // 可以更改为其他属性
    },
    setup(props, context){
        const updateValue = (e: KeyboardEvent) => {
          context.emit("update:modelValue",e);   // 传递的方法
        }
        return {
        	updateValue
        }
    }
}
// 父组件
<my-input3 v-model:modelValue="userName"/>  
// 等同于
<my-input3 :modelValue="userName" @update:modelValue="userName = $event"/> 

modelValue也可以更改为其他更为见明知义的属性:

// 子组件内部
export default defineComponent({
    name: "my-input3",
    props: {
       	name:String // 可以更改为其他属性
    },
    setup(props, context){
        const updateValue = (e: KeyboardEvent) => {
          context.emit("update:name",e);   // 传递的方法
        }
    }
}
                              
// 父组件
<my-input3 v-model:name="userName"/>  
                               
// 等同于
<my-input3 :name="userName" @update:name="userName = $event"/> 

对普通prop进行双向绑定:

v-bind.sync (已废弃),使用 v-model:propName 代替

// 子组件抛出update:myPropName事件
this.$emit('update:title', newValue)

// 父级监听:
<my-input3 :title="userName" @update:title="userName = $event"/> 
 
// 简写:
<my-input3 :title.sync="userName" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值