原文:https://www.cnblogs.com/li-li/p/10022288.html
1、es6的語法
一、let與var的區別html
ES6 新增了let命令,用來聲明變量。它的用法相似於var(ES5),可是所聲明的變量,只在let命令所在的代碼塊內有效。以下代碼:前端
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上面代碼在代碼塊之中,分別用let和var聲明瞭兩個變量。而後在代碼塊以外調用這兩個變量,結果let聲明的變量報錯,var聲明的變量返回了正確的值。這代表,let聲明的變量只在它所在的代碼塊有效。vue
for循環的計數器,就很合適使用let命令,以下代碼:react
for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined
上面代碼中,計數器i只在for循環體內有效,在循環體外引用就會報錯。jquery
二、var變量提高現象,以下代碼:git
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
上面代碼中,變量i是var命令聲明的,在全局範圍內都有效,因此全局只有一個變量i。每一次循環,變量i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),裏面的i指向的就是全局的i。也就是說,全部數組a的成員裏面的i,指向的都是同一個i,致使運行時輸出的是最後一輪的i的值,也就是 10。若是使用let,聲明的變量僅在塊級做用域內有效,最後輸出的是 6。es6
三、另外,for循環還有一個特別之處,就是設置循環變量的那部分是一個父做用域,而循環體內部是一個單獨的子做用域。github
for (let i = 0; i < 3; i++) { let i = 'abc'; console.log(i); } // abc// abc// abc
上面代碼正確運行,輸出了 3 次abc。這代表函數內部的變量i與循環變量i不在同一個做用域,有各自單獨的做用域。ajax
四、let不存在變量提高算法
var命令會發生」變量提高「現象,即變量能夠在聲明以前使用,值爲undefined。而let命令改變了語法行爲,它所聲明的變量必定要在聲明後使用,不然報錯。以下代碼:
// var 的狀況 console.log(foo); // 輸出undefined var foo = 2; // let 的狀況 console.log(bar); // 報錯ReferenceError let bar = 2;
上面代碼中,變量foo用var命令聲明,會發生變量提高,即腳本開始運行時,變量foo已經存在了,可是沒有值,因此會輸出undefined。變量bar用let命令聲明,不會發生變量提高。這表示在聲明它以前,變量bar是不存在的,這時若是用到它,就會拋出一個錯誤。
五、let不容許在相同做用域內重複聲明同一個變量,以下代碼:
// 報錯 function func() { let a = 10; var a = 1; } // 報錯 function func() { let a = 10; let a = 1; }
六、ES6還添加了const命令,const聲明一個只讀的常量,一旦聲明,常量的值就不能改變,以下:
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
const聲明的變量不得改變值,這意味着,const一旦聲明變量,就必須當即初始化,不能留到之後賦值。也就是說,const只聲明不賦值,就會報錯。
const的做用域與let命令相同,即只在聲明所在的塊級做用域內生效,不能重複聲明,而且不存在變量提高。
七、ES6模板字符串
模板字符串(template string)是加強版的字符串,用反引號(`)標識。它能夠看成普通字符串使用,也能夠用來定義多行字符串,或者在字符串中嵌入變量。模板字符串中嵌入變量,須要將變量名寫在${}之中。
let name = 'tom'; let str = `我是 ${name}.`
八、變量的解構賦值
ES6 容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構(Destructuring)。
ES6 容許寫成下面這樣:
let [a, b, c] = [1, 2, 3];
上面代碼表示,能夠從數組中提取值,按照對應位置,對變量賦值。
本質上,這種寫法屬於「模式匹配」,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。若是解構不成功,變量的值就等於undefined。
九、函數
(1)es5的普通函數,function聲明函數,以下:
function add(x) { return x; }; add(10); // 10
(2)函數對象的寫法,以下:
let add = function (x) { return x; }; add(10); // 10
(3)es6箭頭函數,以下:
let add = (x) => { return x; }; add(10) // 10
(4)上面的箭頭函數可簡寫成以下形式:
let add = x => x; add(10); // 10 // 若是箭頭函數的代碼塊部分多於一條語句,就要使用大括號將它們括起來,而且使用return語句返回。以下: var sum = (num1, num2) => { return num1 + num2; } // 若是箭頭函數直接返回一個對象,必須在對象外面加上括號,不然會報錯。以下: let getTempItem = id => { id: id, name: "Temp" }; // 報錯 let getTempItem = id => ({ id: id, name: "Temp" }); // 不報錯
十、es6的對象(this指向問題)
(1)匿名函數中this指向
// 字面量方式聲明一個對象person let person = { name: "tom", age: 30, fav: function () { console.log(this); // this指向 當前的調用者person對象 console.log(this.name); } }; person.fav() // {name: "tom", age: 30, fav: ƒ} // tom
(2)對象的單體模式,本質與上個示例同樣:
let person = { name: "tom", age: 30, fav(){ console.log(this); // this指向 當前的調用者person對象 console.log(this.name); } }; person.fav() // {name: "tom", age: 30, fav: ƒ} // tom
(3)箭頭函數中this指向
let person = { name: "tom", age: 30, fav: () => { console.log(this); // this指向 person的父級對象(上下文),即window console.log(this.name); } }; person.fav() // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
十一、es6的類
(1)es5
function Person(name, age) { this.name = name; this.age = age; } // 基於原型給對象聲明方法,原型prototype是當前類的父類(繼承性) Person.prototype.showName = function () { console.log(this.name); }; let p1 = new Person('alex', 29); p1.showName() // alex
(2)es6
class Person{ constructor(name='alex', age=29){ // 單體模式 this.name = name; this.age = age; } showname(){ // 單體模式 console.log(this.name); // this指向當前對象Person } showage(){ console.log(this.age); } } let p1 = new Person(); p1.showname(); // alex
2、vue的基本語法
一、vue的介紹
(1)前端三大框架(能夠去github查看三個框架的 star星):
vue 尤雨溪,漸進式的JavaScript框架
react Facebook公司,裏面的(高階函數 es6)很是多,對初學者不友好
angular 谷歌公司,目前更新到6.0,學習angular得須要玩一下typescript
(2)cdn方式引用
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
(3)下載到本地引用
<script src='./vue.js'></script>
(4)庫和框架
上面vue.js文件是一個庫,小而精;
框架是功能比較齊全,像Django,大而全,功能比較多;
(5)實例化對象
示例代碼:
<script src="./vue.js"></script> <script> // 實例化對象 new Vue({ el:"#app", // 這裏data是一個對象,在後續學習中發現data中通常是一個函數 data:{ // 數據屬性 msg1:"黃瓜", person:{ name:"alex" }, msg2:'hello Vue', isShow:'True' }, methods:{ // 該組件中聲明的方法 }, watch:{ // 該組件中監聽的數據屬性 } }); </script>
注意:若是是咱們本身定義的屬性和方法,則所有暴露在外面,若是是vue實例對象本身屬性和方法,會在前邊加一個」$」進行區分。另外,data中有一個觀察者Observer,在觀察着一些數據是否發生了改變,若改變,則將改變後的值立馬渲染到DOM中對應的地方,控制檯查看data效果以下圖:
二、vue的模板語法
<div id="app"> <!--模板語法--> <h2>{{ msg1 }}</h2> <h3>{{ 'haha' }}</h3> <h3>{{ 1+1 }}</h3> <h4>{{ {'name':'alex'} }}</h4> <h5>{{ person.name }}</h5> <h2>{{ 1>2?'真的':'假的' }}</h2> <p>{{ msg2.split('').reverse().join('') }}</p> </div>
三、vue的思想:數據驅動視圖,設計模式MVVM(model view viewmodel)
四、vue的基本指令(使用指令系統後邊必定是字符串,且字符串中的變量必定是數據屬性中已有的變量)
(1)vue的指令系統之v-text和v-html(***),以下:
<div id="content"> {{ msg }} <div v-text="msg"></div> <!-- v-text至關於innerText --> <div v-html="msg"></div> <!-- v-html至關於innerHTML --> </div> <script src="./vue.js"></script> <script> // 實例化對象 new Vue({ el:"#content", // data中是一個函數 函數中return一個對象,能夠是空對象,但不能不return data(){ // 函數的單體模式 return{ msg:"<h2>alex</h2>" } } }); </script>
效果以下圖:
(2)條件渲染v-if和v-show,以下:效果以下圖:
<div class="box1" v-show="isShow">hello</div>
<div class="box2" v-if="isShow">hello</div>
分析:isShow爲真則顯示div,爲假則不顯示;
區別:v-show爲假時至關於display:none;v-if爲假時至關於移除該div,可是有一個佔位的註釋」<!-- -->」;
官網對v-if和v-show的區別:
1)v-if 是「真正」的條件渲染,由於它會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。
2)v-if 也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。
3)相比之下,v-show 就簡單得多——無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS 進行切換。
4)通常來講,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show 較好;若是在運行時條件不多改變,則使用 v-if 較好。
v-if與v-else:可使用 v-else 指令來表示 v-if 的「else 塊」:
<div v-if="Math.random() > 0.5"> Now you see me </div> <div v-else> Now you don't </div> // 注意:v-else 元素必須緊跟在帶 v-if 或者 v-else-if 的元素的後面,不然它將不會被識別。
(3)v-bind和v-on
v-bind:標籤中全部屬性,如img標籤的src alt,a標籤的href title id class等,以下:
<img v-bind:src="imgSrc" v-bind:alt="msg">
v-bind:class='{active:isActive}'表示若isActive(數據屬性中定義的變量)爲真,則對應div增長active類,不然不增長,以下:
<div class="box" v-bind:class='{active:isActive}'></div>
v-on:監聽js中的全部事件,如click,mouseover,mouseout等,以下:
<button v-on:click="clickHandler">切換顏色</button>
v-bind的簡便寫法是":",如:<div class="box" :class='{active:isActive}'></div>
v-on的簡便寫法是"@",如:<button @click="clickHandler">切換顏色</button>
(4)列表渲染v-for(不只能夠遍歷數組,還能夠遍歷對象),以下:
<div id="app"> <ul v-if="res.status === 'ok'"> <!-- v-for的優先級是最高的 diff算法 --> <li v-for='(item,index) in res.users' :key="item.id"> <h3>{{ item.id }} -- {{ item.name }} -- {{ item.age }}</h3> </li> </ul> <div v-for='(value,key) in person'> {{ key }}-----{{ value }} </div> </div> <script src="./vue.js"></script> <script> new Vue({ el:"#app", data(){ return { res: { status: 'ok', users: [ {id: 1, name: 'alex', age: 18}, {id: 2, name: 'wusir', age: 30}, {id: 3, name: 'yuan', age: 48} ] }, person: { name: 'tom' } } }, methods:{ // 該組件中聲明的方法 }, watch:{ // 該組件中監聽的數據屬性 } }); </script>
總結:遍歷數組時,一個參數是值,兩個參數是(值,索引);遍歷對象時,一個參數是值,兩個參數是(值,鍵)。
注意:必定要綁定一個標識(有id就綁定id,沒有id綁定index),則值改變會直接經過key查找,而不用再去遍歷查找,提高效率。
三、Vue應用示例
一、實現輪播圖,代碼以下:


<div id="app"> <img :src="images[currentIndex].imgSrc" @click="imgHandler" alt=""> <br /> <button @click="prevHandler">上一張</button> <button @click="nextHandler">下一張</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> // Vue實例對象,能夠有返回值vm,官網中就是用vm表明Vue實例對象 let vm = new Vue({ el: '#app', data() { return { // 實際項目中images這個數據以及圖片是後端返回過來的 images:[ {id:1, imgSrc:'./images/1.jpg'}, {id:2, imgSrc:'./images/2.jpg'}, {id:3, imgSrc:'./images/3.jpg'}, {id:4, imgSrc:'./images/4.jpg'} ], currentIndex:0 } }, methods:{ nextHandler(){ this.currentIndex++; if(this.currentIndex == 4){ this.currentIndex = 0; } }, prevHandler(){ this.currentIndex--; if(this.currentIndex == -1){ this.currentIndex = 3; } }, imgHandler(e){ console.log(e); // e是當前事件對象 console.log(e.target); // 當前事件對象的目標對象 console.log(this); // this指當前Vue實例對象 } }, // 組件建立完成時調用created函數,可發送ajax created(){ // 注意:開定時器就要清定時器,後面會介紹在destroyed函數中清掉 setInterval(()=>{ // 定時器中若不用箭頭函數則this指則定時器對象 console.log(this); // 這時this指當前Vue實例對象 this.currentIndex++; if(this.currentIndex == 4){ this.currentIndex = 0; } },2000); // 若定時器中不用箭頭函數,也能夠用下面方式 let _this = this; setInterval(function () { console.log(_this); // _this指當前Vue實例對象 },2000) } }) </script>
二、Vue中使用ajax(created是組件建立完成時執行),代碼以下:


<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> span.active{color:red} </style> </head> <body> <div id="app"> <span @click="clickHandler(index, category.id)" v-for="(category,index) in categoryList" :key="category.id" :class="{active:index==currentIndex}"> {{ category.name }} </span> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="jquery.min.js"></script> <script> let vm = new Vue({ el: '#app', data() { return { categoryList:[], currentIndex:0 } }, methods:{ clickHandler(i, id){ this.currentIndex = i; // 發起請求 $.ajax({ url:`https://www.luffycity.com/api/v1/courses/?sub_category=${id}`, type:'get', success:function (res) { console.log(res); } }) } }, // 組件建立完成時調用created函數,可發送ajax created(){ $.ajax({ url:'https://www.luffycity.com/api/v1/course_sub/category/list/', type:'get', success:(res) => { // 若不用箭頭函數,則this指當前ajax對象 console.log(res); // res是請求接口收到的數據 // 根據響應數據的狀態字段判斷是否成功 if(res.error_no === 0){ var data = res.data; this.categoryList = data; // this指當前Vue實例對象 let obj = { id:0, name:'所有', category:0 }; // unshift方法表示在數組前插入一個元素 this.categoryList.unshift(obj) } }, error:function (err) { console.log(err); } }) } }) </script> </body> </html>
頁面運行效果以下圖:
依次點擊每一項,控制檯效果以下圖:
三、實現音樂播放器,代碼以下:


<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .active{color:blue} </style> </head> <body> <div id="music"> <!-- audio 是HTML5的新標籤 --> <!-- @ended 播放完成會自動調用該方法 --> <audio @ended="nextHandler" :src="musicList[currentIndex].songSrc" controls autoplay></audio> <ul> <li @click="songHandler(index)" v-for="(item,index) in musicList" :key="item.id" :class="{active:index==currentIndex}"> <h5>歌名:{{ item.name}}</h5> <p>歌手:{{ item.author}}</p> </li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let musicList = [ { 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 { musicList:[], currentIndex:0 } }, methods:{ songHandler(i){ this.currentIndex = i }, nextHandler(){ this.currentIndex++; if(this.currentIndex == 4){ this.currentIndex = 0; } } }, created(){ // 實際項目中每每向後臺要數據,賦值給數據屬性 this.musicList = musicList } }) </script> </body> </html>
四、Vue基礎知識
一、計算屬性(主要產生緩存的數據屬性,防止DOM性能消耗)
模板內的表達式很是便利,可是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板太重且難以維護。例如:
<div id="example"> {{ message.split('').reverse().join('') }} </div>
在這個地方,模板再也不是簡單的聲明式邏輯。你必須看一段時間才能意識到,這裏是想要顯示變量 message 的翻轉字符串。當你想要在模板中屢次引用此處的翻轉字符串時,就會更加難以處理。因此,對於任何複雜邏輯,你都應當使用計算屬性。例如:
<div id="example"> <p>原數據: "{{ message }}"</p> <p>翻轉後的數據: "{{ reversedMessage }}"</p> </div> var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 計算屬性的 getter(計算屬性默認只有getter方法),計算屬性要有返回值 reversedMessage: function () { return this.message.split('').reverse().join('') // `this`指向vm實例 } } })
二、偵聽器(watch)
雖然計算屬性在大多數狀況下更合適,但有時也須要一個自定義的偵聽器。這就是爲何 Vue 經過 watch 選項提供了一個更通用的方法,來響應數據的變化。當須要在數據變化時執行異步或開銷較大的操做時,這個方式是最有用的。
watch能夠監聽單個屬性,若是想監聽多個屬性,則聲明多個屬性的監聽,以下:
<div id="app"> <p>{{ msg }}</p> <button @click='clickHandler'>修改</button> </div> <script src="vue.js"></script> <script> new Vue({ el:'#app', data(){ return { msg:"alex", age:18 } }, methods:{ clickHandler(){ this.msg = "wusir" } }, watch:{ // 監聽屬性'msg' 'msg':function (value) { console.log(value); if (value === 'wusir'){ this.msg = '大武sir'; } }, // 監聽屬性'age' 'age':function (value) { } } }) </script>
注意:計算屬性便可以監聽單個屬性,又能夠監聽多個屬性,以下示例:
<div id="app"> <p>{{ myMsg }}</p> <button @click='clickHandler'>修改</button> </div> <script src="vue.js"></script> <script> new Vue({ el:'#app', data(){ return { msg:"alex", age:18 } }, methods:{ clickHandler(){ this.msg = "wusir"; this.age = 20; } }, computed:{ myMsg: function () { // 即監聽msg屬性,又監聽age屬性 return `個人名字叫${this.msg},年齡是${this.age}`; } } }) </script>
三、計算屬性的應用(上例中音樂播放器改成計算屬性實現)
修改audio標籤的src屬性值,以下:
<audio @ended="nextHandler" :src="currentSong" controls autoplay></audio>
Vue實例中增長計算屬性computed,以下:
computed:{ currentSong(){ // 既監聽了musicList,又監聽了currentIndex return this.musicList[this.currentIndex].songSrc } }
總結:計算屬性的方法便可以在模板語法中使用,又能夠在指令系統中使用。
四、關於函數中this指向的問題
Vue實例對象中,通常methods和computed中定義的函數中的this是指當前Vue實例對象,而created中的ajax和定時器中定義的函數中的this是指ajax或者定時器對象,這時,ajax和定時器中的函數改成箭頭函數,就能夠改變this的指向,即this指向當前Vue實例對象。
5、補充知識點
一、查看接口,以下圖:
二、json在線格式化工具:http://www.bejson.com/
三、本身查閱資料瞭解js中閉包。