自定义表单组件的v-model

本文介绍了如何在Vue中为自定义表单组件实现v-model双向绑定。通过理解v-model的原理——结合:value和@input,可以将v-model应用到自定义组件上。同时,讨论了在不同类型的输入控件中,如单选框、复选框,可能需要使用model选项来处理v-model的冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义组件的v-model

v-model指令非常好用,直接可以让表单元素的值与data中的值实现双向绑定:

	<div id="app">
    	<input type="text" v-model="msg">
  	</div>
	var app = new Vue({
	    el: '#app',
	    data: {
	      msg: ''
	    }
	})

这样msg的值就与input的输入绑定了。

如果我们自定义了一个表单组件,想用v-model来绑定数据,要怎么做呢?
定义好组件后,直接在组件上使用v-model,是实现不了的

	<div id="app">
    	<my-input v-model="msg"></my-input>
    	<p>{{msg}}</p>
  	</div>
	Vue.component('my-input', {
    	template: `<input type="text" >`
  	})
	var app = new Vue({
	    el: '#app',
	    data: {
	      	msg: '我是msg'
	    }
	})

无论你在input中怎么输入,p元素中的内容都不会变。
要想在自定义表单组件中使用v-model,先要知道v-model是怎么实现的。

v-model是一个语法糖,不使用语法糖就是这样写(不同的输入控件写法可能不一样,后面会提到):

	<div id="app">
    	<input type="text" :value="msg" @input="msg = $event.target.value">
  	</div>
	var app = new Vue({
	    el: '#app',
	    data: {
	      msg: ''
	    }
	})

:value=“msg”: msg的值是啥,input中显示的就是啥
@input=“msg = $event.target.value”: input中输入啥,msg就变成啥
这样成完成了双向绑定。

知道了它的实际实际写法,在自定义组表单件中,如果不使用语法糖来实现的话,那就是这样:

	<div id="app">
    	<my-input :value="msg" @input="msg = $event"></my-input>
    	<p>{{msg}}</p>
  	</div>
Vue.component('my-input', {
    props: {
      	value: String // 需要接收父组件传来的value
    },
   	template: `<input type="text" :value="value" @input="$emit('input', $event.target.value)">`
 })
 var app = new Vue({
	el: '#app',
 	data: {
   		msg: '我是msg'
 	},
})

子组件接收父组件传来的value,并v-bind到自己的value
子组件的input事件来触发父组件的input事件,并将input的value值作为参数传递到父组件。

这样确实是实现了,但是我说好的用v-model呢,是不是只要在my-input组件调用的时候使用v-model就行了呢:

	<div id="app">
    	<my-input v-model="msg"></my-input>
    	<p>{{msg}}</p>
  	</div>
Vue.component('my-input', {
    props: {
      	value: String // 需要接收父组件传来的value
    },
   	template: `<input type="text" :value="value" @input="$emit('input', $event.target.value)">`
 })
 var app = new Vue({
	el: '#app',
 	data: {
   		msg: '我是msg'
 	},
})

运行一下,好像就是这个样子,是不是没有问题了呢?

我在官网上看到这样一句话:
“一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突。”

智能翻译器:v-model会默认使用元素的value值和input事件,但有的输入控件关键的值不是value,或者没有input事件,自定义表单组件的v-model就会有问题,需要用model选项来处理这种问题。
以下几种输入控件对比一下:

	<!--value为关键值, 用input事件来修改值-->
	<input type="text" > 
	<!--value为关键值, 用change事件来修改值-->
	<select>
		<option value="1">第一个选项</option>
		<option value="2">第二个选项</option>
		<option value="3">第三个选项</option>
	</select>
	<!--checked为关键值, 用change事件来修改值-->
	<input type="checkbox" > 

刚刚我们写的my-input组件的完整写法是这样

	<div id="app">
    	<my-input v-model="msg"></my-input>
    	<p>{{msg}}</p>
  	</div>
Vue.component('my-input', {
	model: {
		prop: 'value',
		event: 'input'
	},
    props: {
      	value: String
    },
   	template: `<input type="text" :value="value" @input="$emit('input', $event.target.value)">`
 })
 var app = new Vue({
	el: '#app',
 	data: {
   		msg: '我是msg'
 	},
})

如果我们用的是checkbox,借用一下官网的demo:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked', // 输入控件的'关键值'
    event: 'change' // 用于修改值的事件
  },
  props: {
    checked: Boolean
  },
  template: `<input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" >`
})

就到这里了,谢谢浏览!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值