[笔记][Vue.js]打开Vue.js世界的大门(4)-让v-model双向绑定抓住你的资料

HI!记得我们在第一篇的时候有提过如何将Vue.js的资料绑定到View上面吗?如果忘记的话可以看一下以下最简单的範例:
HTML

<input id="name" :value="text" >

JavaScript

let name = new Vue({    el:'#name',    data:{        text:'神Q超人',    },})

透过指定HTML的元件来创建一个Vue物件,并在物件中用data属性传入资料物件,这是一个Vue.js对View的单向绑定,而Vue.js还有提供双向绑定!我们今天就来提一下要如何做到双向绑定!

v-model

在Vue.js中有个v-model属性可以做到这件事情,他可以对inputtextareaselectcheckboxcheckbox这堆全部让使用者输入的表单做双向的绑定,主要是透过事件去监听使用者输入的事件来更新我们一开始给的,感觉是不是很厉害?让我们动手做看看吧!

input

像第一篇说的,Vue.js的用法都非常直觉,感觉很难的v-model也是,只需要将v-model当做属性加到input里面就可以了!
HTML

<div id="name">    <!--为input设定一个v-model属性,并将绑定的资料设定为text-->    <input v-model="text" :value="text">    <div>您的姓名是:{{text}}</div></div>

JavaScript

//这里把资料拆出来let nameData = {    text : '神Q超人'}let name = new Vue({    el:'#name',    data:nameData,})

在HTML的部分,我们将text这个资料绑定在三个地方,分别是input的预设值、div的内容和我们今天提到的v-model,因为v-model的关係,他在监听到input的资料如果改变,会即时更新text里面的值,而又因为div内绑定了text的资料,所以也会同步更新成新值,就像下方的操作:
http://img2.58codes.com/2024/2010693573Fyf9wG4U.jpg
很简单吧!那让我们继续说下去!

textarea

这个表单就和input一样,不同的是文字可以在textarea内折行,而厉害的是,就算折行Vue.js也不会忘记他: 
HTML

<div id="introduce">    <textarea v-model="text" :value="text"></textarea>    <div>您的自我介绍内容:</div>    <pre>{{text}}</pre></div>

JavaScript

let introduceData = {    text : '自我介绍内容'}let introduce = new Vue({    el:'#introduce',    data:introduceData,})

http://img2.58codes.com/2024/20106935LjFycaKMg8.jpg
这边题外话一下,上面我把text放到一个pre标籤中,这个<pre>我之前发现的神奇标籤,在他里面会保留textarea内输入的换行,这是我的秘密武器XD

select

select比较特别,我们这里应用上一篇讲的迴圈来填入select的选项,然后像上方一样,在select中增加v-model去绑定数据。

不一样的是,因为选项是动态产生的,资料会存在v-for="list in lists"list中,但实际上的data内并没有list这个属性,所以必须再增加一个selectNamev-model绑定数据,这么一来,只要select的选项改变,list内的item就会把目前绑定的value值(下方程式码中的:value="list.item")写给selectName,而后方的资料变动,也就会同时更新View,可以看以下範例:

<div id="gender">    <select v-model="selectName">        <option v-for="list in lists" :value="list.item">{{list.item}}</option>    </select>    <div>选择的性别是:{{selectName}}</div></div>
let genderData = {    selectName : '',    lists : [        {val:"M",item:'男'},        {val:"W",item:'女'},    ]}let gender = new Vue({    el:'#gender',    data:genderData,})

http://img2.58codes.com/2024/20106935hYriuqNtP7.jpg
看到上方的结果,我们确实做到了select的双向绑定,但也许会有个问题,如果我要同时取得optionvaluetext呢?就目前看来似乎只能绑定一个,所以这时候我们要利用事件绑定方法的@change来处理这件事情!
HTML

<div id="gender">    <!--这里把v-model先拿掉,要留着也可以,增加了@change事件-->    <select id="s_gender" :value="selectVal" @change="updateVal">      <option v-for="list in lists" :value="list.val" >{{list.item}}</option>    </select>    <div>选择的性别是:{{selectName}}</div>    <div>该性别的值是:{{selectVal}}</div></div>

JavaScript

let genderData = {    selectName : '',    selectVal : '',    lists : [        {val:"M",item:'男'},        {val:"W",item:'女'},    ]}let genderMethods = {    //将目前该性别选单的value和name写入genderData的selectName及selectVal    updateVal : () =>{        let obj = document.getElementById('s_gender')        //取得值        genderData.selectVal = obj.value;        //取得目前选择选项的文字        genderData.selectName = obj.options[obj.selectedIndex].text;          }}let gender = new Vue({    el:'#gender',    data:genderData,    methods:genderMethods,})

http://img2.58codes.com/2024/20106935j3djAgFq80.jpg
结果会将两个值都带出来,不过上面的方法看起来有点複杂,其实只是土法炼钢用change事件去更新genderData内属性的值,并藉由单像绑定的特性更动前面的View,不过用这个方法就等于和没v-model的做法一样,不晓得有没有更好的方法,如果有其他做法还麻烦各位大大教我一下,谢谢!

select的multiple版本

下拉选单有两个版本,一种是上面提到的单选的,另一种是複选的,其实我也不晓得从什么时候,只要在select中加入multiple属性,他自然就会变成複选的版本,Vue.js在处理複选的资料时,他会把所有选择的资料,不管几个都放进阵列再写回后方的data中,我们用刚刚的範例直接看看结果吧!
HTML

<div id="gender">    <!--在select属性中加入multiple设定为複选-->    <select v-model="selectName" multiple >        <option v-for="list in lists" :value="list.item">{{list.item}}</option>    </select>    <div>选择的性别是:{{selectName}}</div></div>

JavaScript

let genderData = {    selectName : '',    lists : [        {val:"M",item:'男'},        {val:"W",item:'女'},    ]}let gender = new Vue({    el:'#gender',    data:genderData,})

以上其实都没有改变,就只是在select中加入了multiple属性,不过这个在实务上似乎没有那么常见,结果会像下方,当我选择一个或以上的值的时候,绑定的资料会变成阵列写回!
http://img2.58codes.com/2024/20106935NSiqhie1sF.jpg

checkbox

看到这里,应该就会轻鬆不少了,因为剩下的单选框和複选框的用法就和下拉选单差不多,直接来看看吧(原谅我偷懒直接把上面的下拉选单改成複选框XD)!
HTML

<div id="gender">    <div>      <span v-for="list in lists">        <input type="checkbox" :value="list.item" v-model="checkedNames"/>        <label>{{list.item}}</label>      </span>    </div>    <div>选择的性别是:{{checkedNames}}</div></div>

JavaScript

let genderData = {    //这里绑定的值要是阵列    checkedNames : [],    lists : [        {val:"M",item:'男'},        {val:"W",item:'女'},    ]}let gender = new Vue({    el:'#gender',    data:genderData,})

http://img2.58codes.com/2024/2010693576yd59c1aX.jpg
结果应该是和下拉选单的multiple版本是一样的,但是有个卡了我非常久的地方XD,如果是check的话一开始由v-modle绑定的资料应该要是阵列型态,也就是说checkedNames的初始设置checkedNames:''这样是不行的,他必须要是checkedNames:[]才可以,这点用在checkbox的时候要注意一下!

radio

终于来到最后了XD,这里是单选框,也就是很单纯的单一值,没有多选就没有阵列,那来看看压轴的範例吧(如果你发现下面的範例和上面根本一模一样,那绝对是错觉XD)!
HTML

<div id="gender">    <div>      <span v-for="list in lists">        <input type="radio" :value="list.item" v-model="checkedNames"/>        <label>{{list.item}}</label>      </span>    </div>    <div>选择的性别是:{{checkedNames}}</div></div>

JavaScript

let genderData = {    checkedNames : '',    lists : [        {val:"M",item:'男'},        {val:"W",item:'女'},    ]}let gender = new Vue({    el:'#gender',    data:genderData,})

做到了这里,各位应该脑子里都会有画面大概会呈现什么结果了吧!那我们一起来见证是不是和想像中一样!
http://img2.58codes.com/2024/2010693538JxZHzIr3.jpg
没错!所以其实看似很难的双向绑定,在Vue.js中也变的简单起来了,当然还是有些时候我们必须手动去取值给data,就像上方下拉选单同时取valuetext的情况,不过如果是我理解错误,拜託各位大大一定要告诉我!不想活在错误中啊XD,另外关于v-model还有几点要额外提的部分:

1. .lazy

v-modle中,我们使用双向绑定,不论是input或是select资料都会即时的绑定,但是当你使用input又不想让他即时绑定资料,可以加上.lazy属性,他就像一般的onchange一样,只有在该input失去焦点的时候才会重新绑定资料!
HTML

<div id="name">    <input v-model.lazy="text" :value="text">    <div>您的姓名是:{{text}}</div></div>

JavaScript

let nameData = {    text : '神Q超人'}let name = new Vue({    el:'#name',    data:nameData,})

http://img2.58codes.com/2024/20106935Zz2rkTsxgq.jpg
这么一来就会如画面上,当游标还停留在input时,Vue.js就不会进行资料的绑定,只有在焦点离开input的时候才会再绑定data,当然如果是像select之类的表单,在选择的时候就等于离开焦点,所以也感受不到.lazy的效果。

2. .number

这一个.number则是会在type="number"时使用,为了避免有文字输入的情况,他会只容许数字进行绑定,例如:
HTML

<div id="age">    <input v-model.number="text" :value="text" type="number">    <div>您的年龄是:{{text}}</div></div>

JavaScript

let ageData = {    text : '神Q超人'}let age = new Vue({    el:'#age',    data:ageData,})

http://img2.58codes.com/2024/2010693546IjPsSFxo.jpg
可以看到,就算我一开始的data是中文,他也不会进行资料绑定到inputvalue当中,一直到我把他的value更改成数字,才会进行绑定。

3. .trim

这个属性就单纯多了,会在绑定资料的时候自动清除前后的空白!
HTML

<div id="name">    <input v-model.trim="text" :value="text">    <div>您的姓名是:{{text}}</div></div>

JavaScript

let nameData = {    text : '神Q超人'}let name = new Vue({    el:'#name',    data:nameData,})

http://img2.58codes.com/2024/20106935SAeGmcrv6j.jpg
如上图,当在文字的前后不论输入多少空白都不会被绑定到data中,不过文字与文字之间的空白则会保留,另外当焦点移开input时,也会重新绑定成移除字串头尾空白后的资料!

补充说明(感谢fysh711426大大在此篇文章中的补充)

watch的运作主要是因为v-model帮我们做了两件事情

使用v-bind单向绑定资料,会因为每次绑定值的变动同步更新到View上。使用v-on:input去侦测每次值的变动,触发更新v-bind绑定的值。

所以以下两种写法是一样的:
v-model

<input v-model="text">

v-bind&v-on:input

<input  v-bind:value="text"  v-on:input="text = $event.target.value">

参考文章:https://blog.csdn.net/u010320804/article/details/79486034


以上!讲了很多关于v-modle的用法和情况,不过这些都只是基本的而已,其实只要看懂一个就能够应用在其他表单上,在这之后还有更可怕的在等着XD。最后也感谢各位大大的观看!如果文章中有任何理解错误或是不清楚的地方,还请留言告诉我,我会尽快修正的!谢谢大家!http://img2.58codes.com/2024/emoticon41.gif


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章