一、ES6常用語法
1、變量的定義
1. 介紹 ES6以前 var關鍵字用來聲明變量,無論聲明在何處都存在變量提升這個事情,會提前創建變量。 作用域也只有全局作用域以及函數作用域,所以變量會提升在函數頂部或全局作用域頂部。 let 關鍵字表示變量,const 表示常量。都是塊級作用域,比如一個函數內部,代碼塊{}內部~ 不會報錯: <script> console.log(age); var age = 18; </script> <script> function f() { console.log(age); if(1){ var age = 1; } } </script> 會報錯: <script> console.log(age); </script> 2. let:塊級作用域,let定義的變量只能作用於一對花括號內{} 會報錯: <script> console.log(age); let age = 18; </script> <script> function f() { console.log(age); if (1) { let age = 1; } } f() </script> 不會報錯: <script> let age = 18; console.log(age); </script> <script> function f() { if (1) { let age = 1; console.log(age); } } f() </script> 3. 修改 var:可以重新定義,也可以重新賦值 let:不可以重新定義,但可以重新賦值 const:不可以重新定義,也不可以重新賦值 不會報錯: <script> var age = 18; var age = 20; </script> <script> var age = 18; age = 20; </script> <script> let age = 18; age = 20; </script> 會報錯: <script> let age = 18; let age = 20; </script> <script> const age = 18; const age = 20; </script> <script> const age = 18; age = 20; </script>
2、模板字符串
1. 語法:反引號`` 2. 變量:${} 3. 相對於普通字符串:模板字符串可以換行,變量可以使用${}來替換 4. 示例 <body> <div id="app"> </div> <script> // 給div添加HTML代碼 let ele = document.getElementById("app"); let hobby1 = "抽煙"; let hobby2 = "打架"; let hobby3 = "看女主播"; ele.innerHTML = `<ul> <li>${hobby1}</li> <li>${hobby2}</li> <li>${hobby3}</li> </ul>` </script> </body> 如果使用普通的字符串:不可以換行,變量不能放在引號里面,因為在引號里面會被解析成普通字符而不是變量 ele.innerHTML = "<ul><li>" + hobby1 + "</li></ul>"
3、箭頭函數
1. 介紹 類比Python的匿名函數 2. this -- 普通函數的this取決於函數最近的調用者 -- 箭頭函數的this取決於當前上下文的環境 3. 箭頭函數示例 3-1、 ES6中允許使用“箭頭”(=>)定義函數 var f = a => a; 相當於 var f = function( a ) { return a; } 3-2、無參數的箭頭函數 var f = () => 10; 相當於 var f = function() { return 10; } 3-3、有參數的箭頭函數 var sum = (a, b) => a + b; 相當於 var sum = function(a, b) { return a +b; } 4. this是誰 <script> // 普通函數的this取決於函數最近的調用者 // 箭頭函數的this取決於當前上下文的環境 // 普通函數 function aa() { console.log(this) } aa(); // aa這個函數最近的調用者是window,this是window let obj1 = { a: 1, func: aa } obj1.func(); // aa這個函數最近的調用者是obj1,this是obj1 let obj2 = { obj1: obj1, a: 2 } obj2.obj1.func(); // aa這個函數最近的調用者是obj1,this是obj1 // 箭頭函數 let fun2 = () => this; console.log(fun2()) // 這個箭頭函數是在window下調用的,this是window </script>
4、數據的解構(相當於python的*args, **kwargs)
1. 解構對象 let {key, key} = obj <script> // 定義對象 let obj = { a: 1, b: 2, x: 3, y: 4 }; // 解析對象 let {x, y} = obj; console.log(x); // 3 console.log(y); // 4 </script> 2. 解構數組 let [x, y, x] = array <script> // 定義數組 let hobby = ["吹牛", "泡妞", "打架"]; // 解析數組 let [hobby1, hobby2, hobby3] = hobby; console.log(hobby1); // 吹牛 console.log(hobby2); // 泡妞 console.log(hobby3); // 打架 </script>
5、類的定義:ES6中已經開始支持使用class定義類
1. 定義類:class 2. 構造方法:constructor(相當於python中__init__) 3. 沒有self,只有this,this代表這個類本身 4. 繼承使用關鍵字:extends 5. 繼承后的子類沒有this,需要用super方法來找到父類的this 6. 例子

<script> class Animal { // 初始化 constructor(){ // 設置一個屬性名為type this.type = "animal" }; // say方法 say(){ console.log("FFFFFUUUU") } }; // 狗類繼承動物類 class Dog extends Animal { // 子類沒有this constructor(){ // 用super方法拿到父類的this super(); // 修改屬性type的值 this.type = "dog" } // 重寫say方法 say(){ console.log("wow wow wow") } } let animal = new Animal(); console.log(animal.type); // animal animal.say() // FFFFFUUUU let dog = new Dog(); console.log(dog.type); // dog dog.say() // wow wow wow // 如果Dog類沒有重寫say方法,那么則會使用父類的say方法 </script>
6、import export
1. 介紹 在ES6中,import 導入模塊、export導出模塊 一個js文件可以導入另一個js文件的變量,但是目前瀏覽器並不支持這種語法, 不過在后面會講到 打包 ,打包后就可以使用,現在演示一下語法(目前沒有打包,會報錯的,這里只是演示語法) 2. aa.js let name = "xiaoming"; let age = 18; // export拋出變量,其他js文件就可以導入這些拋出的變量 export {name, age} 3. index.js // import導入aa拋出的變量 import {name, age} from "aa" console.log(name) console.log(age) 4. HTML文件 <script src="index.js"></script>
二、Vue初識
1、Vue框架介紹
Vue是一個構建數據驅動的web界面的漸進式框架。
目標是通過盡可能簡單的API實現響應式的數據綁定和組合的視圖組件。
使用Vue需要引入相應的JS文件,可到官網下載或者直接使用CDN:https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js
借鑒后端的MVC架構模式: Model數據 Views模板 Controler數據與模板交互的控制器
Vue是MVVM架構:Model數據 View模板 ViewModel為模板提供處理好的數據
主要思想是數據驅動視圖
從獲取DOM渲染DOM的操作中解脫出來
2、Vue常用指令
1. 介紹 Vue的指令directives很像我們所說的自定義屬性,指令是Vue模板中最常用的功能, 它帶有v-前綴,功能是當表達式改變的時候,相應的行為作用在DOM上。 兩種獲取數據方式: 1. {{數據}} {{name}} 獲取數據name 2. v-..="數據" <h3 v-text="age"></h3> 2. demo

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="content-type" charset="utf-8"> <title>Title</title> <!--導入Vue.js--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> </head> <body> <div id="app"> <!--使用Vue的數據name--> {{name}} </div> <script> // 實例化一個Vue對象,其中el必須要有 const app = new Vue({ el: "#app", // el表示這個Vue對象的作用域是id為app的這塊,無論app這塊嵌套了多少個div,都可以使用這個對象 data: { // data存放數據 name: "小明", } }) </script> </body> </html> 上面代碼相當於: let ele = document.getElementById("app"); ele.innerText = "小明";
3. v-text:相當於innerText

<body> <div id="app"> <h3 v-text="name"></h3> <h3 v-text="age"></h3> </div> <script> const app = new Vue({ el: "#app", data: { name: "狗明", age: 18, } }) </script> </body>
4. v-html:相當於innerHtml

<body> <div id="app"> <h3 v-text="name"></h3> <h3 v-text="age"></h3> <div> <div v-html="hobby"> </div> </div> </div> <script> const app = new Vue({ el: "#app", data: { name: "狗明", age: 18, hobby: `<ul> <li>泡妞</li> <li>打架</li> </ul> ` } }) </script> </body>
5. v-for

<body> <div id="app"> <ul> <!--循環的索引是位置參數,在第二位,用什么變量名接收都可以--> <!--key為了唯一標識這個循環的每個循環體,避免后續太多循環后可能出現的錯亂,一般讓key等於index,且key是唯一的--> <li v-for="(course, index) in course_list" :key="index">{{course}}{{index}}</li> </ul> <ul> <!--拿到的每個元素p是一個對象類型(字典),JS中可以使用點去取值--> <li v-for="(p, index) in people" :key="index">{{p.name}}{{p.age}}</li> </ul> </div> <script> const app = new Vue({ el: "#app", data: { course_list: ["語文", "數學", "英語"], people: [ { name: "小明", age: 18 }, { name: "狗明", age: 38 } ] } }) </script> </body>
6. v-bind 動態綁定屬性 簡寫直接冒號 :

<body> <style> .my_style { width: 200px; height: 200px; border: 1px solid red; } </style> <div id="app"> <!--v-bind動態綁定class樣式 my_style,is_show控制樣式是否應用上--> <div v-bind:class="{my_style: is_show}"> </div> <!--v-bind的簡寫--> <img :src="my_src"> </div> <script> const app = new Vue({ el: "#app", data: { is_show: true, my_src: "https://pic.cnblogs.com/avatar/1449477/20180725103023.png" } }) </script> </body>
7. v-on 綁定事件 簡寫直接 @

<body> <div id="app"> <!-- v-on綁定事件 v-on:事件="methods里面的方法名"--> <button v-on:click="my_click">屠龍寶刀點擊就送</button> <!-- v-on綁定事件簡寫 --> <button @click="game('天龍八部')">玩游戲</button> <!-- v-on一次綁定多個事件,v-on="{事件1: 方法名1, 事件2: 方法名2}" --> <button v-on="{mouseenter: my_enter, mouseleave: my_leave}">鼠標事件</button> </div> <script> const app = new Vue({ el: "#app", data: { }, methods: { my_click: function(){ alert("屠龍寶刀"); }, game: function(gg){ alert("玩"+gg); }, my_enter: function () { console.log("mouse enter") }, my_leave: function () { console.log("mouse leave") }, } }) </script> </body>
8. v-if v-else-if v-else:是使用appendChild實現的,只有符合條件的才會塞到html頁面上,不符合條件的不會生成html代碼

<body> <div id="app"> <div v-if="role == 'admin'">管理員</div> <div v-else-if="role == 'hr'">HR</div> <div v-else>不是人</div> </div> <script> const app = new Vue({ el: "#app", data: { role: "admin" } }) </script> </body>
9. v-show:是使用display實現的,不顯示的html代碼只是用display: none隱藏起來了

<body> <div id="app"> <div v-show="admin">管理員</div> <div v-show="hr">HR</div> <div v-show="others">不是人</div> <button @click="my_click">點擊顯示或隱藏</button> <h2 v-show="is_show">嘿嘿</h2> </div> <script> const app = new Vue({ el: "#app", data: { admin: true, hr: false, others: false, is_show: false, }, methods: { my_click: function(){ this.is_show = !this.is_show } } }) </script> </body>
10. v-model 數據的雙向綁定 -- input -- textarea -- select

<body> <div id="app"> <!--lazy失去焦點時才更新,trim去空格--> <input type="text" v-model.lazy.trim="username"> {{username}} <pre>{{username}}</pre> <hr> <!--number:輸入數字時,把數據轉為數字類型--> <input type="text" v-model.lazy.number="phone"> {{phone}} {{typeof phone}} <textarea name="" id="" cols="30" rows="10" v-model="article"></textarea> {{article}} <select name="" id="" v-model="choices" multiple> <option value="1">小明</option> <option value="2">狗明</option> <option value="3">番薯明</option> </select> {{choices}} </div> <script> const app = new Vue({ el: "#app", data: { username: "", // 這里設置默認值 phone: "", article: "", choices: ["1"], } }) </script> </body>
11. 指令修飾符 -- .lazy:失去焦點時才獲取數據,默認是內容改變就獲取 -- .number: 當輸入的數據是數字時,轉為數字類型 -- .trim:去空格
12. 自定義的指令 Vue.dirctive("指令名稱", function(el, binding){ el 綁定指令的標簽元素 binding 指令的所有信息組成的對象 value 指令綁定數據的值 modifires 指令修飾符 })
binding對象的參數:
def: {bind: ƒ, update: ƒ}
expression: "posed" // 綁定的數據名
modifiers: {right: true, top: true} // 修飾符的值
name: "pos" // 指令名稱
rawName: "v-pos.right.top" // 指令帶修飾符
value: true // 綁定的數據posed的值
__proto__: Object
12-1. 自定義指令控制某個div元素的位置

<body> <style> .my_box { width: 200px; height: 200px; border: 1px solid red; } </style> <div id="app"> <div class="my_box" v-pos.right.top="posed"> </div> </div> <script> // 第一個參數:指令名稱 // 第二個參數綁定一個回調函數 // 函數中el是我們綁定指令的標簽元素 // binding是綁定這個指令的一些數據 // modifiers(對象):指令修飾符組成的對象的布爾值right top // value:綁定的數據posed Vue.directive("pos", function(el, binding) { console.log(el); console.log(binding); let gps = binding.modifiers; if (binding.value){ el.style.position = "fixed"; // el.style.right = 0; // el.style.bottom = 0; for(let posi in gps){ el.style[posi] = 0; } } }); const app = new Vue({ el: "#app", data: { posed: true } }) </script> </body>
12-2. 自定義模仿v-text原理

<body> </style> <div id="app"> <h2 v-my_text="name"></h2> </div> <script> Vue.directive("my_text", function(el, binding){ el.innerText = binding.value; }) const app = new Vue({ el: "#app", data: { name: "小明" } }) </script> </body>
三、Vue常用指令補充
1、在Vue中獲取DOM
1、在Vue中獲取DOM
1. 給要獲取的HTML標簽設置一個 ref="rname" 屬性
2. 在Vue中通過 $refs.rname 獲取到這個DOM元素
3. 示例

<body> <div id="app"> <div ref="my_div"></div> <button v-on:click="my_click">點擊顯示文本</button> </div> <script> const app = new Vue({ el: "#app", methods: { my_click: function() { // 找到這個DOM對象(vue實例里面的this都是代表這個實例,這里是app) let ele = this.$refs.my_div; // 給這個div添加文本 ele.innerText = "嘿嘿嘿!驚喜吧!" } } }) </script> </body>
2、計算屬性
1. computed存放需要計算的數據,鍵對應函數,通過return把計算結果賦值給 鍵 ,在HTML頁面上就可以使用{{鍵}}獲取結果
2. computed計算出來的數據會放入緩存,同時會一直監聽用於計算的各個數據,當數據變化時,會重新計算並得出結果。
3. 示例

<body> <div id="app"> <table> <thead> <tr> <th>科目</th> <th>成績</th> </tr> </thead> <tbody> <tr> <td>語文</td> <td><input type="text" v-model.number="Chinese"></td> </tr> <tr> <td>數學</td> <td><input type="text" v-model.number="meths"></td> </tr> <tr> <td>英語</td> <td><input type="text" v-model.number="English"></td> </tr> <tr> <td>總分</td> <td>{{sum}}</td> </tr> <tr> <td>平均分</td> <td>{{avg}}</td> </tr> </tbody> </table> </div> <script> const app = new Vue({ el: "#app", data: { Chinese: "", meths: "", English: "" }, computed: { sum: function() { return this.Chinese + this.meths + this.English }, avg: function() { return this.sum/3 } } }) </script> </body>
3、數據的監聽
1. 監聽數據用watch
2. watch里面的每個鍵就是要監聽的數據,handler對應一個函數,參數val是新的值,oldVal是原本的值
3. 在可變數據類型中,val和oldVal都是修改后的數據,因為可變數據類型修改的是原本的值,而不是生成新的值,不可變數據類型,會生成新的值。
4. watch能直接監聽到數組長度的變化
5. 但是監聽不到數組的某個值發生改變,也就是說,數組只是改變了某個值是不會觸發watch的,深度監聽也監聽不到
6. 想要在數組不改變長度,只改變某個值的時候監聽就需要用: Vue實例.$set(某個數組, 索引, "新值");
7. 對象(字典)的某個值發生改變,使用深度監聽可以監聽得到
8. 對象(字典)增加一些鍵值對,使用深度監聽也監聽不到,但是使用:Vue實例.$set(某個對象, 鍵, "新值"); 可以監聽到
9. 示例

<body> <div id="app"> {{name}} <br> {{hobby}} <br> {{girl}} <br> <button @click="my_click">點我改變數據</button> </div> <script> const app = new Vue({ el: "#app", data: { name: "小明", hobby: ["泡吧", "打劫", "碰瓷"], girl: { name: "小鳳姐", age: 48 } }, methods: { my_click: function() { // 修改數據 // this.name = "狗明"; // 數組長度發生了變化,觸發watch //this.hobby.push("狗屎"); // 數組長度不變,某個值改變了,不會觸發watch //this.hobby[0] = "狗子"; // 全局的$set,相當於修改完后會去告訴Vue實例一聲,可以觸發watch // app.$set(this.hobby, 0, "狗子"); // 修改對象某個值,深度監聽就能觸發watch // this.girl.age = 58; // 增加對象內容,需要全局的$set // this.girl['sex'] = 'boy'; // 監聽不到 app.$set(this.girl, "sex", "boy"); } }, watch: { name: { handler: function(val, oldVal) { console.log(val); console.log(oldVal); } }, hobby: { handler: function(val, oldVal) { // 改變數組長度的時候,新舊值相同 console.log(val); console.log(oldVal); }, // 深度監聽 deep: true }, girl: { handler: function(val, oldVal) { // 改變數組長度的時候,新舊值相同 console.log(val); console.log(oldVal); }, // 深度監聽 deep: true } } }) </script> </body>