23.Vue中雙向資料繫結是如何實現的
vue中如何實現資料的雙向繫結
vue中如何實現資料的雙向繫結
vue中的指令
v-cloak:
v-model(表單元素設定了之後會忽略掉value,checked,selected)
v-text:代替 {{}} 渲染成文字(不會識別html標籤)可以防止網速卡慢時{{}}出現在頁面上
v-html:把html字元渲染成html
v-once:只繫結一次(不能寫成v-once=”msg”)
v-bind:動態地繫結一個或多個特性
v-for:遍歷陣列、物件、字串、數字
條件渲染:v-if v-else-if v-else與v-show
v-show
v-on:監聽 DOM 事件(v-on:click可縮寫為@click)
自定義指令
vue中的修飾符
表單修飾符
事件修飾符
表單元素雙向資料繫結(雙向同步)
單選框
複選框
下拉框
Vue中的Class樣式與style樣式動態繫結(動態的優先順序高於原來的)
根據hash實現單頁面開發
vue中如何實現資料的雙向繫結
實現檢視變化資料跟著變:分兩步,上面get中的為第二步(即再次讀取的時候會呼叫get方法得到之前設定的值,以此來實現動態改變) 由於直接寫obj.name = this.value;會導致迴圈呼叫set方法,所以要藉助中間物件的形式把值賦給中間物件,獲取obj.name的時候我們獲取中間物件的最新值即可let obj = {name:'zhufeng',age:9};//資料 let temp = {name:"lily"};//藉助中間物件 let input1 = document.getElementById("box2");//檢視 //對某一個物件使用了Object.defineProperty方法之後就要寫對應的get和set方法了,不然無法像操作普通物件一樣訪問或者設定它的屬性 //此方法不相容IE8及以下 Object.defineProperty(obj,"name",{ configurable:true,//屬性是否可刪除 writable:false,//屬性是否可修改 enumerable:false,//屬性是否可列舉 get(){//獲取obj的屬性名對應的屬性值時會呼叫該方法 /*2*/ return temp['name']; }, set(val){//設定obj的屬性名對應的屬性值時會呼叫此方法 //實現檢視變化資料跟著變:分兩步,上面get中的為第二步(即再次讀取的時候會呼叫get方法得到之前設定的值,以此來實現動態改變) //由於直接寫obj.name = this.value;會導致迴圈呼叫set方法,所以要藉助中間物件的形式把值賦給中間物件,獲取obj.name的時候我們獲取中間物件的最新值即可 /*1、*/ temp.name=val; //實現資料變化檢視改變 input1.value=val; } }); //為了初始化的時候讓檢視中(文字框中)有值:出現obj.name說明要訪問這個屬性就會用到defineProperty中的get方法 input1.value=obj.name; //實現檢視改變資料跟著改變 input1.addEventListener("input",function(){ obj.name = this.value;//當值變化時會呼叫set方法 },false);
vue中的指令
dom元素的行間屬性,vue提供了內建的指令,必須以v-開頭,後面的值均為變數
v-cloak:
消除頁面剛載入時會看到{{}}閃一下的效果,可加給最外層的根元素;
//需要新增對應的css樣式 [v-cloak]{ display: none; }
v-model(表單元素設定了之後會忽略掉value,checked,selected)
讓表單元素和資料實現雙向繫結(對映關係)
<input type="text" v-model="msg">
v-text:代替 {{}} 渲染成文字(不會識別html標籤)可以防止網速卡慢時{{}}出現在頁面上
{{}} 中的值都會解析成文字內容;
{{msg}}等價於<div v-text="msg"><!--此處不能再寫內容,防止出現閃的效果--></div>
v-html:把html字元渲染成html
<div v-html="msg"></div>
v-once:只繫結一次(不能寫成v-once=”msg”)
<div v-once>{{msg}}</div>
v-bind:動態地繫結一個或多個特性
// 繫結一個屬性 <img v-bind:src="imageSrc"> //可縮寫為如下形式,此時:src後面的值就可以是變數、表示式、賦值運算、計算、三元運算子(儘量少寫邏輯運算) <img :src="imageSrc">//此時imageSrc就代表一個變數
v-for:遍歷陣列、物件、字串、數字
解決了迴圈問題,更高效,會在原有的基礎上進行修改,會複用原有的結構,不會修改所有DOM
要迴圈建立哪一個標籤就在那一個標籤上加v-for,後面的迴圈最好用in,用of有時會報錯迴圈陣列或物件使用v-for指令 <div v-for="(val,index) in msg"> {{val,index}}//msg為陣列時,val為陣列中的每一項,index為索引 </div> <div v-for="(value,key,index) in msg"> {{key}}={{value}}{{index}};//msg為物件時,key為物件中的每個屬性名,value為屬性值,index為索引 </div>
條件渲染:v-if v-else-if v-else與v-show
v-if v-else-if v-else:條件滿足才渲染v-if所在標籤以及標籤內的內容;(操作的是DOM結構)
- 設定條件判斷的DOM元素必須是連續的
- 操作的是DOM元素
- key 管理複用的元素 若不想複用DOM元素,只需要給相應的DOM元素增加不同的key值
- 支援 template 標籤
- 頻繁的顯示和隱藏用v-if會很浪費效能(操作的是DOM結構),此時要用v-show(操作的是CSS樣式)
<div id="app"> <button @click="flag=!flag">請點選</button> //template標籤是vue提供給我們的沒有任何實際意義,用來包裹元素用的(v-show不支援template標籤) <template v-if="flag"> <label>登入</label> <input type="text" key="1">//key 管理複用的元素 若不想複用DOM元素,只需要給相應的DOM元素增加不同的key值 </template> <template v-else> <label>註冊</label> <inputtype="text"key="2"> </template> </div> let vm=new Vue({ el:'#app', data:{ flag:true } });
v-show
條件滿足才讓v-show所在標籤以及標籤內的內容顯示(操作的是元素的css樣式),不支援 template 標籤
<input type="text" v-show="flag">//flag為true時,input框才顯示
v-on:監聽 DOM 事件(v-on:click可縮寫為@click)
可以用 v-on 指令監聽 DOM 事件,並在觸發時執行一些 JavaScript 程式碼(在
methods
物件中定義的方法,而且methods中的方法名不能和data中的變數名一樣)
<div v-on:click ="fn1('zhaosi,$event')">{{msg}}</div> <div @click ="fn1('zhaosi,$event')">{{msg}}</div>//上面的簡寫 方法後面可加()可不加。不加的話預設會傳入事件物件e, 加()代表要傳引數,如果要用事件物件,則需要傳$event
自定義指令
可通過在vue例項的directives:{}屬性中賦予自定義指令意義
<div id="app"> <button v-color="flag">變色</button> </div> let vm=new Vue({ el:'#app', data:{ flag:true }, directives:{//在這裡賦予對應自定義指令意義 //可直接寫對應的指令不用寫v- color(el,val){ //el和val都是預設給的:el指的是指令所繫結的DOM元素,val是一個物件,裡面儲存的是有關指令的資訊,可用val.value獲取到指令繫結的變數(或者表示式)所代表的值,這裡就是flag所代表的值 'red' el.style.background=val.value; } } });
vue中的修飾符
表單修飾符
v-model.number
:將使用者的輸入值轉為數值型別v-model.lazy
:在表單觸發change事件時更新資料,而非觸發input事件時更新資料v-model.trim
:自動過濾使用者輸入的首尾空白字元事件修飾符
@click.stop
:阻止點選事件的傳播(往上傳播和往下傳播都會被阻止)@submit.prevent
:阻止點選提交按鈕時的預設行為(阻止事件的預設行為)@click.capture
:點選的時候讓事件在捕獲階段執行;@click.once
:只在第一次點選的時候讓繫結的事件執行;@click.self
:只有點選的事件源是自己的時候觸發事件;(判斷事件源)
表單元素雙向資料繫結(雙向同步)
使用v-model屬性可讓input中的內容和資料實現雙向同步,但是使用了v-model屬性之後,input的value、checked、select屬性都會失效
<div id="app"> <input type="text" v-model="msg"> </div> <script src="vue.js"></script> <script> let vm=new Vue({ el:'#app',//vue的屬性和方法對哪個DOM根元素起作用(對它的後代元素也起作用) //資料 如果data中屬性的值是一個數組,如果想改變陣列中內容,只能使用原生的會修改原陣列的方法進行修改,普通的 陣列[索引]=值 不行; data:{//寫在data中的屬性都會掛載到當前例項上 msg:'zhufeng' } }); console.log(vm.msg);//'zhufeng' </script>
單選框
對於單選框和複選框來說,加了v-mdel屬性後,初始設定的value屬性不會失效;
<div id="app"> <input type="radio" v-model="msg" value="男">男 <input type="radio" v-model="msg" value="女">女 {{msg}} </div> let app3=new Vue({ el:'#app', data:{ msg:'男'//預設選中的項,值與value的值對應,點選女的時候msg就會動態改為女 } });
複選框
單個複選框:
<div id="app"> //複選框中加了v-model後value依然可用 <input type="checkbox" v-model="msg"> </div> let app3=new Vue({ el:'#app', data:{ //如果是複選框且只有一個的時候,會把msg的值轉化為布林值,如果為true,代表選中 msg:false//為false時代表預設不選中 } });
多個複選框,需要繫結到同一個陣列,而且要給input設定初始value值,為了在後面選中的時候獲取到對應的選中框的值
<div id="app"> //複選框中加了v-model後value依然可用 <input type="checkbox" v-model="msg" value="吃飯">吃飯 <input type="checkbox" v-model="msg" value="睡覺">睡覺 <input type="checkbox" v-model="msg" value="敲程式碼">敲程式碼 {{msg}} </div> new Vue({ el: '#app', data: { msg: [] //此處的msg需要是一個數組 } })
下拉框
<div id="app"> //加了multiple後就變為多選框,用ctrl+左鍵點選多選,msg也要換為一個數組 <select v-model="msg" multiple> //加了disabled時候使用者就不能選中此項了 //option中的value是給寫程式碼的人看的 <option value="0" disabled>請選擇地區</option> <option value="1">北京</option> <option value="2">上海</option> <option value="3">浙江</option> </select> {{msg}}//如果option的value屬性不寫,則取的是option中的內容 </div> let app3=new Vue({ el:'#app', data:{ msg:'0'//預設選中的某一項,值與每一個option的value值對應 } });
Vue中的Class樣式與style樣式動態繫結(動態的優先順序高於原來的)
:class=”{}”或者:class=”[]:
通過:class=”{}”或者:class=”[]來動態的繫結class樣式,與原來的class樣式不衝突。
有兩種方式:
1、物件的方式繫結
2、陣列的方式繫結
<div id="app"> <!--以物件的方式動態繫結class樣式:當flag為true時,z樣式生效。y樣式不生效--> <div class="x" :class="{z:flag,y:false}">我的世界</div> <!--以陣列的方式動態繫結class樣式:y,z兩個樣式都會生效--> <div class="x" :class="[y,z]">我的世界</div> </div> let vm=new Vue({ el:'#app', data:{ flag:true } });
:style=”{}”或者:style=”[]”:繫結行內的樣式
通過上述的方式來動態繫結行內的樣式
<div id="app"> //第一種是物件的方式 <div :style="{backgroundColor:'red',color:'pink'}">我是誰</div> //第二種是陣列的方式 <div :style="[str1,str2]">我的世界</div> </div> let vm=new Vue({ el:'#app', data:{ str1:{backgroundColor:'blue'}, str2:{color:'yellow'} } });
根據hash實現單頁面開發
通過hash記錄跳轉的路徑(可以產生歷史管理)
瀏覽器自帶的歷史管理方法history(history.pushState(),push到哪裡就跳轉到哪裡),可能會導致404錯誤(因為使用者可能會隨意輸入路徑)
開發時使用hash的方式,上線的時候使用history的方式
[使用hash儲存]
//儲存:儲存的時候要把儲存的物件轉換成字串 localStorage.setItem('todo',JSON.stringify(obj)); //獲取:獲取的時候要把字串轉換成物件 JSON.parse(localStorage.getItem('todo'));