vue 表单元素和组件中v-model应用、自定义v-model、watch监听

(1)表单与侦听器

	1、放在input、textarea等输入框标签内
			<input v-model="message" placeholder="edit me">
			<textarea v-model="message" placeholder="add multiple lines"></textarea>
			
		(1)会忽略表单元素的value初始值,而是将data中初始化变量据作为数据来源的初始值
		
		修饰符(可以链式调用):
			v-model.lazy	等到回车/焦点消失,变量中的内容才是输入框中的内容
			v-model.trim	去掉输入框前后内容的空格
			v-model.number	将用户的输入值转为数值类型,单纯设置<input type='number'' />还是会被转换成字符串
		
		扩展属性,仅会在 v-model 存在时工作
			<input
			  type="checkbox"
			  v-model="toggle"
			  :true-value="dynamicTrueValue"
			  :false-value="dynamicFalseValue" 
			/>
			v-model属性的值会在选中时被设为true-value的值,取消选择时设为false-value的值

	2、放在单选框/复选框中
			v-model='变量'

		单选框:
			v-model值为选中的value值
			<input type="radio" id="one" value="One" v-model="picked">
			<input type="radio" id="two" value="Two" v-model="picked">

		多选框:
			(1)当标签未设置value,v-model会绑定是否选中的布尔值
				<input type="checkbox" id="checkbox" v-model="checked">	未设置value初始值,则会绑定到选中状态的布尔值
		 	(2)当标签设置value,且v-model绑定的值是数组,则会根据是否选中的value,往数组增/删元素
		 		<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
				<input type="checkbox" id="john" value="John" v-model="checkedNames">
				checkedNames: []

	3、下拉框
		 v-model的值为option标签中选中的值,若option标签设置了value,则为value值
		   <select v-model="selected">
		    <option disabled value="">请选择</option>
		    <option>A</option>
		    <option>B</option>
		    <option>C</option>
		  </select>

	4、多选下拉框(即在下拉框多加了multiple属性)
		v-mdodel必须声明成数组[ ],数组内容为多选文本内容,若option标签设置了value,则为value值
		  <select v-model="selected" multiple style="width: 50px;">
		    <option>A</option>
		    <option>B</option>
		    <option>C</option>
		  </select>
		  
	其中:
	 使用model选项来自定义各个表单的v-model
		<template>
		    <input
		      type="checkbox"
		      :checked="v-model传递的变量名"
		      @change="$emit('改变时触发的事件名称', $event.target.checked)"
		    >
	    </template>
		export default{
			model:{
				prop: 'v-model传递的变量名',		v-model的值会传入该变量
			    event: '改变时触发的事件名称'
			},
			props:['v-model传递的变量名']	在组件的props选项里声明这个prop。
			
		}
		<base-checkbox v-model="lovingVue"></base-checkbox>
			这里的lovingVue的值将会传入这个prop,同时当<base-checkbox>触发一个change事件并附带一个新的值的时,这个lovingVue的property将会被更新。

(2)组件中使用v-model
	1、在标签上使用v-model会等价于
		<input v-model="searchText">
		<input
		  v-bind:value="searchText"
		  @input="searchText = $event.target.value"
		>
	2、故在组件上使用,需要接收传递的value和$emit抛出input事件让父元素接收
		
		<custom-input v-model="searchText"></custom-input>
		
		旧版本:
			<custom-input
			  v-bind:value="searchText"
			  @input="searchText = $event"
			></custom-input>
			
		  组件中:
		  	Vue.component('custom-input', {
			  props: ['value'],
			  template: `
			    <input
			      v-bind:value="value"
			      @input="$emit('input', $event.target.value)"
			    >
			  `
			})
			
		新版本:
			<custom-input
			  :model-value="searchText"
			  @update:model-value="searchText = $event"
			></custom-input>
			组件中:
			app.component('custom-input', {
			  props: ['modelValue'],
			  emits: ['update:modelValue'],
			  template: `
			    <input
			      :value="modelValue"
			      @input="$emit('update:modelValue', $event.target.value)"
			    >
			  `
			})
		(1)修改默认:modelValue 、update:modelValue默认名称
			通过v-model:自定义名称,进行修改
			<my-component v-model:title="bookTitle"></my-component>
			app.component('my-component', {
			  props: {
			    title: String
			  },
			  emits: ['update:title'],
			  template: `
			    <input
			      type="text"
			      :value="title"
			      @input="$emit('update:title', $event.target.value)">
			  `
			})
		(2)传递并修改多个v-model名称同理:
			<user-name
			  v-model:first-name="firstName"
			  v-model:last-name="lastName"
			></user-name>
	    
	    (3)自定义修饰符
			<my-component v-model.capitalize="myText"></my-component>
			
			1、添加到组件v-model的修饰符将通过modelModifiers这个prop提供给组件
				app.component('my-component', {
				  props: {
				    modelValue: String,
				    modelModifiers: {
				      default: () => ({})
				    }
				  },
				  emits: ['update:modelValue'],
				  created() {
					console.log(this.modelModifiers)  =>{ capitalize: true }
				  },
				  methods: {
				    emitValue(e) {
				      let value = e.target.value
				      if (this.modelModifiers.capitalize) {
				        value = value.charAt(0).toUpperCase() + value.slice(1)
				      }
				      this.$emit('update:modelValue', value)
				    }
				  },
				  template: `<input
				    type="text"
				    :value="modelValue"
				    @input="emitValue">`
				})
				
			2、重命名的带修饰符的v-model
				<my-component v-model:description.capitalize="myText"></my-component>
				
				app.component('my-component', {
				  props: ['description', 'descriptionModifiers'],
				  emits: ['update:description'],
				  template: `
				    <input type="text"
				      :value="description"
				      @input="$emit('update:description', $event.target.value)">
				  `,
				  created() {
				    console.log(this.descriptionModifiers)  =>{ capitalize: true }
				  }
				})

			
		(4)使用computed封装
			app.component('custom-input', {
			  props: ['modelValue'],
			  emits: ['update:modelValue'],
			  template: `
			    <input v-model="value">
			  `,
			  computed: {
			    value: {
			      get() {
			        return this.modelValue
			      },
			      set(value) { 
			        this.$emit('update:modelValue', value)
			      }
			    }
			  }
			})
	

(3)监听函数
		监听的就是引用地址
		不能使用箭头函数:this将不会按照期望指向Vue实例,
		watch:{
			(1)普通监听
				函数名(data)/变量名:function(newData,oldData)
				{
					xxx
				},
				变量名:'methods中声明的变量名'
				"对象.属性":function (val, oldVal) {...} 监视嵌套属性,即对象下的某个属性
			
			(2)监听对象/数组内部属性的变化,deep表示深层监听
				名称:{
					handler:方法,
					deep:true
				},
				
				vm.$watch('someObject', callback, {
				  deep: true
				})
				
			(2.5)监听函数返回值
				vm.$watch(
				  function () {
				    return this.a + this.b  每当返回不同结果都会触发监听回调,类似计算属性
				    return this.a.b   监视嵌套属性,通过函数的方式
				  },
				  function (newVal, oldVal) {
				    ...
				  }
				)
				
				watch:{
					"e.g":function (val, oldVal) {} 监视嵌套属性,即e下的g属性
				}
				
			(2.6)设置监听调用时机
				vm.$watch('value',fn,{ 
					flush:'pre'|'post'|'sync'
						'pre': 默认值,指定的回调应该在渲染前被调用,它允许回调在模板运行前更新了其他值。
							回调使用队列进行缓冲,回调只被添加到队列中一次,即使观察值变化了多次,值的中间变化将被跳过,不会传递给回调。
						'post':指定回调推迟到渲染之后调用,如果回调需要通过$refs访问更新的DOM或子组件,那么则使用该值。					
							回调使用队列进行缓冲,回调只被添加到队列中一次,即使观察值变化了多次,值的中间变化将被跳过,不会传递给回调。
						'sync': 一旦值发生了变化,回调将被同步调用,无pre和post的特性。
				 })
				
			(3)侦听开始立即调用
				名称:{
					handler:方法,
					immediate: true,
				},
				vm.$watch('a', callback, {
				  immediate: true
				})

			(4)可以传入回调数组,它们会被逐一调用
				名称:[回调函数,回调函数,...]
				
				f:[
				  方式一:
			      'handle1',	在methods中声明的函数名
			      方式二:
			      function handle2(val, oldVal) {
			        console.log('handle2 triggered')
			      },
			      方式三:
			      {
			        handler: function handle3(val, oldVal) {
			          console.log('handle3 triggered')
			        },
			        deep: true
			      },
			      ...
			    ]
							
			(5)返回取消监听函数
				var unwatch = vm.$watch('a', cb);
				unwatch(); 取消监听,当添加immediate参数时,不能在第一次回调函数中取消监听
					兼容写法:
					var unwatch = vm.$watch(
					  'value',
					  function () {
					    doSomething()
					    if (unwatch) {
					      unwatch()
					    }
					  },
					  { immediate: true }
					)
		}

代码示例:

<template lang='html'>
	<div >

		<div>
		//输入框
			<input v-model.lazy.trim.number='inpt' type='text' name='' value='' id=''>
			<p>{{inpt}}</p>

			//单个多选按钮
			<input type='checkbox' value='a' id='ipt' v-model='checked'>
			<label for='ipt'>{{checked}}</label>
			<span>{{checked}}</span>	

			//单选按钮
			<input type="radio" id="one"  v-model="picked">
  			<label for="one">One</label>
  			<span>{{picked}}</span>	

  			 <input type="radio" id="two" value="Two" v-model="picked">
 			 <label for="two">Two</label>

 			 //多选下拉框
 			   <select v-model="selected" multiple style="width: 50px;">
			    <option>A</option>
			    <option>B</option>
			    <option>C</option>
			  </select>
			  <br>
			  <span>Selected: {{ selected }}</span>

			  //单选下拉框
			   <select v-model="selected2">
			    <option disabled value="">请选择</option>
			    <option>A</option>
			    <option>B</option>
			    <option>C</option>
			  </select>
			<span>Selected: {{ selected2 }}</span>

			//多选按钮
			<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
			  <label for="jack">Jack</label>
			  <input type="checkbox" id="john" value="John" v-model="checkedNames">
			  <label for="john">John</label>
			  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
			  <label for="mike">Mike</label>
			  <br>
			  <span>Checked names: {{ checkedNames }}</span>

		</div>

	</div>

</template>

<script>
export default{
	name:'vuedemo',
	data()
	{
		return{
			inpt:'',
			checked:[],
			picked:'',
			selected:[],
			selected2:[],
			checkedNames:[]
		}
	},
	//wacth
	watch:{
		inpt(data)
		{
			if(data==100)
			{
				this.inpt='符合条件'
			}
		}
	}
	
}
</script>

<style lang='css'>

</style>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值