v-model 指令在表单控件元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。但是 Vue 是单项数据流,v-model 只是语法糖而已。

     v-model这个指令只能用在<input>, <select>,<textarea>这些表单元素上,所谓双向绑定,指的就是我们在js中的vue实例中的data与其渲染的dom元素上的内容保持一致,两者无论谁被改变,另一方也会相应的更新为相同的数据。这是通过设置属性访问器实现的。

一.双向绑定列子

那么在表单处理中我们具体如何使用v-model呢,先看看官方文档给出的例子:

<span style="color:#666666">
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model双向绑定</title>
</head>
<body >
<form id="demo">
	<!-- text -->
	<p>1.  <input type="text" v-model="msg">input文本:{{msg}}</p>
	<!-- checkbox -->
<p>2. <input id="checkbox"type="checkbox"v-model="checked"><label for="checkbox">{{ checked }}</label></p>
	<div>
		<span>3.  </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>
		<br>
		<span>多选的名字checkbox: {{ checkedNames }}</span>
	</div>
	<br>
	<!-- radio buttons -->
	<div>
		<span>4.  </span>
	  	<input type="radio" id="one" value="苹果" v-model="picked">
	  	<label for="one">苹果</label>
	  	<input type="radio" id="two" value="梨" v-model="picked">
	 	<label for="two">梨</label>
	    <br>
	    <span>单选框radio: {{ picked }}</span>
	</div>
	<br/>
	<!-- select -->
	<div>
		<span>5.  </span>
		<select v-model="vselected">
			<option disabled value="">请选择</option>
			<option>A</option>
			<option>B</option>
			<option>C</option>
		</select>
		<span>单选列表select: {{ vselected }}</span>
	</div>
	<br/>
	<br/>
	<!-- multiple select -->
	<div>
		<span>6.  </span>
		<select v-model="selected">
		  	<option v-for="option in options" v-bind:value="option.value">
		    {{ option.text }}
		 	 </option>
		</select>
		<span>Selected: {{ selected }}</span>
	</div>
	<br/>
	<div>
		<p>7.  textarea多行文本:{{ textarea }}</p>
		<textarea v-model="textarea" placeholder="add multiple lines"></textarea>
	</div>
	<br/>
	<br/>
	<p><pre>最后data: {{$data}}</pre></p>
</form>
<script src="js/vue.js"></script>
<script>
var vm =new Vue({
	el: '#demo',
	data: {
	    msg      : 'hello vue.js!',
	    checked  : true,
	    checkedNames: [],
	    picked   : '苹果',
	    vselected:'',
	    selected: '杜鹃',
	    options: [
	      { text: 'One', value: '杜鹃' },
	      { text: 'Two', value: '牡丹' },
	      { text: 'Three', value: '百合' }
	    ],
	    textarea:'hello vue.js!'

	}
});
</script>
</body>
</html>
</span>

当你在浏览器上调整上面表单元素的选中值时,你会发现下面打印的vue实例内容也会随之改变,而如果你在代码中改变vue实例data内容时渲染出来的表单选中值也会随之改变。

二.修饰符   

v-model这个指令还有几个可选的参数:lazy,number,trim,options

1.使用lazy参数是将双向数据同步的时间节点从input触发改为了change触发,调用方式如下:

<!-- synced after "change" instead of "input" -->
<input v-model.lazy="msg" >

2.使用number参数是通知v-model绑定的dom元素把用户输入值默认当成数字来处理,调用如下:

<input v-model.number="age" type="number">

3.如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入

 <input v-model.trim="msg">

4.使用options参数是用于渲染一个select项的列表,调用方式如下:

<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
   {{ option.text }}
</option>
</select>

其中options的参数名指向一个数组,该数组可以包括字符串或对象,对象可以是{text:'', value:''}的形式,指定了<option>的value属性与text内容,例如:
data: {
   selected: '杜鹃',
   options: [
     { text: 'One', value: '杜鹃' },
     { text: 'Two', value: '牡丹' },
     { text: 'Three', value: '百合' }
   ]
}
将渲染出:
<select>
   <option value="杜鹃">One</option><option value="牡丹">Two</option>
<option value="百合">Three</option>

</select>

三.例子

1.添加的数据 添加到表格中

<template>
	<div>
		<el-col :span="24">
			<el-form ref="form">
				<el-form-item label="姓名">
					<el-input v-model="userData.name"></el-input>
				</el-form-item>
				<el-form-item label="出生日期" >
					<el-input v-model="userData.date"></el-input>
				</el-form-item>
				<el-form-item label="地址" >
					<el-input v-model="userData.address"></el-input>
				</el-form-item>
				<el-form-item>
					<el-button type="primary" @click="onSubmit">立即创建</el-button>
				</el-form-item>
			</el-form>
		</el-col>
		<el-table :data="userDatas">
			<el-table-column prop="date" label="日期"></el-table-column>
			<el-table-column prop="name" label="姓名"></el-table-column>
			<el-table-column prop="address" label="地址"></el-table-column>
		</el-table>
	</div>
</template>
<script>
export default {
	data () {
		return {
			userData:[{data:'',name:'',address:''}],
			model_data:'',
			userDatas: [{
				date: '2016-05-02',
				name: '王小虎1',
				address: '上海市普陀区金沙江路 1518 弄'
	        }, {
	          date: '2016-05-04',
	          name: '王小虎2',
	          address: '上海市普陀区金沙江路 1517 弄'
	        }, {
	          date: '2016-05-01',
	          name: '王小虎3',
	          address: '上海市普陀区金沙江路 1519 弄'
	        }, {
	          date: '2016-05-03',
	          name: '王小虎4',
	          address: '上海市普陀区金沙江路 1516 弄'
	        }]
		}
	},
	methods: {
		onSubmit(){
			this.userDatas.push(this.userData);
		}
	}
}
</script>

四.补充

1.vue.js的双向数据绑定就是通过Object.defineProperty(前端数据双向绑定原理:Object.defineProperty())方法实现的,俗称属性拦截器。

五. 自定义组件的 v-model

背景:在有些情况下,需要对一个 prop 进行“双向绑定”

(1)vue2++

vue自定义组件上的v-model结合mode(通过 mode 来指定其他属性)如何与子组件数据绑定

 

父组件:

<user v-model="name"></user>
<div>子传给父的:{{name}}</div>
import  User from './User.vue'
export default {
    name: 'Lons',
    components: {
        User
    },
    data() {
        return {
            name:"王一博",
        }
    }
}

子组件:

<template>
    <div>
        <input v-model="pValue"  />
    </div>
</template>

<script>
export default {
    name: 'User',
    data() {
        return {
            pValue: this.value,
        }
    },
    props: {
        // 实现双向绑定 和value更新
        value: {
            type: String,
            defaultValue: '',
        },
    },
    // 通过v-model双向绑定
    // 组件内使用model更新值
    model: {
        prop: 'value',//父组件传下来的值与props相对应
        event: 'change',//事件:触发这个事件,从而改变父组件的v-model的值
    },
    // 监听器
    watch: {
        // 子组件更新 则更新父组件
        pValue: function (val) {
            this.$emit("change", val);
        },
    },
    created () {
        console.log('父传给子的数据:',this.value)
    }
}
</script>

要注意的是:

<input>数据发生改变的时候父组件的parentValue也能同步改变,那还要手动触发一个change事件,提交到父组件:所以我们应该在watch里面添加input的监听,当数据发生改变时,手动提交一个change事件,将数据传到父组件,以此完成数据的双向绑定(input 只能数据双向绑定,并不能与父组件的进行双向绑定)。

(2)vue3

v-model prop 和事件默认名称已更改:

prop属性:value 变为-> modelValue;
event事件:input 变为-> update:modelValue;

Logo

前往低代码交流专区

更多推荐