vue中如何實現數據的雙向綁定
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><input type="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'));
