vue 自定义组件的v-model

本文探讨了Vue自定义组件中v-model的工作原理,揭示其作为语法糖的本质,即v-bind:value和v-on:input的组合。在组件内部,通过v-bind:value与父组件传递值,v-on:input利用$emit触发父组件更新。同时,文章指出在处理如checkbox、radio等类型的组件时,model属性的重要性,用于关注并更新组件的checked属性而非value。正确使用model属性可以确保组件行为符合预期,例如在checkbox中,model属性能确保组件初始状态的正确呈现。
v-model 能够实现一个双向绑定

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

当我们修改输入框中的数据时,会同时修改父元素中 data对象中的 value的值
也就是说 输入框的value值和 父元素中的 value值进行了绑定

v-model就是一个语法糖,实际上应该是这样
<div id="example1">
	<input type='text' v-bind:value="message" v-on:input="message=$event.target.value"/>
</div>
  • v-bind:value=“message” 这个就是将父元素的message值和input框的value值进行一个绑定(message变化导致value变化)
  • v-on:input=“message=$event.tartget.value” 这个是将input框的value值和父元素的message值进行一个绑定(value变化导致message变化)

BUT
如果我们使用组件,v-model就不是这么简单了

Vue.component('my-example1',{
	template:`
		<input type="text" v-bind:value="val" v-on:input="$emit('input',$event.target.value)"/>
	`,
	props:['val']
})
new Vue({
	el:"#example2",
	data:{
		val:''
	}
})
<div id="example2">
	<my-example1 v-model="val"></my-example1>
	{{val}}
</div>

剖析一下组件内的这个元素

<input type="text" v-bind:value="val" v-on:input="$emit('input',$event.target.value)"/>
  • 使用 v-bind:value 将 该input框的value值和从父元素传入的val值做绑定(父元素中的val变化导致input框的value值变化)

  • 使用 v-on:input 使用$emit 调用父元素的input事件,并将 $event.target.value(也就是这个input框的value值)传过去

如果没有理解父元素的val为什么变化,我们可以这么写父元素

<div id="example2">
	<my-example1 v-bind:value="val" v-on:input="getval"></my-example1>
</div>
new Vue({
	el:"#example2",
	data:{
		val:''
	},
	methods:{
		getval:function(v){
			this.val = v
		}
	}
})

当组件中子元素调用父元素的Input方法时,相当于调用了 getval($event.target.value) 修改了父元素的val值


官方API上还有组件中还有一个model属性,这个属性是干什么的呢?

注: 如果想直接理解它的作用,请直接看第二种方法

一般使用type为text, password 等类型的输入框的时候, 我们更加关注的是输入框的value属性,但是当我们时候 checkbox, radio 类型的输入框时,我们更加关注的应该是输入框的checked属性,应该这是也前端显示直接挂钩的.

如果我们没有在组件中定义model属性,但是又想修改父元素的val属性和组件的checked属性时,我们应该这样做:

<div id='example3'>
    <model id="abc" v-model="val"></model>
    {{val}}
  </div>

因为是checkbox,监控的应该是change事件而不是input事件,但是没有定义Model属性时,只能调用父元素的input事件来进行一些行为

Vue.component('model',{
  // model:{
  //   prop:'checked',
  //   event:'change'
  // },
  props:['val'],
  template:`
  <input type="checkbox" :checked='val' @change="$emit('input',$event.target.checked)" >
  `,

})
new Vue({
  el:'#mod',
  data:{
    val:true,
  }
})

Vue.component('model',{
  model:{
     prop:'checked',
     event:'change'
  },
  props:['val'],
  template:`
  <input type="checkbox" :checked='val' @change="$emit('change',$event.target.checked)" >
  `,

})

这里不只是将组件内添加了一个Model属性,而且这是用我们调用的是父元素的change事件

如果之间在html的开发者工具中看这两者的区别, 我们可以看到

  • 第一种修改了组件(input框) 的value属性(但是它的checked属性也是修改了)
  • 第二种修改了组件(input框) 的checked属性(但是不会修改它的value属性)

而且使用第一种方式的话页面刚刚渲染出来的时候复选框是不会选上的,而使用第二种方式复选框默认是选上的(会将true值渲染成checked)


所以说使用model属性的根本理由是:
对于这种"特殊" 的输入框,我们修改这个输入框的时候应该关注的不是它的值,而是它是否选中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值