九阳真经前端篇——更新至ES6
HTML
HTML語義化
HTML語義化就是讓頁面內容結構化,它有如下優點:
- 易于用戶閱讀,樣式丟失的時候能讓頁面呈現清晰的結構
- 有利于SEO,搜索引擎根據標簽來確定上下文和各個關鍵字的權重
- 方便其他設備解析,如盲人閱讀器根據語義化渲染網頁
- 有利于開發和 維護,語義化更具有可讀性,代碼更好維護,與CSS關系更和諧
如:
<header>代表頭部 <nav>代表超鏈接區域 <main>定義文檔主要內容 <article>可以表示文章、博客等內容 <aside>通常表示側邊欄或嵌入內容 <footer>代表尾部HTML5新標簽(待補充)
有<header>,<footer><aside><nav><video><audio><canvas>等CSS
盒子模型
盒模型分為標準和模型和怪異盒模型(IE盒模型)
box-sizing:content-box //標準盒模型 box-sizing:border-box //怪異盒模型標準盒模型:元素的寬度等于style里的width+margin+border+padding寬度
如下代碼,整個寬高還是120px
div{box-sizing: content-box;margin: 10px;width: 100px;height: 100px;padding: 10px; }怪異盒模型:元素寬度等于style里的width寬度
如下代碼,整個寬高還是100px
div{box-sizing: border-box;margin: 10px;width: 100px;height: 100px;padding: 10px; }rem與em的區別
rem是根據根的font-size變化,而em是根據父級的font-size變化
CSS選擇器
- css常用選擇器
- css選擇器權重
!important -> 行內樣式 -> #id -> .class -> 元素和偽元素 -> * -> 繼承 -> 默認
CSS3新特性(待補充)
transition:過渡 transform:旋轉,縮放,移動或者傾斜 animation:動畫 gradient:漸變 shadow:陰影 border-radius:圓角行內元素和塊級元素
- 行內元素(display;inline)
寬度和高度是由內容決定,與其他元素共占一行的元素,我們將其叫行內元素,例如:<span> 、 <i> 、 <a>等
- 塊級元素
默認寬度由父容器決定,默認高度由內容決定,獨占一行并且可以設置寬高的元素,我們將其叫做塊級元素,例如:<p> 、<div> 、<ul>等
相對定位和絕對定位的區別
- position:absolute
絕對定位:是相對于元素最近的已定位的祖先元素
- position:relative
相對定位:相對定位是相對于元素在文檔中的初始位置
Flex布局(待補充)
復習鏈接:https://juejin.im/post/5d428c5451882556dc30535c
BFC
復習鏈接:https://blog.csdn.net/wyf521995/article/details/103106913
簡單描述
- 什么是BFC?
BFC格式化上下文,它是一個獨立的渲染區域,讓處于 BFC 內部的元素和外部的元素相互隔離,使內外元素的定位不會相互影響
- 如何產生BFC?
- BFC作用
BFC最大的一個作用就是:在頁面上有一個獨立隔離容器,容器內的元素和容器外的元素布局不會相互影響
解決上外邊距重疊;重疊的兩個box都開啟bfc; 解決浮動引起高度塌陷;容器盒子開啟bfc 解決文字環繞圖片;左邊圖片div,右邊文字容器p,將p容器開啟bfc水平垂直居中(待補充)
- Flex布局
- 水平居中
- 垂直居中
less,sass,styus三者的區別
- 變量
Sass聲明變量必須是『$』開頭,后面緊跟變量名和變量值,而且變量名和變量值需要使用冒號:分隔開。
Less 聲明變量用『@』開頭,其余等同 Sass。
Stylus 中聲明變量沒有任何限定,結尾的分號可有可無,但變量名和變量值之間必須要有『等號』。
- 作用域
Sass:三者最差,不存在全局變量的概念
Less:最近的一次更新的變量有效,并且會作用于全部的引用!
Stylus:Sass 的處理方式和 Stylus 相同,變量值輸出時根據之前最近的一次定義計算,每次引用最近的定義有效;
- 嵌套
三種 css 預編譯器的「選擇器嵌套」在使用上來說沒有任何區別,甚至連引用父級選擇器的標記 & 也相同
- 繼承
Sass和Stylus的繼承非常像,能把一個選擇器的所有樣式繼承到另一個選擇器上。使用『@extend』開始,后面接被繼承的選擇器。Stylus 的繼承方式來自 Sass,兩者如出一轍。 Less 則又「獨樹一幟」地用偽類來描述繼承關系;
-
導入@import
-
Sass 中只能在使用 url() 表達式引入時進行變量插值
$device: mobile; @import url(styles.#{$device}.css); -
Less 中可以在字符串中進行插值
@device: mobile; @import "styles.@{device}.css"; -
Stylus 中在這里插值不管用,但是可以利用其字符串拼接的功能實現
device = "mobile" @import "styles." + device + ".css"
-
link與@import區別于選擇(待補充)
<style type="text/css">@import url(CSS文件路徑地址); </style> <link href="CSSurl路徑" rel="stylesheet" type="text/css" /link功能較多,可以定義 RSS,定義 Rel 等作用,而@import只能用于加載 css;
當解析到link時,頁面會同步加載所引的 css,而@import所引用的 css 會等到頁面加載完才被加載;
@import需要 IE5 以上才能使用;
link可以使用 js 動態引入,@import不行
多行文本的文本省略號(待補充)
overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: verticalJavaScript
JS的幾條基本規范
1、不要在同一行聲明多個變量 2、請使用===/!==來比較true/false或者數值 3、使用對象字面量替代new Array這種形式 4、不要使用全局變量 5、Switch語句必須帶有default分支 6、函數不應該有時候有返回值,有時候沒有返回值 7、For循環必須使用大括號 8、IF語句必須使用大括號 9、for-in循環中的變量 應該使用var關鍵字明確限定作用域,從而避免作用域污染JS引用方法
-
行內引入
<body><input type="button" onclick="alert('行內引入')" value="按鈕"/><button onclick="alert(123)">點擊我</button> </body> -
內部引入
-
外部引入
<body><div></div><script type="text/javascript" src="./js/index.js"></script> </body>
注意:
1,不推薦寫行內或者HTML中插入
JS的基本數據類型(待補充)
Undefined、Null、Boolean、Number、String、新增:Symbol
數組操作(待補充)
在 JavaScript 中,用得較多的之一無疑是數組操作,這里過一遍數組的一些用法
map: 遍歷數組,返回回調返回值組成的新數組 forEach: 無法break,可以用try/catch中throw new Error來停止 filter: 過濾 some: 有一項返回true,則整體為true every: 有一項返回false,則整體為false join: 通過指定連接符生成字符串 push / pop: 末尾推入和彈出,改變原數組, 返回推入/彈出項【有誤】 unshift / shift: 頭部推入和彈出,改變原數組,返回操作項【有誤】 sort(fn) / reverse: 排序與反轉,改變原數組 concat: 連接數組,不影響原數組, 淺拷貝 slice(start, end): 返回截斷后的新數組,不改變原數組 splice(start, number, value...): 返回刪除元素組成的數組,value 為插入項,改變原數組 indexOf / lastIndexOf(value, fromIndex): 查找數組項,返回對應的下標 reduce / reduceRight(fn(prev, cur), defaultPrev): 兩兩執行,prev 為上次化簡函數的return值,cur 為當前值(從第二項開始)JS有哪些內置對象
Object是JavaScript中所有對象的父對象數據封裝對象:Object、Array、Boolean、Number和String 其他對象:Function、Arguments、Math、Date、RegExp、Errorget請求傳參長度的誤區
誤區:我們經常說get請求參數的大小存在限制,而post請求的參數大小是無限制的
? 實際上HTTP 協議從未規定 GET/POST 的請求長度限制是多少。對get請求參數的限制是來源與瀏覽器或web服務器,瀏覽器或web服務器限制了url的長度。為了明確這個概念,我們必須再次強調下面幾點:
? 1、HTTP 協議 未規定 GET 和POST的長度限制
? 2、GET的最大長度顯示是因為 瀏覽器和 web服務器限制了 URI的長度
? 3、不同的瀏覽器和WEB服務器,限制的最大長度不一樣
? 4、要支持IE,則最大長度為2083byte,若只支持Chrome,則最大長度 8182byte
補充get和post請求在緩存方面的區別
- get請求類似于查找的過程,用戶獲取數據,可以不用每次都與數據庫連接,所以可以使用緩存。
- post不同,post做的一般是修改和刪除的工作,所以必須與數據庫交互,所以不能使用緩存。因此get請求適合于請求緩存。
閉包
-
什么是閉包
函數A里面辦函了函數B,而函數B里面使用了函數A的變量,那么函數B被稱為閉包
又或者:閉包就是能夠讀取其他函數內部變量的函數
function A() {var a = 1;function B() {console.log(a);}return B(); } -
閉包的特征
- 函數內再嵌套函數
- 內部函數可以引用外層的參數和變量
- 參數和變量不會被垃圾回收機制回收
-
對閉包的理解
使用閉包主要是為了設計私有的方法和變量.閉包的優點是可以避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易曹成內存泄漏,在js中,函數即閉包,只有函數才會產生作用域的概念
閉包最大的用處有兩個,一個是可以讀取函數內部的變量,另一個就是讓這些變量時鐘保持在內存中
閉包的另一個用處就是封裝對象的私有屬性和私有方法
-
閉包的好處
能夠實現封裝和緩存等
-
閉包的壞處
就是消耗內存,不正當使用會造成內存溢出的問題
-
使用閉包的注意點
由于閉包會使得函數中的變量都被保存在內存中,內存消耗恒大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能會導致內存泄漏
解決方法是:在退出函數之前,將不使用的局部變量全部刪除
-
閉包的經典問題
for(var i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000); }這段代碼輸出:
答案:3個3 解析:首先,for 循環是同步代碼,先執行三遍 for,i 變成了 3;然后,再執行異步代碼 setTimeout,這時候輸出的 i,只能是 3 個 3 了有什么辦法依次輸出0 1 2
-
第一種方法:使用let
for(let i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000); }在這里,每個 let 和代碼塊結合起來形成塊級作用域,當 setTimeout() 打印時,會尋找最近的塊級作用域中的 i,所以依次打印出 0 1 2
如果這樣不明白,我們可以執行下邊這段代碼
for(let i = 0; i < 3; i++) {console.log("定時器外部:" + i);setTimeout(function() {console.log(i);}, 1000); }此時瀏覽器依次輸出的是:
定時器外部:0 定時器外部:1 定時器外部:2 0 1 2即代碼還是先執行 for 循環,但是當 for 結束執行到了 setTimeout 的時候,它會做個標記,這樣到了 console.log(i) 中,i 就能找到這個塊中最近的變量定義
-
第二種方法
使用立即執行函數解決閉包問題
for(let i = 0; i < 3; i++) {(function(i){setTimeout(function() {console.log(i);}, 1000);})(i) }
-
JS作用域及作用域鏈
-
作用域
在JavaScript中,作用域分為 全局作用域 和 函數作用域
- 全局作用域
代碼在程序的任何地方都能被訪問,window 對象的內置屬性都擁有全局作用域
- 函數作用域
在固定的代碼片段才能被訪問
作用域有上下級關系,上下級關系的確定就看函數是在哪個作用域下創建的。如上,fn作用域下創建了bar函數,那么“fn作用域”就是“bar作用域”的上級。
作用域最大的用處就是隔離變量,不同作用域下同名變量不會有沖突。
變量取值:到創建 這個變量的函數的作用域中取值
-
作用域鏈
一般情況下,變量取值到創建這個變量的函數的作用域中取值。
但是如果在當前作用域中沒有查到值,就會向上級作用域去查,直到查到全局作用域,這么一個查找過程形成的鏈條就叫做作用域鏈
原型和原型鏈
-
原型和原型鏈的概念
每個對象都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那么他就會去prototype里找這個屬性,這個prototype又會有自己的prototype,于是就這樣一直找下去
-
原型和原型鏈的關系
instance.constructor.prototype = instance.__proto__ -
原型和原型鏈的特點
JavaScript對象是通過引用來傳遞的,我們創建的每個新對象實體中并沒有一份屬于自己的原型副本。當我們修改原型時,與之相關的對象也會繼承這一改變,當我們需要一個屬性的時,Javascript引擎會先看當前對象中是否有這個屬性, 如果沒有的就會查找他的Prototype對象是否有這個屬性,如此遞推下去,一直檢索到 Object 內建對象
組件化和模塊化
組件化
-
為什么要組件化開發
有時候頁面代碼量太大,邏輯太多或者同一個功能組件在許多頁面均有使用,維護起來相當復雜,這個時候,就需要組件化開發來進行功能拆分、組件封裝,已達到組件通用性,增強代碼可讀性,維護成本也能大大降低
-
組件化開發的優點
很大程度上降低系統各個功能的耦合性,并且提高了功能內部的聚合性。這對前端工程化及降低代碼的維護來說,是有很大的好處的,耦合性的降低,提高了系統的伸展性,降低了開發的復雜度,提升開發效率,降低開發成本
-
組件化開發的原則
- 專一
- 可配置性
- 標準型
- 復用性
- 可維護性
模塊化
-
為什么要模塊化
早期的javascript版本沒有塊級作用域、沒有類、沒有包、也沒有模塊,這樣會帶來一些問題,如復用、依賴、沖突、代碼組織混亂等,隨著前端的膨脹,模塊化顯得非常迫切
-
模塊化的好處
- 避免變量污染,命名沖突
- 提高代碼復用率
- 提高了可維護性
- 方便依賴關系管理
-
模塊化的幾種方法
-
函數封裝
var myModule = {var1: 1,var2: 2,fn1: function(){},fn2: function(){} }總結:這樣避免了變量污染,只要保證模塊名唯一即可,同時同一模塊內的成員也有了關系
缺陷:外部可以睡意修改內部成員,這樣就會產生意外的安全問題 -
立即執行函數表達式
var myModule = (function(){var var1 = 1;var var2 = 2;function fn1(){} function fn2(){}return {fn1: fn1,fn2: fn2 }; })();總結:這樣在模塊外部無法修改我們沒有暴露出來的變量、函數
缺點:功能相對較弱,封裝過程增加了工作量,仍會導致命名空間污染可能、閉包是有成本的
-
圖片的預加載和懶加載
- 預加載:提前加載圖片,當用戶需要查看時可以直接從本地緩存中渲染
- 懶加載:懶加載的主要目的是作為服務器前端的優化,減少請求數或延遲請求數
兩種技術的本質:兩者的行為是相反的,一個是提前加載,一個是遲緩甚至不加載。預加載則會增加服務器前端壓力,懶加載對服務器有一定的緩解壓力作用。
mouseover和 mouseenter的區別
- mouseover:當鼠標移入元素或者其他子元素都會觸發事件,所以有一個重復觸發,冒泡的過程,對應的移除事件是mouseout
- mouseenter:當鼠標移除元素本身(不包含元素的子元素)會觸發事件,也就是不會冒泡,對應的移除事件是mouseleave
解決異步回調地獄(待補充)
promise,generator,async/await
對This對象的理解(待補充)
- this總是指向函數的直接調用者(而非間接調用者)
- 如果有new關鍵字,this指向new出來的那個對象
- 在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this總是指向全局對象Window
Vue
Vue生命周期
- 什么是Vue生命周期?
參考博文:https://blog.csdn.net/wyf521995/article/details/103114989
簡單描述:Vue 實例從創建到銷毀的過程,就是生命周期。也就是從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命周期
-
Vue生命周期的作用是什么?
它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯
-
Vue生命周期總共有幾個階段?
它可以總共分為8個階段:創建前/后, 載入前/后,更新前/后,銷毀前/銷毀后
-
第一次頁面加載會觸發哪幾個鉤子?
第一次頁面加載時會觸發 beforeCreate, created, beforeMount, mounted 這幾個鉤子
-
DOM渲染在哪個周期中就已經完成?
DOM 渲染在 mounted 中就已經完成了
-
每個生命周期適合哪些場景?
生命周期鉤子的一些使用方法:
beforecreate : 可以在這加個loading事件,在加載實例時觸發
created : 初始化完成時的事件寫在這里,如在這結束loading事件,異步請求也適宜在這里調用
mounted : 掛載元素,獲取到DOM節點
updated : 如果對數據統一處理,在這里寫上相應函數
beforeDestroy : 可以做一個確認停止事件的確認框
nextTick : 更新數據后立即操作dom
v-show與v-if的區別
v-show是css切換,v-if是完整的銷毀和重新創建
使用 頻繁切換時用v-show,運行時較少改變時用v-if
v-if=‘false’ v-if是條件渲染,當false的時候不會渲染
開發中常用的指令有哪些?
v-model :一般用在表達輸入,很輕松的實現表單控件和數據的雙向綁定 v-html: 更新元素的 innerHTML v-show 與 v-if: 條件渲染, 注意二者區別 v-on : click: 可以簡寫為@click,@綁定一個事件。如果事件觸發了,就可以指定事件的處理函數 v-for:基于源數據多次渲染元素或模板塊 v-bind: 當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM綁定Class的數組方法
-
對象方法
v-bind:class="{'orange': isRipe, 'green': isNotRipe}" -
數組方法
v-bind:class="[class1, class2]" -
行內
v-bind:style="{color: color, fontSize: fontSize+'px' }"
組件之間的傳值通信
-
父組件給子組件傳值
使用props,字組件可以使用props接收父組件傳遞的數據
父組件vue模板father.vue
<template><child :msg="message"></child> </template><script> import child from './child.vue'; export default {components: {child},data () {return {message: 'father message';}} } </script>子組件vue模板child.vue
<template><div>{{msg}}</div> </template><script> export default {props: {msg: {type: String,required: true}//我覺得這樣寫有點麻煩,直接用數組接收就可以了/*props:['msg'],*/} } </script> -
子組件向父組件通信
父組件向子組件傳遞事件方法,子組件通過$emit觸發事件,回調給父組件
子組件vue模板child.vue
<template><button @click="handleClick">點我</button> </template><script> export default {props: {msg: {type: String,required: true}},methods () {handleClick () {//........this.$emit('msgFunc',msg);}} } </script>父組件vue模板fatehe.vue
<template><child @msgFunc="func"></child> </template><script> import child from './child.vue'; export default {components: {child},methods: {func (msg) {console.log(msg);}} } </script> -
非父子,兄弟組件之間通信
可以通過實例一個vue實例Bus作為媒介,要相互通信的兄弟組件之中,都引入Bus,然后通過分別調用Bus事件觸發和監聽來實現通信和參數傳遞
bus.js代碼如下:
import Vue from 'vue' export default new Vue()在需要通信的組件都引入Bus.js:
<template><button @click="toBus">子組件傳給兄弟組件</button> </template><script> import Bus from '../common/js/bus.js' export default{methods: {toBus () {Bus.$emit('on', '來自兄弟組件')}} } </script>另一個組件也import Bus.js 在鉤子函數中監聽on事件
import Bus from '../common/js/bus.js' export default {data() {return {message: ''}},mounted() {Bus.$on('on', (msg) => {this.message = msg})}}詳細可以參考文章:https://blog.emier.cn/post/2019-11-17-vue-jing-dian-mian-shi-ti-yu-zhi-shi-dian-chuan-shao/
路由跳轉方式
1,<router-link to='home'> router-link標簽會渲染為<a>標簽,咋填template中的跳轉都是這種;2,另一種是編程是導航 也就是通過js跳轉 比如 router.push('/home')詳細可參考文章:https://blog.emier.cn/post/2019-11-17-vue-jing-dian-mian-shi-ti-yu-zhi-shi-dian-chuan-shao/
MVVM
M - Model,Model 代表數據模型,也可以在 Model 中定義數據修改和操作的業務邏輯V - View,View 代表 UI 組件,它負責將數據模型轉化為 UI 展現出來VM - ViewModel,ViewModel 監聽模型數據的改變和控制視圖行為、處理用戶交互,簡單理解就是一個同步 View 和 Model 的對象,連接 Model 和 Viewcomputed和watch有什么區別?
computed:
watch:
小結
key
參考文章:https://www.jianshu.com/p/4bdd2690859c
組件中的data為什么是函數?
為什么組件中的data必須是一個函數,然后return一個對象,而new Vue實例里,data可以直接是一個對象?
// data data() {return {message: "子組件",childName:this.name} }// new Vue new Vue({el: '#app',router,template: '<App/>',components: {App} })因為組件是用來復用的,JS里對象是引用關系,這樣作用域沒有隔離,而new Vue的實例,是不會被復用的,因此不存在引用對象問題
Class與Style如何動態綁定?
Class 可以通過對象語法和數組語法進行動態綁定
-
class對象語法
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>data: {isActive: true,hasError: false } -
class數組語法
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>data: {activeClass: 'active',errorClass: 'text-danger' } -
style對象語法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>data: {activeColor: 'red',fontSize: 30 } -
style數組語法
<div v-bind:style="[styleColor, styleSize]"></div>data: {styleColor: {color: 'red'},styleSize:{fontSize:'23px'} }
vue的單項數據流(待補充)
keep-alive(待補充)
v-model的原理
vue 項目中主要使用 v-model 指令在表單 input、textarea、select 等元素上創建雙向數據綁定,我們知道 v-model 本質上不過是語法糖,v-model 在內部為不同的輸入元素使用不同的屬性并拋出不同的事件:
- text 和 textarea 元素使用 value 屬性和 input 事件;
- checkbox 和 radio 使用 checked 屬性和 change 事件;
- select 字段將 value 作為 prop 并將 change 作為事件;
以input表單元素為例:
<input v-model='something'>相當于:
<input v-bind:value="something" v-on:input="something = $event.target.value">如果在自定義組件中,v-model 默認會利用名為 value 的 prop 和名為 input 的事件,如下所示:
父組件: <ModelChild v-model="message"></ModelChild>子組件: <div>{{value}}</div>props:{value: String }, methods: {test1(){this.$emit('input', '小紅')}, },nextTick() -待補充
在下次DOM更新循環結束之后執行延遲回調。在修改數據之后,立即使用的這個回調函數,獲取更新后的DOM
// 修改數據 vm.msg = 'Hello' // DOM 還未更新 Vue.nextTick(function () {// DOM 更新 })Vue插槽(待補充)
-
匿名插槽
當子組件模板只有一個沒有屬性的插槽時,
父組件傳入的整個內容片段將插入到插槽所在的 DOM 位置,
并替換掉插槽標簽本身 -
命名插槽
solt元素可以用一個特殊的特性name來進一步配置如何分發內容。
多個插槽可以有不同的名字。 這樣可以將父組件模板中 slot 位置,
和子組件 slot 元素產生關聯,便于插槽內容對應傳遞 -
作用域插槽
在父級中,具有特殊特性 slot-scope 的 元素必須存在,
表示它是作用域插槽的模板。slot-scope 的值將被用作一個臨時變量名,
此變量接收從子組件傳遞過來的 prop 對象
Vue-Router有哪幾種導航鉤子?
全局前置守衛:const router = new VueRouter({ ... })router.beforeEach((to, from, next) => {// ...}) 全局解析守衛: 你可以用 router.beforeResolve 注冊一個全局守衛。這和 router.beforeEach 類似, 區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用。全局后置鉤子: 你也可以注冊全局后置鉤子,然而和守衛不同的是,這些鉤子不會接受 next 函數也不會改變導航本身:router.afterEach((to, from) => {// ... })路由獨享的守衛:const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}] }) 組件內的守衛: 你可以在路由組件內直接定義以下路由導航守衛: const Foo = {template: `...`,beforeRouteEnter (to, from, next) {// 在渲染該組件的對應路由被 confirm 前調用// 不!能!獲取組件實例 `this`// 因為當守衛執行前,組件實例還沒被創建},beforeRouteUpdate (to, from, next) {// 在當前路由改變,但是該組件被復用時調用// 舉例來說,對于一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,// 由于會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鉤子就會在這個情況下被調用。// 可以訪問組件實例 `this`},beforeRouteLeave (to, from, next) {// 導航離開該組件的對應路由時調用// 可以訪問組件實例 `this`} }vuex(待學待補充)
-
vuex是什么?
vuex 就是一個倉庫,倉庫里放了很多對象。其中 state 就是數據源存放地,對應于一般 vue 對象里面的 data
state 里面存放的數據是響應式的,vue 組件從 store 讀取數據,若是 store 中的數據發生改變,依賴這相數據的組件也會發生更新
它通過 mapState 把全局的 state 和 getters 映射到當前組件的 computed 計算屬性
-
五種屬性
- state
- mutations
- getters
- action
-
總結
vuex 一般用于中大型 web 單頁應用中對應用的狀態進行管理,對于一些組件間關系較為簡單的小型應用,使用 vuex 的必要性不是很大,因為完全可以用組件 prop 屬性或者事件來完成父子組件之間的通信,vuex 更多地用于解決跨組件通信以及作為數據中心集中式存儲數據
你對Vue項目進行哪些優化?
-
代碼層面的優化
v-if 和 v-show 區分使用場景 computed 和 watch 區分使用場景 v-for 遍歷必須為 item 添加 key,且避免同時使用 v-if 長列表性能優化 事件的銷毀 圖片資源懶加載 路由懶加載 第三方插件的按需引入 優化無限列表性能 服務端渲染 SSR or 預渲染 -
webpack層面的優化
Webpack 對圖片進行壓縮 減少 ES6 轉為 ES5 的冗余代碼 提取公共代碼 模板預編譯 提取組件的 CSS 優化 SourceMap 構建結果輸出分析 Vue 項目的編譯優化 -
基礎的web技術優化
開啟 gzip 壓縮
瀏覽器緩存
CDN 的使用
使用 Chrome Performance 查找性能瓶頸
補充
Vue路由的兩種模式
小白回答:hash模式url帶#號,history模式不帶#號
大牛解答:hash模式url里面永遠帶著#號,我們在開發當中默認使用這個模式。那么什么時候要用history模式呢?如果用戶考慮url的規范那么就需要使用history模式,因為history模式沒有#號,是個正常的url適合推廣宣傳。當然其功能也有區別,比如我們在開發app的時候有分享頁面,那么這個分享出去的頁面就是用vue或是react做的,咱們把這個頁面分享到第三方的app里,有的app里面url是不允許帶有#號的,所以要將#號去除那么就要使用history模式,但是使用history模式還有一個問題就是,在訪問二級頁面的時候,做刷新操作,會出現404錯誤,那么就需要和后端人配合讓他配置一下apache或是nginx的url重定向,重定向到你的首頁路由上就ok啦。
hash與history的區別:
| url顯示 | 有#,很Low | 無#,好看 |
| 回車刷新 | 可以加載到hash值對應頁面 | 一般就是404掉了 |
| 支持版本 | 支持低版本瀏覽器和IE瀏覽器 | HTML5新推出的API |
hash模式
我們先來認識下這位朋友#,這個#就是hash符號,中文名哈希符或錨點,當然這在我們前端領域姑且這么稱呼。
然后哈希符后面的值,我們稱之為哈希值。OK,接下來我們繼續分析他的原理。路由的哈希模式其實是利用了window可以監聽onhashchange事件,也就是說你的url中的哈希值(#后面的值)如果有變化,前端是可以做到監聽并做一些響應(搞點事情),這么一來,即使前端并沒有發起http請求他也能夠找到對應頁面的代碼塊進行按需加載。
后來人們給他起了一個霸氣的名字叫前端路由,成為了單頁應用標配。
history模式
我們先介紹一下H5新推出的兩個神器:pushState與replaceState
具體自行百度,簡而言之,這兩個神器的作用就是可以將url替換并且不刷新頁面,好比掛羊頭賣狗肉,http并沒有去請求服務器該路徑下的資源,一旦刷新就會暴露這個實際不存在的“羊頭”,顯示404。
那么如何去解決history模式下刷新報404的弊端呢,這就需要服務器端做點手腳,將不存在的路徑請求重定向到入口文件(index.html),前后端聯手,齊心協力做好“掛羊頭賣狗肉”的完美特效。
總之,pushState方法不會觸發頁面刷新,只是導致history對象發生變化,地址欄會有反應。
history模式下,build之后本地 index.html 打開是無效的。
hash模式下,build之后本地 index.html 打開正常!
如何解決SPA應用首屏加載過慢
-
將全局引入轉換為按需引入文件
-
在 config/index.js 文件中將productionSourceMap 的值設置為false. 不生成映射資源
-
路由懶加載:懶加載即組件的延遲加載,通常vue的頁面在運行后進入都會有一個默認的頁面,而其他頁面只有在點擊后才需要加載出來,使用懶加載可以將頁面中的資源劃分為多份,從而減少第一次加載的時候耗時
這種優化,就是將每個組件的js代碼獨立出來,在使用到這個組件時,才向服務器請求文件,并且請求過一次后就會緩存下來,再次使用到這個組件時,就會使用緩存,不再發送請求
-
壓縮css和js文件
-
使用cdn托管(就是把原服務器上數據復制到其他服務器上,用戶訪問時,哪臺服務器近訪問到的就是哪臺服務器上的數據。)
ES6
var,let,const之間的區別
var聲明變量可以重復聲明,而let不可以重復聲明
var是不受限于塊級的,而let是受限于塊級
var會與window相映射(會掛一個屬性),而let不與window相映射
var可以在聲明的上面訪問變量,而let有暫存死區,在聲明的上面訪問變量會報錯
const聲明之后必須賦值,否則會報錯
const定義不可變的量,改變了就會報錯
const和let一樣不會與window相映射、支持塊級作用域、在聲明的上面訪問變量會報錯
解構賦值
數組解構
let [a, b, c] = [1, 2, 3] //a=1, b=2, c=3 let [d, [e], f] = [1, [2], 3] //嵌套數組解構 d=1, e=2, f=3 let [g, ...h] = [1, 2, 3] //數組拆分 g=1, h=[2, 3] let [i,,j] = [1, 2, 3] //不連續解構 i=1, j=3 let [k,l] = [1, 2, 3] //不完全解構 k=1, l=2對象結構
let {a, b} = {a: 'aaaa', b: 'bbbb'} //a='aaaa' b='bbbb' let obj = {d: 'aaaa', e: {f: 'bbbb'}} let {d, e:{f}} = obj //嵌套解構 d='aaaa' f='bbbb' let g; (g = {g: 'aaaa'}) //以聲明變量解構 g='aaaa' let [h, i, j, k] = 'nice' //字符串解構 h='n' i='i' j='c' k='e'函數參數的定義
一般我們在定義函數的時候,如果函數有多個參數時,在es5語法中函數調用時參數必須一一對應,否則就會出現賦值錯誤的情況,來看一個例子:
function personInfo(name, age, address, gender) { console.log(name, age, address, gender) } personInfo('william', 18, 'changsha', 'man')上面這個例子在對用戶信息的時候需要傳遞四個參數,且需要一一對應,這樣就會極易出現參數順序傳錯的情況,從而導致bug,接下來來看es6解構賦值是怎么解決這個問題的:
function personInfo({name, age, address, gender}) {console.log(name, age, address, gender) } personInfo({gender: 'man', address: 'changsha', name: 'william', age: 18})這么寫我們只知道要傳聲明參數就行來,不需要知道參數的順序也沒關系
變換變量的值
在es5中我們需要交換兩個變量的值需要借助臨時變量的幫助,來看一個例子:
var a=1, b=2, c c = a a = b b = c console.log(a, b)來看ES6如何實現
let a=1, b=2; [b, a] = [a, b] console.log(a, b)函數默認參數
在日常開發中,經常會有這種情況:函數的參數需要默認值,如果沒有默認值在使用的時候就會報錯,來看es5中是怎么做的:
function saveInfo(name, age, address, gender) { name = name || 'william' age = age || 18 address = address || 'changsha' gender = gender || 'man' console.log(name, age, address, gender) } saveInfo()在函數離 main先對參數做一個默認值賦值,然后再使用避免使用的過程中報錯,再來看es6中的使用的方法:
function saveInfo({name= 'william', age= 18, address= 'changsha', gender= 'man'} = {}) {console.log(name, age, address, gender) } saveInfo()forEach,for in,for of三者的區別(待補充)
forEach更多的用來遍歷數
for in 一般常用來遍歷對象或json
for of數組對象都可以遍歷,遍歷對象需要通過和Object.keys()
for in循環出的是key,for of循環出的是value
使用箭頭函數應該注意什么?(待補充)
1、用了箭頭函數,this就不是指向window,而是父級(指向是可變的)
2、不能夠使用arguments對象
3、不能用作構造函數,這就是說不能夠使用new命令,否則會拋出一個錯誤
4、不可以使用yield命令,因此箭頭函數不能用作 Generator 函數
Set、Map的區別
應用場景Set用于數據重組,Map用于數據儲存
Set:
1,成員不能重復
2,只有鍵值沒有鍵名,類似數組
3,可以遍歷,方法有add, delete,has
Map:
1,本質上是健值對的集合,類似集合
2,可以遍歷,可以跟各種數據格式轉換
promise對象的用法,手寫一個promise(待補充)
promise是一個構造函數,下面是一個簡單實例
var promise = new Promise((resolve,reject) => {if (操作成功) {resolve(value)} else {reject(error)} }) promise.then(function (value) {// success },function (value) {// failure })Ajax
Github
webpack
微信小程序
網絡協議
性能優化
總結
以上是生活随笔為你收集整理的九阳真经前端篇——更新至ES6的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 男追女之九阳真经(转载)
- 下一篇: 推荐个将其他文档转为pdf的软件:Nit