最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Vue全套視頻教程vite版,Vue2+Vue3快速上手,一套通透

2023-04-10 15:01 作者:山藥當(dāng)當(dāng)  | 我要投稿

老杜Vue學(xué)習(xí)筆記

第二章 Vue 核心技術(shù)

2.1 事件處理

2.1.1 事件處理的核心語法

(1) 指令的語法格式:<標(biāo)簽 v-指令名:參數(shù)=”表達(dá)式”></標(biāo)簽>

(2) 事件綁定的語法格式:v-on:事件名。例如鼠標(biāo)單擊事件的綁定使用 v-on:click。

(3) 綁定的回調(diào)函數(shù)需要在 Vue 實例中使用 methods 進(jìn)行注冊。methods 可以配置多個回調(diào)函數(shù),采用逗號隔開。

(4) 綁定回調(diào)函數(shù)時,如果回調(diào)函數(shù)沒有參數(shù),( )可以省略。

(5) 每一個回調(diào)函數(shù)都可以接收一個事件對象 event。

(6) 如果回調(diào)函數(shù)有參數(shù),并且還需要獲取事件對象,可以使用$event 進(jìn)行占位。

(7) v-on:click 可以簡寫為@click。簡寫的語法格式:@事件名

(8) 回調(diào)函數(shù)中的 this 是 vm。如果回調(diào)函數(shù)是箭頭函數(shù)的話,this 是 window 對象,因為箭頭函數(shù)沒有自己的 this,它的 this 是繼承過來的,默認(rèn)這個 this 是箭頭函數(shù)所在的宿主對象。這個宿主對象其實就是它的父級作用域。

而對象又不能構(gòu)成單獨的作用域,所以這個父級作用域是全局作用域,也就是 window。

(9) 回調(diào)函數(shù)并沒有在 vm 對象上,為什么通過 vm 可以直接調(diào)用函數(shù)呢?嘗試手寫 Vue 框架。

(10) 可以在函數(shù)中改變 data 中的數(shù)據(jù),例如:this.counter++,這樣會聯(lián)動頁面上產(chǎn)生動態(tài)效果。

2.1.2 事件修飾符

(1) .stop - 調(diào)用 event.stopPropagation()。

1. <div @click="san">

2.<div @click.stop="er">

3.<button @click="yi">{{name}}</button>

4.</div>

5. </div>

(2) .prevent - 調(diào)用 event.preventDefault()。

1. <a href="http://www.bjpowernode.com" @click.prevent="yi">

2. {{name}}

3. </a>

(3) .capture - 添加事件偵聽器時使用 capture 模式。

1. <div @click.capture="san">

2.<div @click.capture="er">

3.<button @click="yi">{{name}}</button>

4.</div>

5. </div>

注意:只有添加了 capture 修飾符的元素才會采用捕獲模式。(或者說帶有 capture 修飾符的優(yōu)先觸發(fā))

(4) .self - 只當(dāng)事件是從偵聽器綁定的元素本身觸發(fā)時才觸發(fā)回調(diào)。

1. <div @click="san">

2.<div @click.self="er">

3.<button @click="yi">{{name}}</button>

4.</div>

5. </div>

(5) .once - 只觸發(fā)一次回調(diào)。

1. <button @click.once="yi">

2.{{name}}

3. </button>

(6) .passive - (2.3.0) 以 { passive: true } 模式添加偵聽器

①無需等待,直接繼續(xù)(立即)執(zhí)行事件默認(rèn)行為。(對 wheel 事件有效果)

②.passive 和 .prevent 修飾符不能共存。

2.1.3 按鍵修飾符

1. 常用的按鍵修飾符包括:

(1) .enter

(2) .tab (只能配合 keydown 使用)

(3) .delete (捕獲“刪除”和“退格”鍵)

(4) .esc

(5) .space

(6) .up

(7) .down

(8) .left

(9) .right

2. 可以直接將 KeyboardEvent.key 暴露的任意有效按鍵名轉(zhuǎn)換為 kebab-case 來作為修飾符。

<input type=”text” @keyup.page-down=”getInfo”>

3. 可以通過全局 config.keyCodes 對象自定義按鍵修飾符別名

Vue.config.keyCodes.huiche = 13

2.1.4 系統(tǒng)修飾鍵

1. 系統(tǒng)修飾鍵包括 4 個

(1) .ctrl

(2) .alt

(3) .shift

(4) .meta

2. 系統(tǒng)修飾鍵在使用時應(yīng)注意:

(1) 只有當(dāng)系統(tǒng)修飾鍵和其他鍵組合使用,并且組合鍵釋放時,才會觸發(fā) keyup 事件。

(2) 只要按下系統(tǒng)修飾鍵,就會觸發(fā) keydown 事件。

3. 小技巧

(1) <input type=”text” @keyup.ctrl.c=”getInfo”/>

2.2 計算屬性

1. 案例:用戶輸入信息,然后翻轉(zhuǎn)用戶輸入的字符串。

(1) 插值語法可以實現(xiàn),但是有三個問題

1、代碼可讀性差

2、代碼不可復(fù)用

3、代碼難以維護(hù)

(2) 可以使用 methods 方式實現(xiàn),存在 1 個問題

1、效率低,即使數(shù)據(jù)沒有發(fā)生變化,但每一次仍然會調(diào)用 method。

(3) 使用計算屬性可以解決以上問題。

2. 什么是計算屬性?

data 中的是屬性。用 data 的屬性經(jīng)過計算得出的全新的屬性就是計算屬性。

3. 計算屬性的使用

1. <div id="app">

2.<h1>{{msg}}</h1>

3.輸入的信息:<input type="text" v-model="info"><br>

4.反轉(zhuǎn)的信息:{{reversedInfo}} <br>

5.反轉(zhuǎn)的信息:{{reversedInfo}} <br>

6.反轉(zhuǎn)的信息:{{reversedInfo}} <br>

7.反轉(zhuǎn)的信息:{{reversedInfo}} <br>

8. </div>

9. <script>

10.const vm = new Vue({

11.el : '#app',

12.data : {

13.msg : '計算屬性-反轉(zhuǎn)字符串案例',

14.info : ''

15.},

16.computed : {

17.reversedInfo:{

18.get(){

19.console.log('getter 被調(diào)用了');

20.return this.info.split('').reverse().join('')

21.},

22.set(val){

23.//this.reversedInfo = val // 不能這樣做,這樣會導(dǎo)致無限遞歸

24.this.info = val.split('').reverse().join('')

25.}

26.}

27.}

28.})

29. </script>

(1) 計算屬性需要使用:computed

(2) 計算屬性通過 vm.$data 是無法訪問的。計算屬性不能通過 vm.$data 訪問。

(3) 計算屬性的 getter/setter 方法中的 this 是 vm。

(4) 計算屬性的 getter 方法的調(diào)用時機(jī):

①第一個時機(jī):初次訪問該屬性。

②第二個時機(jī):計算屬性所依賴的數(shù)據(jù)發(fā)生變化時。

(5) 計算屬性的 setter 方法的調(diào)用時機(jī):

①當(dāng)計算屬性被修改時。(在 setter 方法中通常是修改屬性,因為只有當(dāng)屬性值變化時,計算屬性的值就會聯(lián)動更新。注意:計算屬性的值被修改并不會聯(lián)動更新屬性的值。)

(6) 計算屬性沒有真正的值,每一次都是依賴 data 屬性計算出來的。

(7) 計算屬性的 getter 和 setter 方法不能使用箭頭函數(shù),因為箭頭函數(shù)的 this 不是 vm。而是 window。

4. 計算屬性的簡寫形式

只考慮讀取,不考慮修改時,可以啟用計算屬性的簡寫形式。

1. computed : {

2.reversedInfo(){

3.console.log('getter 被調(diào)用了');

4.return this.info.split('').reverse().join('')

5.}

6. }

2.3 偵聽屬性的變化

1. 偵聽屬性的變化其實就是監(jiān)視某個屬性的變化。當(dāng)被監(jiān)視的屬性一旦發(fā)生改變時,執(zhí)行某段代碼。

2. 監(jiān)視屬性變化時需要使用 watch 配置項。

使用 watch 實現(xiàn):比較數(shù)字大小的案例

1. <div id="app">

2.<h1>{{msg}}</h1>

3.數(shù)值 1:<input type="text" v-model="number1"><br>

4.數(shù)值 2:<input type="text" v-model="number2"><br>

5.比較大小:{{compareResult}}

6. </div>

7. <script>

8.const vm = new Vue({

9.el : '#app',

10.data : {

11.msg : '偵聽屬性的變化',

12.number1 : 1,

13.number2 : 1,

14.compareResult : ''

15.},

16.watch : {

17.number1 : {

18.immediate : true,

19.handler(newVal, oldVal){

20.let result = newVal - this.number2

21.if(result > 0){

22.this.compareResult = newVal + '>' + this.number2

23.}else if(result < 0){

24.this.compareResult = newVal + '<' + this.number2

25.}else{

26.this.compareResult = newVal + '=' + this.number2

27.}

28.}

29.},

30.number2 : {

31.immediate : true,

32.handler(newVal, oldVal){

33.let result = this.number1 - newVal

34.if(result > 0){

35.this.compareResult = this.number1 + '>' + newVal

36.}else if(result < 0){

37.this.compareResult = this.number1 + '<' + newVal

38.}else{

39.this.compareResult = this.number1 + '=' + newVal

40.}

41.}

42.}

43.}

44.})

45. </script>

運行效果:



3. 如何深度監(jiān)視:

(1) 監(jiān)視多級結(jié)構(gòu)中某個屬性的變化,寫法是:’a.b.c’ : {}。注意單引號哦。

(2) 監(jiān)視多級結(jié)構(gòu)中所有屬性的變化,可以通過添加深度監(jiān)視來完成:deep : true

4. 如何后期添加監(jiān)視:

(1) 調(diào)用 API:vm.$watch(‘number1’, {})

5. watch 的簡寫:

(1) 簡寫的前提:當(dāng)不需要配置 immediate 和 deep 時,可以簡寫。

(2) 如何簡寫?

①watch:{ number1(newVal,oldVal){}, number2(newVal, oldVal){} }

(3) 后期添加的監(jiān)視如何簡寫?

①vm.$watch(‘number1’, function(newVal, oldVal){})

6. computed 和 watch 如何選擇?

(1) 以上比較大小的案例可以用 computed 完成,并且比 watch 還要簡單。所以要遵守一個原則:computed

和 watch 都能夠完成的,優(yōu)先選擇 computed。

(2) 如果要開啟異步任務(wù),只能選擇 watch。因為 computed 依靠 return。watch 不需要依賴 return。

7. 關(guān)于函數(shù)的寫法,寫普通函數(shù)還是箭頭函數(shù)?

(1) 不管寫普通函數(shù)還是箭頭函數(shù),目標(biāo)是一致的,都是為了讓 this 和 vm 相等。

(2) 所有 Vue 管理的函數(shù),建議寫成普通函數(shù)。

(3) 所有不屬于 Vue 管理的函數(shù),例如 setTimeout 的回調(diào)函數(shù)、Promise 的回調(diào)函數(shù)、AJAX 的回調(diào)函數(shù),

建議使用箭頭函數(shù)。

2.4 class 與 style 綁定

數(shù)據(jù)綁定的一個常見需求場景是操縱元素的 CSS class 列表和內(nèi)聯(lián)樣式。因為 class 和 style 都是 attribute,我們

可以和其他 attribute 一樣使用 v-bind 將它們和動態(tài)的字符串綁定。但是,在處理比較復(fù)雜的綁定時,通過拼接

生成字符串是麻煩且易出錯的。因此,Vue 專門為 class 和 style 的 v-bind 用法提供了特殊的功能增強(qiáng)。除了字

符串外,表達(dá)式的值也可以是對象或數(shù)組。

2.4.1 class 綁定

2.4.1.1 綁定字符串

適用于樣式的名字不確定,需要動態(tài)指定。

1. <!DOCTYPE html>

2. <html lang="en">

3. <head>

4.<meta charset="UTF-8">

5.<title>class 綁定字符串形式</title>

6.<script src="../js/vue.js"></script>

7.<style>

8..static{

9.border: 1px solid black;

10.background-color: beige;

11.}

12..big{

13.width: 200px;

14.height: 200px;

15.}

16..small{

17.width: 100px;

18.height: 100px;

19.}

20.</style>

21.</head>

22.<body>

23.<div id="app">

24.<h1>{{msg}}</h1>

25.<div class="static" :class="c1"></div>

26.</div>

27.<script>

28.const vm = new Vue({

29.el : '#app',

30.data : {

31.msg : 'class 綁定字符串形式',

32.c1 : 'small'

33.}

34.})

35.</script>

36.</body>

37.</html>

運行效果:

使用 vue 開發(fā)者工具修改 c1 的 small 為 big:

通過測試可以看到樣式完成了動態(tài)的切換。

2.4.1.2 綁定數(shù)組

適用于綁定的樣式名字不確定,并且個數(shù)也不確定。

1. <!DOCTYPE html>

2. <html lang="en">

3. <head>

4.<meta charset="UTF-8">

5.<title>class 綁定數(shù)組形式</title>

6.<script src="../js/vue.js"></script>

7.<style>

8..static{

9.border: 1px solid black;

10.}

11..active{

12.background-color: green;

13.}

14..text-danger{

15.color: red;

16.}

17.</style>

18.</head>

19.<body>

20.<div id="app">

21.<h1>{{msg}}</h1>

22.<div class="static" :class="['active','text-danger']">

數(shù)組形式</div>

23.<br><br>

24.<div class="static" :class="[activeClass,errorClass]">

數(shù)組形式</div>

25.<br><br>

26.<div class="static" :class="classArray">數(shù)組形式</div>

27.</div>

28.<script>

29.const vm = new Vue({

30.el : '#app',

31.data : {

32.msg : 'class 綁定數(shù)組形式',

33.activeClass : 'active',

34.errorClass : 'text-danger',

35.classArray : ['active', 'text-danger']

36.}

37.})

38.</script>

39.</body>

40.</html>

運行效果:

使用 vue 開發(fā)者工具刪除數(shù)組中的一個樣式:

2.4.1.3 綁定對象

適用于樣式名字和個數(shù)都確定,但是要動態(tài)決定用或者不用。

1. <!DOCTYPE html>

2. <html lang="en">

3. <head>

4.<meta charset="UTF-8">

5.<title>class 綁定對象形式</title>

6.<script src="../js/vue.js"></script>

7.<style>

8..static{

9.border: 1px solid black;

10.}

11..active{

12.background-color: green;

13.}

14..text-danger{

15.color: red;

16.}

17.</style>

18.</head>

19.<body>

20.<div id="app">

21.<h1>{{msg}}</h1>

22.<div class="static" :class="{active : true, 'text-dang

er' : true}">對象形式</div>

23.<br><br>

24.<div class="static" :class="classObject">對象形式

</div>

25.</div>

26.<script>

27.const vm = new Vue({

28.el : '#app',

29.data : {

30.msg : 'class 綁定對象形式',

31.classObject : {

32.active : true,

33.text-danger' : false

34.}

35.}

36.})

37.</script>

38.</body>

39.</html>

運行效果:

使用 vue 開發(fā)者工具修改 text-danger 為 true:

2.4.2 style 綁定

2.4.2.1 綁定對象

1. <div id="app">

2.<h1>{{msg}}</h1>

3.<!-- 靜態(tài)寫法 -->

4.<div class="static" style="font-size: 20px;">對象形式

</div><br><br>

5.<!-- 動態(tài)寫法 1 -->

6.<div class="static" :style="{fontSize: 40 + 'px'}">對象形式

</div><br><br>

7.<!-- 動態(tài)寫法 2 -->

8.<div class="static" :style="styleObject">對象形式

</div><br><br>

9. </div>

10.<script>

11.const vm = new Vue({

12.el : '#app',

13.data : {

14.msg : 'style 綁定對象形式',

15.styleObject : {

16.fontSize : '40px'

17.}

18.}

19.})

20.</script>

2.4.2.2 綁定數(shù)組

1. <div id="app">

2.<h1>{{msg}}</h1>

3.<!-- 靜態(tài)寫法 -->

4.<div class="static" style="font-size: 40px; color: red;">數(shù)

組形式</div><br><br>

5.<!-- 動態(tài)寫法 1 -->

6.<div class="static" :style="[{fontSize:'40px'},{color:'red

'}]">數(shù)組形式</div><br><br>

7.<!-- 動態(tài)寫法 2 -->

8.<div class="static" :style="styleArray">對象形式

</div><br><br>

9. </div>

10.<script>

11.const vm = new Vue({

12.el : '#app',

13.data : {

14.msg : 'style 綁定對象形式',

15.styleArray : [

16.{fontSize:'40px'},

17.{color:'red'}

18.]

19.}

20.})

21.</script>

2.5 條件渲染

2.5.1 v-if

指令用于條件性地渲染一塊內(nèi)容。這塊內(nèi)容只會在指令的表達(dá)式返回 true 時才被渲染

1. <div id="app">

2.<h1>{{msg}}</h1>

3.溫度:<input type="number" v-model="temprature"><br>

4.天氣:

5.<span v-if="temprature <= 10">寒冷</span>

6.<span v-if="temprature > 10 && temprature <= 25">涼爽

</span>

7.<span v-if="temprature > 25">炎熱</span>

8. </div>

9. <script>

10.const vm = new Vue({

11.el : '#app',

12.data : {

13.msg : '條件渲染',

14.temprature : 10

15.}

16.})

17.</script>

運行效果:


2.5.2 v-else-if、v-else

顧名思義,v-else-if 提供的是相應(yīng)于 v-if 的“else if 區(qū)塊”。它可以連續(xù)多次重復(fù)使用。

一個使用 v-else-if 的元素必須緊跟在一個 v-if 或一個 v-else-if 元素后面。

你也可以使用 v-else 為 v-if 添加一個“else 區(qū)塊”,當(dāng)然,v-else 元素也是必須緊跟在一個 v-if 或一個 v-else-if 元素

后面。

1. <div id="app">

2.<h1>{{msg}}</h1>

3.溫度:<input type="number" v-model="temprature"><br>

4.天氣:

5.<span v-if="temprature <= 10">寒冷</span>

6.<span v-else-if="temprature <= 25">涼爽</span>

7.<span v-else>炎熱</span>

8. </div>

9. <script>

10.const vm = new Vue({

11.el : '#app',

12.data : {

13.msg : '條件渲染',

14.temprature : 10

15.}

16.})

17.</script>

2.5.3 <template>與 v-if

因為 v-if 是一個指令,他必須依附于某個元素。但如果我們想要切換不止一個元素呢?在這種情況下我們可以在一個 <template> 元素上使用 v-if,這只是一個不可見的包裝器元素,最后渲染的結(jié)果并不會包含個 <template> 元素。v-else 和 v-else-if 也可以在 <template> 上使用。

1. <div id="app">

2.<h1>{{msg}}</h1>

3.溫度:<input type="number" v-model="temprature"><br>

4.天氣:

5.<template v-if="temprature <= 10">

6.<span>寒冷</span>

7.</template>

8.<template v-else-if="temprature <= 25">

9.<span>涼爽</span>

10.</template>

11.<template v-else>

12.<span>炎熱</span>

13.</template>

14.</div>

15.<script>

16.const vm = new Vue({

17.el : '#app',

18.data : {

19.msg : '條件渲染',

20.temprature : 10

21.}

22.})

23.</script>

2.5.4 v-show

另一個可以用來按條件顯示一個元素的指令是 v-show。其用法基本一樣:

1. <div id="app">

2.<h1>{{msg}}</h1>

3.溫度:<input type="number" v-model="temprature"><br>

4.天氣:

5.<span v-show="temprature <= 10">寒冷</span>

6.<span v-show="temprature > 10 && temprature <= 25">涼爽

</span>

7.<span v-show="temprature > 25">炎熱</span>

8. </div>

9. <script>

10.const vm = new Vue({

11.el : '#app',

12.data : {

13.msg : '條件渲染',

14.temprature : 10

15.}

16.})

17.</script>

不同之處在于 v-show 會在 DOM 渲染中保留該元素;v-show 僅切換了該元素上名為 display 的 CSS 屬性。

v-show 不支持在 <template> 元素上使用,也不能和 v-else 搭配使用。

2.5.5 v-if VS v-show

v-if 是“真實的”按條件渲染,因為它確保了在切換時,條件區(qū)塊內(nèi)的事件監(jiān)聽器和子組件都會被銷毀與重建

v-if 也是惰性的:如果在初次渲染時條件值為 false,則不會做任何事。條件區(qū)塊只有當(dāng)條件首次變?yōu)?true 時才被渲染。

相比之下,v-show 簡單許多,元素?zé)o論初始條件如何,始終會被渲染,只有 CSS display 屬性會被切換。

總的來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要頻繁切換,則使用 v-show 較好;如果在運行時綁定條件很少改變,則 v-if 會更合適。

2.6 列表渲染

語法格式:v-for 指令。該指令用在被遍歷的標(biāo)簽上。

1. v-for="(element, index) in elements" :key="element.id"

或者

1.v-for="(element, index) of elements" :key="element.id"

2.6.1 遍歷數(shù)組、對象、字符串、指定次數(shù)

1. 遍歷數(shù)組

1. <div id="app">

2.<h1>{{msg}}</h1>

3.<h2>遍歷數(shù)組</h2>

4.<ul>

5.<li v-for="(product, index) in products" :key="product.

id">

6.商品名稱:{{product.name}},單價:{{product.price}}元/

千克,下標(biāo):{{index}}

7.</li>

8.</ul>

9. </div>

10.<script>

11.const vm = new Vue({

12.el : '#app',

13.data : {

14.msg : '列表渲染',

15.products : [

16.{id:'111',name:'西瓜',price:20},

17.{id:'222',name:'蘋果',price:10},

18.{id:'333',name:'香蕉',price:30}

19.]

20.}

21.})

22.</script>

運行效果:

2. 遍歷對象

1. <div id="app">

2.<h1>{{msg}}</h1>

3.<h2>遍歷對象</h2>

4.<ul>

5.<li v-for="(propertyValue, propertyName) of dog" :key=

"propertyName">

6.{{propertyName}}:{{propertyValue}}

7.</li>

8.</ul>

9. </div>

10.<script>

11.const vm = new Vue({

12.el : '#app',

13.data : {

14.msg : '列表渲染',

15.dog : {

16.name : '拉布拉多',

17.age : 3,

18.gender : '雄性'

19.}

20.}

21.})

22.</script>

運行結(jié)果:

3. 遍歷字符串

1. <div id="app">

2.<h1>{{msg}}</h1>

3.<h2>遍歷字符串</h2>

4.<ul>

5.<li v-for="char,index of str" :key="index">

6.{{index}}:{{char}}

7.</li>

8.</ul>

9. </div>

10.<script>

11.const vm = new Vue({

12.el : '#app',

13.data : {

14.msg : '列表渲染',

15.str : '動力節(jié)點'

16.}

17.})

18.</script>

運行結(jié)果:

4. 遍歷指定次數(shù)

1. <div id="app">

2<h1>{{msg}}</h1>

3.<h2>遍歷指定次數(shù)</h2>

4.<ul>

5.<li v-for="number,index of 10" :key="index">

6.下標(biāo):{{index}},數(shù)字:{{number}}

7.</li>

8.</ul>

9. </div>

10.<script>

11.const vm = new Vue({

12.el : '#app',

13.data : {

14.msg : '列表渲染'

15.}

16.})

17.</script>

運行結(jié)果:

2.6.2 虛擬 dom 和 diff 算法

所謂的虛擬 dom 就是內(nèi)存當(dāng)中的 dom 對象。vue 為了提高渲染的效率,只有真正改變的 dom 元素才會重新渲染。

2.6.3 v-for 的 key 的作用以及實現(xiàn)原理

1. 用 index 作為 key

1. <!DOCTYPE html>

2. <html lang="en">

3. <head>

4.<meta charset="UTF-8">

5.<title>key 的原理</title>

6.<script src="../js/vue.js"></script>

7. </head>

8. <body>

9.<div id="app">

10.<h1>{{msg}}</h1>

11.<button @click="addFirst">在數(shù)組第一個位置添加 tom</button>

12.<button @click="addLast">在數(shù)組最后位置添加 vue</button>

13.<table>

14.<tr>

15.<th>序號</th>

16.<th>姓名</th>

17.<th>郵箱</th>

18.<th>選擇</th>

19.</tr>

20.<tr v-for="(vip,index) of vips" :key="index">

21.<td>{{index + 1}}</td>

22.<td>{{vip.name}}</td>

23.<td>{{vip.email}}</td>

24.<td><input type="checkbox"></td>

25.</tr>

26.</table>

27.</div>

28.<script>

29.const vm = new Vue({

30.el : '#app',

31.data : {

32.msg : 'key 原理(虛擬 dom 與 diff 算法)',

33.vips : [

34.{id:'100',name:'jack',email:'jack@123.com'},

35.{id:'200',name:'lucy',email:'lucy@123.com'},

36.{id:'300',name:'james',email:'james@123.com'}

37.]

38.},

39.methods : {

40.addFirst(){

41.this.vips.unshift({id:'400',name:'tom',email:'tom@123.com'})

42.},

43.addLast(){

44.this.vips.push({id:'500',name:'vue',email:'vue@123.com'})

45.}

46.}

47.})

48.</script>

49. </body>

50. </html>

運行效果:

全部選中:

添加 tom:

可以看到錯亂了。思考這是為什么?

2. 用 vip.id 作為 key

運行和測試結(jié)果正常,沒有出現(xiàn)錯亂。為什么?

3. key 的作用

key 存在于虛擬 dom 元素中,代表該虛擬 dom 元素的唯一標(biāo)識(身份證號)。

4. diff 算法是如何比較的?

新的虛擬 dom 和舊的虛擬 dom 比較時,先拿 key 進(jìn)行比較:

(1) 如果 key 相同:則繼續(xù)比較子元素:

①子元素不同:直接將新的虛擬 dom 元素渲染到頁面生成新的真實 dom 元素。

②子元素相同:直接復(fù)用之前的真實 dom。

(2) 如果 key 不同:直接將新的虛擬 dom 元素渲染到頁面生成新的真實 dom 元素。

5. index 作為 key 存在兩個問題

(1) 效率較低。

(2) 對數(shù)組的非末尾元素進(jìn)行增刪時,容易錯亂。

6. index 作為 key 和 vip.id 作為 key 對比

當(dāng) index 作為 key 時:

當(dāng) vip.id 作為 key 時:

2.7 列表過濾

使用 watch 和 computed 分別進(jìn)行實現(xiàn):

1. <!DOCTYPE html>

2. <html lang="en">

3. <head>

4.<meta charset="UTF-8">

5.<title>列表過濾</title>

6.<script src="../js/vue.js"></script>

7.<style>

8.table,tr,th,td{

9.border: 1px solid blue;

10.}

11.</style>

12.</head>

13.<body>

14.<div id="app">

15.<h1>{{msg}}</h1>

16.<input type="text" placeholder="請輸入搜索關(guān)鍵詞

" v-model="keyword">

17.<table>

18.<tr>

19.<th>序號</th>

20.<th>姓名</th>

21.<th>郵箱</th>

22.</tr>

23.<tr v-for="(vip,index) of filterVips" :key="vip.id

">

24.<td>{{index+1}}</td>

25.<td>{{vip.name}}</td>

26.<td>{{vip.email}}</td>

27.</tr>

28.</table>

29.</div>

30.<script>

31.const vm = new Vue({

32.el : '#app',

33.data : {

34.keyword : '',

35.msg : '列表過濾',

36.vips : [

37.{id:'100',name:'jack',email:'jack@123.com'}

,

38.{id:'200',name:'lucy',email:'lucy@123.com'}

,

39.{id:'300',name:'james',email:'james@123.co

m'}

40.],

41.//filterVips : []

42.},

43./* watch : {

44.keyword : {

45.immediate : true,

46.handler(newValue, oldValue){

47.this.filterVips = this.vips.filter((v)

=> {

48.return v.name.indexOf(newValue) >=

0

49.})

50.}

51.}

52.}, */

53.computed : {

54.filterVips(){

55.return this.vips.filter((v) => {

56.return v.name.indexOf(this.keyword) >=

0

57.})

58.}

59.}

60.})

61.</script>

62.</body>

63.</html>

2.8 列表排序

1. <!DOCTYPE html>

2. <html lang="en">

3. <head>

4.<meta charset="UTF-8">

5.<meta http-equiv="X-UA-Compatible" content="IE=edge">

6.<meta name="viewport" content="width=device-width, initial-scale=1.0">

7.<title>列表排序</title>

8.<script src="../js/vue.js"></script>

9.<style>

10.table,tr,td,th{

11.border:1px solid black;

12.}

13.</style>

14. </head>

15. <body>

16.<div id="app">

17.<h1>{{msg}}</h1>

18.<input type="text" placeholder="輸入關(guān)鍵字搜索" v-model="keyword"><br>

19.<button @click="type = 1">按照名字升序</button><br>

20.<button @click="type = 2">按照名字降序</button><br>

21.<button @click="type = 0">按照名字原始順序</button><br>

22.<table>

23.<tr>

24.<th>序號</th>

25.<th>姓名</th>

26.<th>郵箱</th>

27.<th>操作</th>

28.</tr>

29.<tr v-for="(vip, index) in filterVips" :key="vip.id">

30.<td>{{index+1}}</td>

31.<td>{{vip.name}}</td>

32.<td>{{vip.email}}</td>

33.<td><input type="checkbox"></td>

34.</tr>

35.</table>

36.</div>

37.<script>

38.const vm = new Vue({

39.el : '#app',

40.data : {

41.msg : '列表排序',

42.vips : [

43.{id:'100',name:'jack',email:'jack@123.com'},

44.{id:'200',name:'lucy',email:'lucy@123.com'},

45.{id:'300',name:'james',email:'james@123.com'},

46.{id:'400',name:'lilei',email:'lilei@123.com'},

47.],

48.keyword : '',

49.type : 0

50.},

51.computed : {

52.filterVips(){

53.// 篩選

54.let arr = this.vips.filter((vip) => {

55.return vip.name.indexOf(this.keyword) >= 0

56.})

57.// 根據(jù)排序類型進(jìn)行排序

58.if(this.type){

59.arr.sort((v1, v2) => {

60.console.log('@')

61.return this.type == 1 ? v1.name.localeCompare(v2.name) : v2.nam

e.localeCompare(v1.name)

62.})

63.}

64.// 返回

65.return arr

66.}

67.}

68.})

69.</script>

70. </body>

71.</html>


Vue全套視頻教程vite版,Vue2+Vue3快速上手,一套通透的評論 (共 條)

分享到微博請遵守國家法律
会东县| 安吉县| 临漳县| 武威市| 东乡族自治县| 科技| 公主岭市| 盐城市| 元阳县| 甘洛县| 黔西| 嘉义县| 紫云| 务川| 京山县| 遵义县| 德州市| 岚皋县| 宜黄县| 马公市| 武定县| 康乐县| 旌德县| 崇仁县| 大理市| 裕民县| 栾城县| 铜山县| 绵阳市| 沂源县| 武乡县| 凤翔县| 宝鸡市| 宜君县| 木兰县| 将乐县| 余庆县| 仙游县| 黔西县| 乌拉特前旗| 博爱县|