目錄
- 1.頁面樣式綁定:
- 1.概述:
- 2.綁定方式:
- 1.通過類名綁定:
- 1.通過動態類名綁定:(:class)
- 2.通過類名數組綁定:
- 3.通過類名對象進行綁定:
- 2.內聯樣式綁定:(:sytle)
- 1.通過樣式對象語法綁定:
- 2.通過樣式數組語法綁定:
- 2.條件渲染:
- 1.概述:
- 2.語法:
- 3.使用方法:
- 4.注意事項;
- 3.列表渲染
- 1.概述:
- 2.語法:
- 3.使用:
- 1.遍歷數組:
- 2.遍歷對象:
- 3.遍歷字符串:
- 4.遍歷次數:
- 4.key的原理:
- 1.案例:
- 2:總結:
- key的作用:
- 1.虛擬DOM中key 的作用: key作為虛擬DOM的標識。
- 2.index能否作為key?
- 3.圖示:
1.頁面樣式綁定:
1.概述:
頁面樣式綁定在 Vue 中是一種將樣式與數據動態關聯起來的方式,使得頁面的樣式可以根據數據的變化而自動更新。
2.綁定方式:
1.通過類名綁定:
1.通過動態類名綁定:(:class)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>
<!--準備樣式 -->//基礎樣式:寬400,長100,實線黑色邊框(寬1).basic {width: 400px;height: 100px;border: 1px solid black;}//容器1樣式:實線紅色邊框,寬4,容器背景漸變色.box1 {border: 4px solid red;/*background-color: rgba(255, 255, 0, 0.6);*/background: linear-gradient(30deg, yellow, pink, orange, yellow);}//容器2樣式:虛線邊框,寬4,邊框顏色rgb,容器背景灰色.box2 {border: 4px dashed rgb(2, 197, 2);background-color: gray;}//容器3樣式:容器背景藍色.box3 {background-color: skyblue;}//容器4樣式:容器背景黃綠色.box4 {background-color: yellowgreen;}// //容器5樣式:字體大小30,為字體添加陰影效果.box5 {font-size: 30px;text-shadow: 2px 2px 10px red;}//容器6樣式:設置邊框圓角.box6 {border-radius: 20px;}</style>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><div class="basic" :class="classStr">{{name}}</div>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {name: '猿究院',classStr: 'box2',}}}).$mount("#root");
</script>
</body>
</html>
上面案例中我們定義了一些樣式,并在div子容器中通過指令語法動態綁定了data屬性中的對應屬性,實現了將data屬性值對應的容器樣式動態的綁定到了div子容器中(注意在div子容器綁定樣式時有兩個類名,實際上他們對應的樣式效果是疊加的)實際樣式效果如下所示:
2.通過類名數組綁定:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>
<!--準備樣式 -->//基礎樣式:寬400,長100,實線黑色邊框(寬1).basic {width: 400px;height: 100px;border: 1px solid black;}//容器1樣式:實線紅色邊框,寬4,容器背景漸變色.box1 {border: 4px solid red;/*background-color: rgba(255, 255, 0, 0.6);*/background: linear-gradient(30deg, yellow, pink, orange, yellow);}//容器2樣式:虛線邊框,寬4,邊框顏色rgb,容器背景灰色.box2 {border: 4px dashed rgb(2, 197, 2);background-color: gray;}//容器3樣式:容器背景藍色.box3 {background-color: skyblue;}//容器4樣式:容器背景黃綠色.box4 {background-color: yellowgreen;}// //容器5樣式:字體大小30,為字體添加陰影效果.box5 {font-size: 30px;text-shadow: 2px 2px 10px red;}//容器6樣式:設置邊框圓角.box6 {border-radius: 20px;}</style>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><div class="basic" :class="classArr">{{name}}</div>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {name: '猿究院',classArr: ['box4', 'box5', 'box6'],}}}).$mount("#root");
</script>
</body>
</html>
上面案例中通過類名數組動態綁定多個類對應的容器樣式,再將這些容器樣式進行疊加后綁定到div子容器中,最終div子容器的樣式效果如下所示:
3.通過類名對象進行綁定:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>
<!--準備樣式 -->//基礎樣式:寬400,長100,實線黑色邊框(寬1).basic {width: 400px;height: 100px;border: 1px solid black;}//容器1樣式:實線紅色邊框,寬4,容器背景漸變色.box1 {border: 4px solid red;/*background-color: rgba(255, 255, 0, 0.6);*/background: linear-gradient(30deg, yellow, pink, orange, yellow);}//容器2樣式:虛線邊框,寬4,邊框顏色rgb,容器背景灰色.box2 {border: 4px dashed rgb(2, 197, 2);background-color: gray;}//容器3樣式:容器背景藍色.box3 {background-color: skyblue;}//容器4樣式:容器背景黃綠色.box4 {background-color: yellowgreen;}// //容器5樣式:字體大小30,為字體添加陰影效果.box5 {font-size: 30px;text-shadow: 2px 2px 10px red;}//容器6樣式:設置邊框圓角.box6 {border-radius: 20px;}</style>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><div class="basic" :class="classObject">{{name}}</div>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {name: '猿究院',classObject: {box1: true,box5: true,box3: false},}}}).$mount("#root");
</script>
</body>
</html>
在此案例中我們通過類對象進行樣式綁定,在data中定義一個ClassObiect的對象,此對象的每個屬性都表示一個容器樣式的容器名,值為布爾值,true表示啟用該容器樣式,false則表示不用,最終div子容器樣式效果如下所示:
2.內聯樣式綁定:(:sytle)
1.通過樣式對象語法綁定:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>
<!--準備樣式 -->//基礎樣式:寬400,長100,實線黑色邊框(寬1).basic {width: 400px;height: 100px;border: 1px solid black;}//容器1樣式:實線紅色邊框,寬4,容器背景漸變色.box1 {border: 4px solid red;/*background-color: rgba(255, 255, 0, 0.6);*/background: linear-gradient(30deg, yellow, pink, orange, yellow);}//容器2樣式:虛線邊框,寬4,邊框顏色rgb,容器背景灰色.box2 {border: 4px dashed rgb(2, 197, 2);background-color: gray;}//容器3樣式:容器背景藍色.box3 {background-color: skyblue;}//容器4樣式:容器背景黃綠色.box4 {background-color: yellowgreen;}// //容器5樣式:字體大小30,為字體添加陰影效果.box5 {font-size: 30px;text-shadow: 2px 2px 10px red;}//容器6樣式:設置邊框圓角.box6 {border-radius: 20px;}</style>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><div class="basic" :style="styleObject">{{name}}</div>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {name: '猿究院',styleObject: {fontSize: '40px',color: 'red'},}}}).$mount("#root");
</script>
</body>
</html>
說明:此時通過內聯式綁定樣式效果,在data的styleObject對象中就不能在寫容器樣式對應的容器名了,而要寫具體的樣式效果。并且由于內聯式級別高于類選擇器,因此basic的樣式效果會被覆蓋。此時div子容器的樣式效果如下圖所示:
2.通過樣式數組語法綁定:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>
<!--準備樣式 -->//基礎樣式:寬400,長100,實線黑色邊框(寬1).basic {width: 400px;height: 100px;border: 1px solid black;}//容器1樣式:實線紅色邊框,寬4,容器背景漸變色.box1 {border: 4px solid red;/*background-color: rgba(255, 255, 0, 0.6);*/background: linear-gradient(30deg, yellow, pink, orange, yellow);}//容器2樣式:虛線邊框,寬4,邊框顏色rgb,容器背景灰色.box2 {border: 4px dashed rgb(2, 197, 2);background-color: gray;}//容器3樣式:容器背景藍色.box3 {background-color: skyblue;}//容器4樣式:容器背景黃綠色.box4 {background-color: yellowgreen;}// //容器5樣式:字體大小30,為字體添加陰影效果.box5 {font-size: 30px;text-shadow: 2px 2px 10px red;}//容器6樣式:設置邊框圓角.box6 {border-radius: 20px;}</style>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><div class="basic" :style="styleArr">{{name}}</div>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {name: '猿究院',styleArr: [{fontSize: '40px',color: 'blue'},{backgroundColor: 'yellowgreen'}]}}}).$mount("#root");
</script>
</body>
</html>
說明:此時通過樣式數組進行樣式效果綁定,將樣式效果以數組的形式進行定義,最終疊加綁定到div子容器上,注意:basic樣式仍會被覆蓋;
2.條件渲染:
1.概述:
在vue中通過v-if,v-else-if,v-else等語句進行條件判斷當前內容是否執行渲染展示
2.語法:
v-if='條件1'.....v-else-if='條件2'....v-else-if='條件3'..........v-else ........
3.使用方法:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>當前count的值是:{{count}}</h2><button @click="count++">點擊count++</button><div v-if="count==1">v-if....</div><div v-else-if="count==2">v-else-if ....</div><div v-else-if="count==3">v-else-if ....</div><div v-else>v-else ....</div></div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {count: 0}}}).$mount("#root");
</script>
</body>
</html>
說明:上述案例中通過v-if,v-else-if,v-else對變量count的值進行判斷,根據count的不同值,在頁面渲染展示不同的內容
4.注意事項;
-
v-if 指令會移除當條件不滿足時頁面的DOM元素;
-
v-else-if指令執行過程中不能被其他業務中斷,否則中斷之后的邏輯判斷不再執行;
-
v-if指令適合執行內容隱藏-顯示切換頻率不高的場景,如果切換頻率較高,則應使用v-show指令,因為v-show指令不會刪除不滿足條件的DOM元素,而是會將其通過CSS隱藏起來,因此效率比較高;
3.列表渲染
1.概述:
列表渲染主要是通過v-for指令對數組,對象,字符串等數據進行遍歷;
2.語法:
v-for="(item,index) in 遍歷對象" :key='對象的鍵'
3.使用:
1.遍歷數組:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><!-- 遍歷數組 --><ul><!-- v-for :key--><!-- item 循環的每一個值,index 下標 --><!-- <li v-for="item in persons">--><li v-for="(item,index) in persons" :key="item.id">{{index}}-{{item.name}}-{{item.age}}</li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {persons: [{id: '001', name: '張三', age: 20},{id: '002', name: '李四', age: 22},{id: '003', name: '王武 ', age: 18}],}}}).$mount("#root");
</script>
</body>
</html>
說明:上面案例中我們使用v-for指令對person數組進行遍歷展示,注意我們的key在選擇時使用的時元素的id,而沒有使用元素在數組中的下標index,主要是為了保證它的唯一性,當使用index作為key時,再執行一些逆序操作時可能會存在一些問題;
2.遍歷對象:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><!-- 遍歷對象 --><ul><!-- (item 值,index 屬性名) --><li v-for="(item,index) in numbers" :key="index">{{index}}-{{item}}</li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {numbers: {a: 1,b: 2,c: 3},}}}).$mount("#root");
</script>
</body>
</html>
3.遍歷字符串:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><!-- 遍歷字符串 --><ul><!-- (item 字符,index 下標) --><li v-for="(item,index) in str" :key="index">{{index}}-{{item}}</li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {str: 'hello'}}}).$mount("#root");
</script>
</body>
</html>
4.遍歷次數:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root">
<!-- 遍歷固定次數 --><ul><!-- (item 次數,index 下標) --><li v-for="(item,index) in 5" :key="index">{{index}}-{{item}}</li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {}}}).$mount("#root");
</script>
</body>
</html>
4.key的原理:
1.案例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>人員列表</h2><button @click="add">添加老劉到列表中</button><ul><li v-for="(item,index) in persons" :key="index">{{index}}-{{item.name}}-{{item.age}}<input type="text"/></li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {persons: [{id: '001', name: '張三', age: 20},{id: '002', name: '李四', age: 22},{id: '003', name: '王武 ', age: 18}]}},methods: {add() {this.persons.unshift({id: '004', name: '老劉 ', age: 25}) //插入到第一個元素位置}}}).$mount("#root");
</script>
</body>
</html>
上面案例中我們給按鈕綁定了一個事件,當事件觸發時,會添加老劉的信息到對象數組中,再通過v-for指令來遍歷對象數組,此時的key為下標index
點擊按鈕,觸發事件,將老劉添加到首位
通過結果看,似乎沒有問題,但當前面數據后面的文本框內有內容時,還會一一對應嗎
從測試結果來看,出現了數據錯亂的現象。例如,新添加 “老劉” 到首位后,本應在其后的輸入框為空,但卻顯示了原本張三對應的數據 “1”。這種異常情況主要源于在 `v-for` 遍歷時使用 `index` 作為 `key`。在該案例中,輸入框內容與 `key`(即 `index`)存在綁定關系。初始時,數據 “1” 對應的 `index` 為 0,代表張三。然而,當 “老劉” 添加至首位后,`index` 為 0 的位置被 “老劉” 占據,導致數據與 `index` 的對應關系錯亂,從而引發了上述顯示錯誤。實際上,從虛擬 DOM 的角度深入分析,在理想情況下,僅新增 “老劉” 這一數據時,其余數據未發生實質性改變,不應重新生成新的虛擬 DOM 對象。但由于 Vue 依靠 `key` 來判斷節點身份,在新增數據到數組首位時,其余數據的下標發生改變,也就意味著以 `index` 作為 `key` 時其值發生了變化。此時,Vue 會判定這些節點均為新節點,進而生成新的虛擬 DOM 對象。這不僅會導致如輸入框數據錯亂等顯示問題,而且即使不考慮數據錯亂,這種因 `key` 變化而頻繁生成新虛擬 DOM 對象的情況,會顯著增加 Diff 算法的計算量以及真實 DOM 的更新操作次數。因為每次生成新虛擬 DOM 后,都需要與舊虛擬 DOM 進行全面的差異比對,然后根據比對結果更新真實 DOM,大量不必要的操作嚴重降低了 Vue 的執行效率。綜上所述,在使用 `v-for` 指令遍歷動態數據列表時,強烈建議使用具有唯一性且穩定不變的屬性作為 `key`,避免使用 `index`,以確保數據與 DOM 節點的正確綁定以及 Vue 應用的高效運行。
所以如果將index作為key則不應該進行逆序操作,如下面案例2所示
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>人員列表</h2><button @click="add">添加老劉到列表中</button><ul><li v-for="(item,index) in persons" :key="index">{{index}}-{{item.name}}-{{item.age}}<input type="text"/></li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {persons: [{id: '001', name: '張三', age: 20},{id: '002', name: '李四', age: 22},{id: '003', name: '王武 ', age: 18}]}},methods: {add() {this.persons.push({id: '004', name: '老劉 ', age: 25}) //插入到最后}}}).$mount("#root");
</script>
</body>
</html>
此時我們再添加老劉到最后,再看看數據是否錯亂
此時發現數據是一一對應的,沒有發現錯亂,這是因為我們添加數據到末尾,沒有改變原數據的index,也就不會出現錯亂,同時原數據也不會重新生成虛擬DOM對象,Vue的效率也會相對較高那如果一定要逆序插入數據,但又不想出現上面的問題,那該如何實現呢。要實現這個需求,此時v-for指令中的key就不能是index了,而應該是遍歷的數據中的一個屬性(最好是唯一屬性),如下面案例3所示:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>人員列表</h2><button @click="add">添加老劉到列表中</button><ul><li v-for="(item,index) in persons" :key="item.id">{{index}}-{{item.name}}-{{item.age}}<input type="text"/></li></ul>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {persons: [{id: '001', name: '張三', age: 20},{id: '002', name: '李四', age: 22},{id: '003', name: '王武 ', age: 18}]}},methods: {add() {this.persons.unshift({id: '004', name: '老劉 ', age: 25}) //插入到第一個元素位置}}}).$mount("#root");
</script>
</body>
</html>
此時我們添加老劉到首位,再看看是否可以實現
通過測試結果可以看出,我們成功將老劉添加到了首位,并且數據沒有出現錯亂
在上面的案例中,我們是通過遍歷元素的id為key,因此數據后面的輸入框內容也是和數據id綁定在一起的,所以當我們添加老劉時,并不會改變其余元素的key,因此就可以成功將數據添加到首位,且不會造成數據錯亂
2:總結:
key的作用:
1.虛擬DOM中key 的作用: key作為虛擬DOM的標識。
當數據發生改變時,VUE會根據【新的數據】生成【新的虛擬DOM】,隨后與舊的虛擬DOM進行差異比對1.舊的虛擬DOM中找到了與新的虛擬DOM相同的 key
-
如果虛擬DOM中的內容沒有改變則使用之前的虛擬DOM
-
如果虛擬DOM中的內容改變了,生成新的虛擬DOM,再將虛擬DOM對應得真實DOM中發生改變的部分進行覆蓋
2.如果舊的虛擬DOM中沒有找到與新的虛擬DOM相同的key,創建新的真實DOM 渲染到頁面中
2.index能否作為key?
1.如果對數據進行了逆序的操作(破壞了順序的操作),會產生沒有必要的真實DOM更新2.如果對數據的操作沒有破壞順序,那么就可以使用index作為key