本節目錄
直接上圖吧:
1.首頁:
2.免費課程頁
還有比如全部里面有個django框架學習,點擊進去,具體的信息展示和課程套餐選擇等功能
3.登陸頁
還有購物車添加成功提示,更新成功提示,當然這些都是前端根據后端的代碼邏輯來寫的,咱們所說的這些功能都是根據業務需求來寫的,不是固定的。
加入購物車成功之后,去結算
4.支付功能:
5.后端數據分析
智能題庫,像我們說的這些功能,需要的數據,都是我們應該現在后端數據庫里面設計好表結構之后,再保存提取出來的數據,所以以后我們寫功能的時候,UI做好功能圖之后,其實第一步應該是按照功能設計數據庫表結構
我們打開瀏覽器控制台你看看這個頁面的ajax請求,看看請求的接口是什么樣的,這些接口我們會通過后面要學的djangorestframework來寫,我們看看接口api(url)的寫法,訪問一下這個接口,看看返回給我們json數據是個什么樣子的
像這種api接口,按說都應該會看,拿到接口大概就知道這個接口是干什么的。
好,大概就看看這些,簡單知道一些功能就行了,我們就開始寫。
首先我們先找一些圖片:別光看圖昂
然后我們寫一下輪播圖,先看目錄結構
看代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test vue</title> </head> <body> <div id="app"> <!-- 1.取圖片數據,可以這樣取 --> <!--<img :src="imgs[0].imgSrc" alt="">--> <!-- 2.讓數據動態起來,放個data里面的屬性或者說是變量 --> <!--<img :src="imgs[currentIndex].imgSrc" alt="">--> <!-- 3.給img綁定個click事件--> <img :src="imgs[currentIndex].imgSrc" alt="" @click="imgHandler"> <button @click="prevHandler">上一張</button> <button @click="nextHandler">下一張</button> </div> <script src="vue.js"></script> <script> // 可以有返回值,我們一般給Vue實例起的變量名都叫vm let vm = new Vue({ el:'#app', data(){ return{ //這些數據按說都是后端給的,我們先寫死了,只要看效果,至於怎么獲取后端的數據,后面學習再說 imgs:[ {id:1,imgSrc:'./img/1.jpg'}, {id:2,imgSrc:'./img/2.jpg'}, {id:3,imgSrc:'./img/3.jpg'}, {id:4,imgSrc:'./img/4.jpg'}, ], currentIndex:0, //默認選中第一張 } }, //通過下面的操作你會發現,完全不需要你自己寫dom操作,更改數據就完成了圖片的切換 methods:{ //上一張的點擊事件 prevHandler(){ this.currentIndex--; //判斷一下,如果currentIndex的值小於等於了0,那么讓他顯示第一張 if (this.currentIndex <= 0){ this.currentIndex = 0; } }, //下一張的點擊事件 nextHandler(){ //讓currentIndex的值自動加一,然后數據驅動視圖,那么html中的img標簽里面那個src就變成了下一張圖片的數據 this.currentIndex++; //判斷一下,如果currentIndex的值等於了所有圖片的個數,那么讓他顯示第一張 if (this.currentIndex === this.imgs.length){ this.currentIndex = 0; } }, //給圖片綁定click事件 imgHandler(e){ //還記得這個可寫可不寫的事件對象e嗎,或者寫event console.log(e); //事件對象,MouseEvent {isTrusted: true, screenX: 141, screenY: 187, clientX: 141, clientY: 96, …} 鼠標事件對象(點擊事件屬於鼠標事件對象) console.log(e.target); //當前事件的標簽對象,<img src="./img/1.jpg" alt="">點擊的當前標簽對象 console.log(this);//在vue這個對象里面,這個this表示的當前的vue對象,其實不一定就是這個vue對象,其中涉及到了vue的繼承性,關於繼承性的簡單解釋,看一下下面的圖解吧 } } }) </script> </body> </html>
vue的繼承性:
下面我們來看一個自動播放圖片的效果,類似輪播圖的效果:注意自己把圖片准備好,我下面的這些圖片都是200*200的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test vue</title> </head> <body> <div id="app"> <img :src="imgs[currentIndex].imgSrc" alt="" @click="imgHandler"> <button @click="prevHandler">上一張</button> <button @click="nextHandler">下一張</button> </div> <script src="vue.js"></script> <!-- 引入jquery,我們操作一下ajax --> <script src="jquery.js"></script> <script> // 可以有返回值,我們一般給Vue實例起的變量名都叫vm let vm = new Vue({ el:'#app', data(){ return{ imgs:[ {id:1,imgSrc:'./img/1.jpg'}, {id:2,imgSrc:'./img/2.jpg'}, {id:3,imgSrc:'./img/3.jpg'}, {id:4,imgSrc:'./img/4.jpg'}, ], currentIndex:0, //默認選中第一張 } }, methods:{ prevHandler(){ this.currentIndex--; if (this.currentIndex <= 0){ this.currentIndex = 0; } }, nextHandler(){ this.currentIndex++; if (this.currentIndex === this.imgs.length){ this.currentIndex = 0; } }, imgHandler(e){ console.log(e); console.log(e.target); console.log(this); } }, //Vue對象稱為一個最大的組件,而這個created方法是組件創建完成后自動執行的內容,通過這個方法我們可以發送ajax請求,其實這個created方法稱為vue的鈎子函數,后面我們會細說vue里面的這些鈎子函數 created(){ //注意this的指向問題,我們下面看看關於this指向的問題及處理方式 // console.log(this); //打印的是當前的vue對象 // setInterval(function () { // console.log(this) //當前setInterval對象的父級對象,此時也就是我們的window對象,Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …},但是我們現在的場景來看,我們更加希望的是這個this是我們當前的vue對象,因為我們要通過這個vue對象操作這個對象里面封裝的數據屬性,那么計時器里面的function就不能這么寫了,下面有兩種寫法 // },2000); //方法一 setInterval(() => { //使用箭頭函數,就能將this指向定義這個setInterval方法的父級對象,還記得嗎,箭頭函數,更改this的指向,那么此時定義這個方法的父級對象就是我們的Vue對象,這是一種改變this指向的方法,下面還有一種方法 // console.log(this) //vue對象 //執行下一頁操作 this.currentIndex++; if (this.currentIndex === this.imgs.length){ this.currentIndex = 0; } },2000); //方法二,就是通過一個變量保存我們當前的vue對象,然后在函數里面用這個變量去操作vue對象里面的內容 // let _this = this; // setInterval(function() { // console.log(_this) //當前vue對象 // },2000) } }) </script> </body> </html>
我們通過ajax做一些東西,其實前端往后端去請求數據實現局部刷新的方式有很多(原生js的XMLHttpRequest,簡稱XHR,還有jQuery的$.ajax(),還有后面要學的axios,還有一個fetch等等都可以發送ajax請求,都可以做請求數據局部刷新的效果。)
上面的這個列表的數據其實是從后端接口請求來的,我們也去請求一下這個接口,首先我們先找到這個接口
這樣看這些數據不太好看,我們找個在線的json數據查看工具,看一看這些數據,首先copy一下這些數據,然后找個在線json數據查看器
但是你對比着看一下,這個全部說明是前端做的,不是后端給的數據,大家記者昂,不一定前端頁面上所有的數據都是后端給的,看你們的業務
好,數據找到了,那我們就來寫寫我們的代碼
看代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test vue</title> </head> <body> <div id="app"> <div> <!-- 6.循環數據生成標簽,打開頁面你就看到效果了,你會發現少個全部那個標簽功能,所以我們想辦法把它加上,怎么加呢,給categoryList添加一個數據不就行了嗎 --> <span v-for="(value,index) in categoryList" :key="value.id"> <!-- 為什么用id,因為我們其實網站上還有其他的操作要和后端進行交互,通過id值來查找數據,這個說的遠了點 --> {{ value.name }} </span> </div> </div> <script src="vue.js"></script> <!-- 引入jquery,我們操作一下ajax --> <script src="jquery.js"></script> <script> // 可以有返回值,我們一般給Vue實例起的變量名都叫vm let vm = new Vue({ el:'#app', data(){ return{ categoryList:[] //1.提前准備一個空數組放這里,后面我們把通過ajax獲取來的數據放進來 } }, methods:{ }, //2.寫個鈎子函數created created(){ //3. 寫ajax去請求數據(其實除了用jQuery的ajax,還有其他的方式,我們后面再說) $.ajax({ //注意昂,人家的接口返回的數據結構可能會發生變化,所以下面的內容要以人家現在接口返回的數據結構基礎上來進行操作,我下面這個可能不是人家現在最新的數據結構了。 url:'https://www.luffycity.com/api/v1/course_sub/category/list/', type:'get', //如果請求成功執行下面的函數 // success:function (data) { 不用這個了,我們用箭頭函數,因為要改this的指向,讓this指向我們的vue對象,才能通過this來操作vue對象里面的數據屬性 success: (data) => { //4. 寫箭頭函數 // console.log(data); //數據就有了,這打印出來是個object對象,這個對象里面有個data屬性,data屬性對應的值就是我們想要的數據,我們在瀏覽器控制台是可以看到的,這個object對象還有個error_no屬性,這個屬性是后端返回的數據獲取成功的一個標志,所以我們也判斷一下 if (data.error_no === 0){ // 5. 請求接口,獲取數據,把數據賦值給vue對象data()方法里面的categoryList let allData = data.data; console.log(allData); //打印一下你會發現它的數據結構就是一個數組套字典,js里稱為自定義對象 // 既然如此,我們直接把這個數據賦值給vue對象里面的data()方法里面的return值里面的那個categoryList就行了,還要注意一點,如果你的數據寫道這里發現出不來,你要想一下this的執行問題,所以我們先打印一下this,看看指向的是誰 // console.log(this);//你會發現這個this是ajax對象,所以我們要改為箭頭函數,然后再打印這個this,就指向我們的vue對象了,那么通過vue對象就能操作下面的數據了 this.categoryList = allData; // 8. 將'全部'那個標簽頁添加到數據里面,id給個0,這個id給多少其實是要和后端配合好的,后端說你給0,將來你點擊這個全部標簽頁的時候,后端通過id=0這個參數數據,就把所有的數據都返回給你 this.categoryList.unshift({"id":0,"name":'全部',"category":0}); } }, //如果請求出現錯誤,執行這個error對應的函數 error:function () { } }) } }) </script> </body> </html>
我們通過上面接口獲取的數據結構是這樣的,但是你發現少個全部頁,所以我們按照下面人家的這個數據結構來添加一組數據,上面的代碼中已經寫了,大家應該看到了。
下面我們來一個給標簽添加css樣式,並且添加點擊事件的一段代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test vue</title> <style> .active{ background-color: dodgerblue; } </style> </head> <body> <div id="app"> <div> <!-- 綁定點擊事件,將index作為參數傳給事件函數 --> <span @click="handlerClick(index)" v-for="(value,index) in categoryList" :key="value.id" :class="{active:index==currentIndex}"><!-- 通過class值來給標簽加樣式,注意寫法{active:true或者false,或者得到true或者false的運算式} --> {{ value.name }} </span> </div> </div> <script src="vue.js"></script> <script src="jquery.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return{ categoryList:[], currentIndex:0, } }, methods:{ handlerClick(index){ //把渲染span標簽時for循環的index傳過來,通過index值來動態更改currentIndex的值,達到一個點擊哪個標簽哪個標簽就有.active類值css樣式的效果 this.currentIndex = index; } }, created(){ $.ajax({ url:'https://www.luffycity.com/api/v1/course_sub/category/list/', type:'get', success: (data) => { if (data.error_no === 0){ let allData = data.data; this.categoryList = allData; this.categoryList.unshift({"id":0,"name":'全部',"category":0}); } }, error:function () { } }) } }) </script> </body> </html>
圖解一下上面這個代碼
接下來我們升級下我們的代碼,再加一些功能,下面這個我更新了,網址接口不再是上面的那個路徑規則了,后端返回的數據也不再是上面的數據結構了
通過這些數據,我們來渲染成下面的效果
你想,我們拿到了數據,通過我們的前端知識是不是就能搞定這樣的頁面了啊,哈哈,所以我只寫一下獲取數據的操作,看代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test vue</title> <style> .active{ background-color: dodgerblue; } </style> </head> <body> <div id="app"> <div> <!-- 綁定點擊事件,將index和數據的id作為參數傳給事件函數 --> <span @click="handlerClick(index,value.id)" v-for="(value,index) in categoryList" :key="value.id" :class="{active:index==currentIndex}"><!-- 通過class值來給標簽加樣式,注意寫法{active:true或者false,或者得到true或者false的運算式} --> {{ value.name }} </span> </div> </div> <script src="vue.js"></script> <script src="jquery.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return{ categoryList:[], currentIndex:0, } }, methods:{ handlerClick(index,id){ //把渲染span標簽時for循環的index傳過來,通過index值來動態更改currentIndex的值,達到一個點擊哪個標簽哪個標簽就有.active類值css樣式的效果 this.currentIndex = index;
//這里大家知道一下可以通過ajax來獲取數據,之后我們學一個新的東西叫做axios,來發送ajax請求,現在寫的是jQuery的ajax請求 $.ajax({ url:`https://www.luffycity.com/api/v1/courses/?sub_category=${id}&ordering=`, type:'get', success:(data) =>{ var all_data = data.data; console.log(all_data); //打印出來的就是我們想要的數據 } }) } }, created(){ $.ajax({ url:'https://www.luffycity.com/api/v1/course_sub/category/list/', type:'get', success: (data) => { if (data.error_no === 0){ let allData = data.data; this.categoryList = allData; this.categoryList.unshift({"id":0,"name":'全部',"category":0}); } }, error:function () { } }) } }) </script> </body> </html>
大家先去現在一個mp3音樂文件,然后放到我們的目錄里面,一會使用,先告訴大家在頁面上播放音樂的標簽的使用
看我的目錄結構,audio標簽播放音樂
我們搞幾個音樂,和音樂的描述信息,然后通過這些內容來搞音樂盒,看代碼,其中有個audio標簽和audio的一些屬性,和ended事件
音樂盒音樂文件下載地址:
下載鏈接:https://pan.baidu.com/s/1EXjTh-oj4b3-skN5WFQKeA
提取碼:eoj5
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .active{ background-color: red; } </style> </head> <body> <div id="music"> <!-- 顯示mq3音樂的標簽,其中controls屬性是顯示播放控件的(暫停、開始什么的),autoplay屬性是讓它自動播放的,loop是播放完之后再自動播放,相當於循環播放一首歌,單曲循環,ended的事件是音樂播放完之后觸發的事件 --> <!--<audio :src="musicData[currentIndex].songSrc" controls autoplay loop @ended="nextHandler"></audio>--> <!-- 寫了ended事件,就別寫loop屬性了,不然不執行ended的事件 --> <audio :src="musicData[currentIndex].songSrc" controls autoplay @ended="nextHandler"></audio> <!-- ul標簽用來顯示音樂的一些描述信息 --> <ul> <!-- --> <li @click="songHandler(index)" v-for="(item,index) in musicData" :key="item.id" :class="{active:index===currentIndex}"> <h2>歌手:{{ item.author }}</h2> <p>歌名:{{ item.name }}</p> </li> </ul> </div> <script src="vue.js"></script> <script> //先准備一些音樂的數據 var allMusicData = [ { id: 1, name: '於榮光 - 少林英雄', author: '於榮光', songSrc: './static/於榮光 - 少林英雄.mp3' }, { id: 2, name: 'Joel Adams - Please Dont Go', author: 'Joel Adams', songSrc: './static/Joel Adams - Please Dont Go.mp3' }, { id: 3, name: 'MKJ - Time', author: 'MKJ', songSrc: './static/MKJ - Time.mp3' }, { id: 4, name: 'Russ - Psycho (Pt. 2)', author: 'Russ', songSrc: './static/Russ - Psycho (Pt. 2).mp3' } ]; new Vue({ el:'#music', data(){ return{ musicData:[], currentIndex:0, //這個不是后端給的,這個是前端來控制的,默認播放第一首歌 } }, //點擊li標簽,播放對應的歌曲 methods:{ songHandler(index){ this.currentIndex = index; }, nextHandler(){ this.currentIndex++; if (this.currentIndex >= this.musicData.length){ this.currentIndex = 0; } } }, created(){ //讓this的musicData等於我們上面的數據,按說這應該是后端給的動態數據 this.musicData = allMusicData } //然后什么點擊上一首下一首的操作會不會啦,是不是點擊按鈕控制currentIndex的值就可以了,自己搞定吧,另外還有什么單曲循環(找個變量一直保存着這個currentIndex的值),還有什么隨機播放,搞一個random隨機值,讓currentIndex的隨機改變,還有順序播放等,自動播放下一首的操作需要我們看一下audio標簽的事件控制方法了,看看下面的圖,找到audio標簽的事件屬性 }) </script> </body> </html>
找audio標簽的事件屬性:
audio的事件屬性里面有個onended事件,可以做音樂播放完了之后觸發的事件
官網是這么說的:
模板內的表達式,就是那個{{ }},非常便利,但是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護。例如:
<div id="example"> {{ message.split('').reverse().join('') }} </div>
在這個地方,模板不再是簡單的聲明式邏輯。你必須看一段時間才能意識到,這里是想要顯示變量 message
的翻轉字符串。當你想要在模板中多次引用此處的翻轉字符串時,就會更加難以處理。
再比如說,你發布一些文章,前端顯示的時候顯示個剛剛或者兩天前發布或者30天前發布等內容,而后端給你的就是個日期數據,那你就需要做一些復雜的運算,如果都寫在模板語法里面,顯得過於復雜,也就是過重。
而我們模板語法里面其實就是要個返回值,所以,對於任何復雜邏輯,你都應當使用計算屬性,來幫你計算這些復雜的操作。
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { /就是這個computed // 計算屬性的 getter reversedMessage: function () { // `this` 指向 vm 實例 return this.message.split('').reverse().join('') } } })
補充個問題昂,如果你在瀏覽器調試台console的地方看到下面的內容:
再說這個computed之前,我們先學一下watch(就是官網說的v-watch)偵聽器,看代碼:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <p>{{ msg }}</p> <p>{{ age }}</p> <!--下面這種寫法是一個簡單的寫法,點擊一下就將msg的值變為Jaden,支持這種寫法,我們還是用我們熟悉的寫法吧 --> <!--<button @click="msg='Jaden'">修改</button>--> <button @click="clickHandler">修改</button> </div> <script src="vue.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return{ msg:'chao', age:18 } }, methods:{ clickHandler(){ this.msg = 'Jaden'; //這個數據一旦發生變化,下面的watch立馬監聽到,然后執行msg對應的那個函數 this.age = 28; } }, //監聽器 watch:{ //這個msg就是上面的data里面的msg屬性,監聽着msg 'msg':function (value) { console.log(value); //Jaden 這就是msg變化后的那個值 if (value === 'Jaden'){ this.msg = '牛x的Jaden'; } }, //可以監聽多個屬性就這樣一個一個寫,聲明多個屬性的監聽,vue的計算屬性比這個watch要友好,既可以監聽單個,又可以監聽多個,然后我們接着學計算屬性 'age':function (v) { if (v === 28){ this.age = 88; } } } }) </script> </body> </html>
下面我們學一下計算屬性,看代碼:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <!--使用computed監聽就不需要寫下面這兩個了--> <!--<p>{{ msg }}</p>--> <!--<p>{{ age }}</p>--> <!--只需要寫上你computed里面的自己寫的那個聲明的方法--> <p>{{ myMsg }}</p> <!--下面這種寫法是一個簡單的寫法,點擊一下就將msg的值變為Jaden,支持這種寫法,我們還是用我們熟悉的寫法吧 --> <!--<button @click="msg='Jaden'">修改</button>--> <button @click="clickHandler">修改</button> </div> <script src="vue.js"></script> <script> let vm = new Vue({ el:'#app', data(){ return{ msg:'chao', age:18 } }, methods:{ //有些朋友對this的指向不是很清晰,我在這里再說一下,單體模式方式1和方式2,this都是指的當前vue對象,而方式3箭頭函數,這種方式this指向的是定義這個箭頭函數的vue對象的父級對象,也就是window對象,所以methods一般不用箭頭函數,看下面的created()方法 //方式1 clickHandler(){ this.msg = 'Jaden'; //這個數據一旦發生變化,下面的watch立馬監聽到,然后執行msg對應的那個函數 this.age = 28; }, // 方式2 // clickHandler:function(){ // this.msg = 'Jaden'; //這個數據一旦發生變化,下面的watch立馬監聽到,然后執行msg對應的那個函數 // this.age = 28; // }, // //方式3 // clickHandler:()=>{ // this.msg = 'Jaden'; //這個數據一旦發生變化,下面的watch立馬監聽到,然后執行msg對應的那個函數 // this.age = 28; // } }, // created(){ //而這種定時器方法本身就是一個方法,是window對象調用的方法,這時的this指的是window對象,所以我們使用定時器方式2箭頭函數的寫法來改變this的指向,讓其是使用上下文的this,其實內部是通過es6的bind方法改變的,了解一下就行了,這時就指向了我們的當前vue對象 //定時器方式1 // setInterval(function () { // // },2000); // //定時器方式2 // setInterval( () => { // // },2000) // }, //this指向總結:像這種create(){}屬於vue對象里面的方法,里面使用其他方法的時候,比如說定時器,ajax等里面還嵌套了其他函數,那么需要使用箭頭函數,像methods和computed這種屬性(鍵值對)對應的大括號里面的方法中使用this都指向的是當前vue對象,如果使用箭頭函數,那么this的指向發生變化會指向window對象,所以不要在這里面寫箭頭函數 //計算屬性 computed:{ //屬性名隨便起,我寫了個myMsg,這叫聲明一個方法,里面有個返回值 myMsg:function () { //這里面寫業務邏輯 //計算屬性默認只有getter方法,getter方法的意思就是我們在下面只是用屬性,不給屬性賦值(this.msg='xxx'這種操作),並且有返回值,后面我們再說一個setter方法,給屬性賦值的操作,這里我想做什么呢,想同時監聽上面data方法里面的msg和age屬性 return `我的名字叫做${this.msg},年齡是${this.age}`;//監聽了兩個屬性 } } }) </script> </body> </html>
關於this的指向問題,也vm實例沒有任何關系,而是與箭頭函數和普通函數的區別。總結下面兩點:
1.es5的普通函數,this指向是指向了調用者,比如vue實例的方法(methods中聲明的一個方法)是由vue實例vm調用的,所以this指向vm,vm實例中定義的單體模式的函數,和es5的普通函數一樣,this指向調用者vm。
2.箭頭函數的this指向它的調用者所在的上下文(資料上箭頭函數沒有this,其實意思箭頭函數中不使用指向調用者的this,而是使用上下文中的this,可以理解為這個函數外層中的this),也就是vm實例所在的上下文(定義vm實例的父類對象),即window對象。
3.后面加上第三方庫的時候,還需要看一下this的指向問題,this指向問題比較坑,很多種情況,所以遇到了我們再看
我們把計算屬性應用到我們上面寫的那個音樂盒實例里面:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .active{ background-color: red; } </style> </head> <body> <div id="music"> <!-- 之前的寫法 --> <!--<audio :src="musicData[currentIndex].songSrc" controls autoplay @ended="nextHandler"></audio>--> <!-- 直接使用計算屬性來監聽musicData和currentIndex的值 --> <audio :src="currentSong" controls autoplay @ended="nextHandler"></audio> <ul> <!-- --> <li @click="songHandler(index)" v-for="(item,index) in musicData" :key="item.id" :class="{active:index===currentIndex}"> <h2>歌手:{{ item.author }}</h2> <p>歌名:{{ item.name }}</p> </li> </ul> </div> <script src="vue.js"></script> <script> //先准備一些音樂的數據 var allMusicData = [ { id: 1, name: '於榮光 - 少林英雄', author: '於榮光', songSrc: './static/於榮光 - 少林英雄.mp3' }, { id: 2, name: 'Joel Adams - Please Dont Go', author: 'Joel Adams', songSrc: './static/Joel Adams - Please Dont Go.mp3' }, { id: 3, name: 'MKJ - Time', author: 'MKJ', songSrc: './static/MKJ - Time.mp3' }, { id: 4, name: 'Russ - Psycho (Pt. 2)', author: 'Russ', songSrc: './static/Russ - Psycho (Pt. 2).mp3' } ]; new Vue({ el:'#music', data(){ return{ musicData:[], currentIndex:0, //這個不是后端給的,這個是前端來控制的,默認播放第一首歌 } }, computed:{ currentSong(){ return this.musicData[this.currentIndex].songSrc } }, //點擊li標簽,播放對應的歌曲 methods:{ songHandler(index){ this.currentIndex = index; }, nextHandler(){ this.currentIndex++; if (this.currentIndex >= this.musicData.length){ this.currentIndex = 0; } } }, created(){ this.musicData = allMusicData } }) </script> </body> </html>
圖解上面的代碼
簡單總結一下
watch:監聽單個屬性
computed:可同時監聽多個屬性,主要產生緩存的數據屬性,改變這個數據屬性的時候,直接拿緩存中數據進行更改,主要作用是為了減少dom操作造成的性能消耗。
對於初學者來說,以后你用vue開發,直接就把這些方法都寫上,即便是暫時用不到,里面不寫任何內容,也沒關系,不會報錯,但是對你自己來說可以給你一個提示的作用。
后面的學習我們會用到vue的這個擴展程序,所以大家下載一下。
先搞個vpn,翻牆,然后在瀏覽器上添加下面這個擴展程序,檢測調試vue開發的網頁,或者你用火狐瀏覽器,火狐應該不用翻牆。
vpn工具下載地址:鏈接:https://pan.baidu.com/s/1szO56suw3e3YnFFnXXcEgA 提取碼:1x72
添加成功之后,在瀏覽器上就會看到這個圖標,如果這個網站的頁面使用vue開發的,那么這個圖標就是亮的,如果不是就是暗色的。
vue官網和餓了么官網等都是vue開發的,大家可以打開看看
打開我們之前用vue寫的網頁,你打開瀏覽器調試台,就會看到vue調試工具,里面可以檢測我們寫的vue的基本上所以內容
你里面的數據發生變化,這里立馬就能監測到,上面這個root是根標簽,然后你在vue里面聲明的所有屬性,這里都有,都可以在這里調試。