2020-05-24

日常知識(shí)點(diǎn)總結(jié)(vue篇):

1古程、vue的生命周期:

Vue實(shí)例從開(kāi)始創(chuàng)建,初始化數(shù)據(jù)喊崖,編譯模板挣磨,掛載Dom->渲染雇逞,更新->渲染,卸載等一系列過(guò)程茁裙,我們稱(chēng)這是Vue的生命周期塘砸。

作用:生命周期中有多個(gè)事件鉤子,讓我們?cè)诳刂普麄€(gè)Vue實(shí)例的過(guò)程時(shí)更容易形成好的邏輯晤锥。

1)beforeCreate( ) ;

實(shí)例創(chuàng)建前,這個(gè)階段實(shí)例的data,method是讀不到的

2)created( );

實(shí)例創(chuàng)建后,這個(gè)階段已經(jīng)完成了數(shù)據(jù)觀測(cè)(data? observer)谣蠢,屬性和方法的運(yùn)算,watch/event事件回調(diào).mount掛載階段還沒(méi)開(kāi)始,$el屬性目前不可見(jiàn),數(shù)據(jù)并沒(méi)有在Dom元素上進(jìn)行渲染.

3)beforeMount( );

在掛載開(kāi)始之前被調(diào)用,相關(guān)的render函數(shù)首次被調(diào)用.

4)mounted( );

el選項(xiàng)的Dom節(jié)點(diǎn)被新創(chuàng)建的vm.$el替換,并掛載到實(shí)例上去之后調(diào)用此生命周期函數(shù).此時(shí)實(shí)例的數(shù)據(jù)在Dom節(jié)點(diǎn)上進(jìn)行渲染.

5)beforeUpdate( );

數(shù)據(jù)更新時(shí)調(diào)用,但不進(jìn)行Dom重新渲染,在數(shù)據(jù)更新時(shí)Dom沒(méi)渲染前可以在這個(gè)生命函數(shù)里進(jìn)行狀態(tài)處理

6)updated( );

這個(gè)狀態(tài)下數(shù)據(jù)更新并且Dom重新渲染,當(dāng)這個(gè)生命周期函數(shù)被調(diào)用時(shí),組件Dom已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴(lài)于Dom的操作.當(dāng)實(shí)例每次進(jìn)行數(shù)據(jù)更新時(shí)updated都會(huì)執(zhí)行.

7)beforeDestory( );

銷(xiāo)毀前執(zhí)行(實(shí)例仍然完全可用)查近∶减猓可以做一個(gè)確認(rèn)停止事件的確認(rèn)框。

8)destoryed( );

Vue實(shí)例銷(xiāo)毀后調(diào)用.調(diào)用后,vue實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷(xiāo)毀.

Vue每個(gè)生命周期階段可以做的事:

created:實(shí)例已經(jīng)創(chuàng)建完成霜威,因?yàn)樗亲钤缬|發(fā)的原因可以進(jìn)行一些數(shù)據(jù)谈喳,資源的請(qǐng)求。

mounted:實(shí)例已經(jīng)掛載完成戈泼,可以進(jìn)行一些Dom操作婿禽。

beforeUpdate:可以在這個(gè)鉤子中進(jìn)一步的更改狀態(tài),這不會(huì)觸發(fā)附加的重渲染過(guò)程大猛。

updated:可以執(zhí)行依賴(lài)于Dom的操作扭倾。然而在大多數(shù)情況下,你應(yīng)該避免在此期間更改狀態(tài)挽绩,因?yàn)檫@可能會(huì)導(dǎo)致更新無(wú)線(xiàn)循環(huán)膛壹。該鉤子在服務(wù)端渲染期間不被調(diào)用。

beforeDestory:可以執(zhí)行一些優(yōu)化操作唉堪,清空定時(shí)器模聋,解除綁定事件。

nextTick:針對(duì)單一事件更新數(shù)據(jù)后立即操作dom

watch: 監(jiān)聽(tīng)具體數(shù)據(jù)變化,并做相應(yīng)的處理

2唠亚、vue響應(yīng)式原理:

當(dāng)一個(gè)vue實(shí)例創(chuàng)建時(shí)链方,vue會(huì)遍歷data選項(xiàng)的屬性,用Object.defineProperty將它們轉(zhuǎn)為getter/setter并且在內(nèi)部追蹤相關(guān)依賴(lài)灶搜,在屬性被訪(fǎng)問(wèn)和修改時(shí)通知變化祟蚀。每個(gè)組件實(shí)例內(nèi)部都有相應(yīng)的watcher程序?qū)嵗鼤?huì)在組件渲染的過(guò)程中把屬性記錄為依賴(lài)割卖,之后當(dāng)依賴(lài)項(xiàng)的setter被調(diào)用時(shí)前酿,會(huì)通知watcher重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新究珊。

3薪者、vue雙向數(shù)據(jù)綁定原理:

vue.js是采用數(shù)據(jù)劫持結(jié)合“發(fā)布者---訂閱者”模式的方式,通過(guò)Object.defineProperty( )來(lái)劫持各個(gè)屬性的setter剿涮、getter言津,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者攻人,觸發(fā)相應(yīng)的監(jiān)聽(tīng)回調(diào)。

具體步驟:

1)需要observe的數(shù)據(jù)對(duì)象進(jìn)行遞歸遍歷悬槽,包括子屬性對(duì)象的屬性怀吻,都加上setter和getter這樣的話(huà),給這個(gè)對(duì)象的某個(gè)值賦值初婆,就會(huì)觸發(fā)setter蓬坡,那么就能監(jiān)聽(tīng)到數(shù)據(jù)變化。

2)compile解析模板指令磅叛,將模板中的變量替換成數(shù)據(jù)屑咳,然后初始化 渲染頁(yè)面視圖,并將每個(gè)指令對(duì)應(yīng)的節(jié)點(diǎn)綁定更新函數(shù)弊琴,添加監(jiān)聽(tīng)數(shù)據(jù)的訂閱者兆龙,一旦數(shù)據(jù)有變動(dòng),收到通知敲董,更新視圖紫皇。

3)Watcher訂閱者是Observer和Compile之間通信的橋梁,主要做的事情是:在自身實(shí)例化時(shí)往屬性訂閱器(dep)里面添加自己腋寨,自身必須有一個(gè)update( )方法聪铺,待屬性變動(dòng)dep.notice( )通知時(shí),能調(diào)用自身的update( )方法萄窜,并觸發(fā)Compile中綁定的回調(diào)铃剔,則功成身退。

4)MVVM作為數(shù)據(jù)綁定的入口脂倦,整合Observe番宁,Compile和Watcher三者,通過(guò)Observe來(lái)監(jiān)聽(tīng)自己的model數(shù)據(jù)變化赖阻,通過(guò)Compile來(lái)解析編譯模板指令,最終利用Watcher搭起Observe和Compile之間的通信橋梁踱蠢,達(dá)到數(shù)據(jù)變化-->視圖更新火欧;視圖交互變化(input)-->數(shù)據(jù)model變更的雙向綁定效果。

4茎截、vue的組件通信:

1)父子間通信苇侵,父 -> 子通過(guò)props,子 -> 父$on企锌,$emit(發(fā)布-訂閱)

2)獲取父子組件實(shí)例的方式$parent榆浓,$children

3)在父組件中提供數(shù)據(jù)子組件進(jìn)行消費(fèi) Provide,inject(寫(xiě)插件用較多)

provide( ) { someval:'來(lái)自低級(jí)組件的數(shù)據(jù)'}

inject:['somaval']

4)Ref獲取實(shí)例的方式調(diào)用組件的屬性或者方法

5)Event? Bus? 實(shí)現(xiàn)跨組件通信

非父子組件/兄弟組件之間的數(shù)據(jù)傳遞:

/*新建一個(gè)Vue實(shí)例作為中央事件*/

let event = new Vue();

/*監(jiān)聽(tīng)事件 */

event.$on('eventName',(val) => {

? //.......do? something

})

/*觸發(fā)事件 */

event.$emit('eventName','這是一條消息撕攒。')

6)vuex:狀態(tài)管理實(shí)現(xiàn)通信陡鹃。服務(wù)器設(shè)置session服務(wù)器返回給客戶(hù)端的信息在響應(yīng)頭中帶著set-cookie='connect.sid'客戶(hù)端會(huì)把信息種植到本地的cookie中httponly客戶(hù)端再次向服務(wù)器發(fā)送請(qǐng)求的時(shí)候烘浦,會(huì)默認(rèn)在請(qǐng)求頭中cookie把connect.sid傳遞發(fā)給服務(wù)器

5、Vuex是什么:

定義:Vuex是專(zhuān)門(mén)為vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式萍鲸。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài)闷叉。

狀態(tài)自管理應(yīng)用包含以下幾個(gè)部分:

State,是 Vuex 這一狀態(tài)管理工具的唯一的數(shù)據(jù)源脊阴,所有的數(shù)據(jù)都儲(chǔ)存在里面握侧。

Getter,對(duì)數(shù)據(jù)獲取之前的再次編譯嘿期,可以理解為state的計(jì)算屬性品擎,

在組件中使用$store.getters.fun( )。

Mutation 备徐,是同步更新數(shù)據(jù)(內(nèi)部會(huì)進(jìn)行是否為異步方式更新數(shù)據(jù)的檢測(cè))孽查。$watch嚴(yán)格模式下會(huì)報(bào)錯(cuò)

在組件中使用$store.commit(" ",params)。

Action坦喘,異步操作盲再,可以獲取數(shù)據(jù)后調(diào)用mutation提交最終數(shù)據(jù)

在組件中使用$store.dispath(" ")。

Module瓣铣,當(dāng)應(yīng)用非常復(fù)雜時(shí)答朋,可以把整個(gè)store拆分成幾個(gè)模塊(module),每個(gè)module中都可以含有各自的state,getter棠笑,mutation梦碗,action

vuex的使用:

1)在src目錄下創(chuàng)建vuex文件夾,并在文件夾下創(chuàng)建一個(gè)store.js文件蓖救。

2)下載洪规,并引入vuex。

3)在store.js文件中循捺,引入vuex并且使用vuex斩例。

4)在main.js中引入store并Vue.use(Vuex)。

使用場(chǎng)景:?jiǎn)雾?yè)應(yīng)用中从橘,組件之間的狀態(tài)磁餐。音樂(lè)播放休傍,登錄管理,加入購(gòu)物車(chē)。

6嗤谚、vue-loader是什么舆床,什么用途:

vue-loader是基于webpack的一個(gè)loader(加載器)缕粹,解析和轉(zhuǎn)換.vue文件登夫,提取出其中的邏輯代碼script,樣式代碼style,以及HTML模板template董栽,再分別把它們交給對(duì)應(yīng)的loader去處理码倦,核心的作用,就是提取裆泳,劃重點(diǎn)叹洲。

webpack的loader,其實(shí)就是用來(lái)打包工禾,轉(zhuǎn)譯js或者css文件运提,簡(jiǎn)單的說(shuō)就是把寫(xiě)的代碼轉(zhuǎn)換成瀏覽器能識(shí)別的,還有一些打包闻葵,壓縮的功能等民泵。

vue-loader的作用:

1)允許為Vue組件的每個(gè)部分使用其它的webpack loader,例如在<style>的部分使用Sass和在<template>的部分使用Pug

2)允許在一個(gè).vue文件中使用自定義塊槽畔,并對(duì)其運(yùn)用系定義的loader鏈

3)使用webpack loader將<style><template>中引入的資源當(dāng)作模塊依賴(lài)來(lái)處理

4)為每個(gè)組件模擬出scoped CSS

5)在開(kāi)發(fā)過(guò)程中使用熱重載來(lái)保持狀態(tài)

7栈妆、vue-router的路由模式:

vue-router中默認(rèn)使用的時(shí)hash模式,也就是URL中帶有#號(hào)厢钧,使用mode:"history"修改為history模式鳞尔。

實(shí)際上存在三種模式:

Hash: 使用URL的hash值來(lái)作為路由。支持所有瀏覽器早直。

History: 以來(lái)HTML5 History API 和服務(wù)器配置寥假。參考官網(wǎng)中HTML5 History模式

Abstract: 支持所有javascript運(yùn)行模式。如果發(fā)現(xiàn)沒(méi)有瀏覽器的API霞扬,路由會(huì)自動(dòng)強(qiáng)制進(jìn)入這個(gè)模式糕韧。

hash模式:

背后的原理時(shí)onhashchange事件。因?yàn)閔ash發(fā)生變化的url都會(huì)被瀏覽器記錄下來(lái)喻圃,因此瀏覽器的前進(jìn)后退都可以用的萤彩。盡管瀏覽器沒(méi)有請(qǐng)求服務(wù)器,但是頁(yè)面狀態(tài)和url----關(guān)聯(lián)起來(lái)斧拍,被稱(chēng)為前端路由雀扶。

history路由:

historyAPI分為兩大部分:切換(history.go()? /history.back()? /history.forward() ),

修改歷史狀態(tài)(pushState( stateObj,title,url) / replaceState(stateObj,title,url))

8、$router與$route的區(qū)別

$router饮焦,是路由實(shí)例對(duì)象怕吴。為VueRouter實(shí)例,想要跳轉(zhuǎn)導(dǎo)航到不同URL县踢,則使用$router.push( )方法,傳入?yún)?shù)為字符串/對(duì)象伟件。

$route硼啤,是路由信息對(duì)象。為當(dāng)前router跳轉(zhuǎn)對(duì)象里面可以獲取name, path, query, params等斧账。

params 和query 的傳參及使用:

1) 使用query傳參的時(shí)候,name,path都可以引入,但使用params傳參的時(shí)候只能使用name進(jìn)行引入.

2) 接收參數(shù)的時(shí)候使用this.$route.params.name或者this.$route.query.name

3) 進(jìn)行路由跳轉(zhuǎn)的時(shí)候,我們使用this.$router.push('路徑')

4) 如果index.js配置路由時(shí),我們能看到,params的參數(shù)是URL不可或缺的一部分,但是query的參數(shù)是拼起來(lái)的,沒(méi)有也不影響.

9谴返、用vue-cli初始化一個(gè)vue項(xiàng)目里的各個(gè)文件都是什么作用(從上到下依次說(shuō)明):

node_modules:項(xiàng)目依賴(lài)的第三方node包

public:

src:放的是整個(gè)項(xiàng)目的源代碼

1)main.js:是整個(gè)項(xiàng)目的入口文件

2)APP.vue:項(xiàng)目最開(kāi)始的根組件

3)router:項(xiàng)目所有路由都放在router下的index.js文件里

4)store:

5)views:

6)components:放的是項(xiàng)目中用到的小組件

7)assets:項(xiàng)目里要用到的圖片資源

8)config:項(xiàng)目里的配置文件煞肾,基礎(chǔ)配置在index.js里,開(kāi)發(fā)環(huán)境的配置在dev.env.js

9)build.js:項(xiàng)目打包的webpack配置內(nèi)容

editorconfig:配置編輯器里的語(yǔ)法嗓袱,里面可以自定義內(nèi)容籍救,可統(tǒng)一編輯器自動(dòng)格式化代碼。

eslintrc.js:代碼的規(guī)范渠抹,看代碼是否標(biāo)準(zhǔn)

gitignore:使用git希望把代碼放到線(xiàn)上蝙昙,但是一些特殊的文件并不想或者不需要傳到線(xiàn)上,就可以把它配置到gitgnore文件里梧却,當(dāng)提交到git倉(cāng)庫(kù)文件時(shí)奇颠,這里的文件就不會(huì)被提交到git線(xiàn)上倉(cāng)庫(kù);

babel.config.js:語(yǔ)法解析器

package-lock.json:package的鎖文件放航,確定安裝的第三方包版本烈拒,為了統(tǒng)一團(tuán)隊(duì)的編碼;

package.json:這是一個(gè)依賴(lài)包广鳍,也就是第三方模塊依賴(lài)存放處荆几;

README.md:項(xiàng)目說(shuō)明文件

10、v-show和v-if指令的共同點(diǎn)和不同點(diǎn):

v-show指令是通過(guò)修改元素的display的CSS屬性讓其顯示或者隱藏

v-if 指令是直接銷(xiāo)毀和重建DOM達(dá)到讓元素顯示和隱藏的效果

使用v-show會(huì)更加節(jié)省性能上的開(kāi)銷(xiāo)赊时;當(dāng)只需要一次顯示或隱藏時(shí)吨铸,使用v-if更加合理。

v-for與v-if不同在同一層級(jí)蛋叼,在使用時(shí)焊傅,v-for的優(yōu)先級(jí)比v-if高,會(huì)先循環(huán)狈涮,然后給每一個(gè)循環(huán)后的節(jié)點(diǎn)狐胎,添加v-if。

11歌馍、NextTick是做什么的

$nextTick是在下次DOM更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)握巢,在修改數(shù)據(jù)之后使用$nextTick,則可以在回調(diào)中獲取更新后的DOM松却。

12暴浦、對(duì)比jQuery, Vue有什么不同

jQuery專(zhuān)注視圖層晓锻,通過(guò)操作DOM去實(shí)現(xiàn)頁(yè)面的一些邏輯渲染歌焦;

Vue專(zhuān)注于數(shù)據(jù)層,通過(guò)數(shù)據(jù)的雙向綁定砚哆,最終表現(xiàn)在DOM層面独撇,減少DOM操作;

Vue使用了組件化思想,使得項(xiàng)目子集職責(zé)清晰纷铣,提高了開(kāi)發(fā)效率卵史,方便重復(fù)利用,便于協(xié)同開(kāi)發(fā)搜立。

12以躯、Vue中computed和watch的區(qū)別:

computed(計(jì)算屬性):

1)不支持異步,當(dāng)computed內(nèi)有異步操作時(shí)無(wú)效啄踊,無(wú)法監(jiān)聽(tīng)數(shù)據(jù)的變化忧设。

2)簡(jiǎn)化template里面{{ }}計(jì)算和處理props或$emit的傳值。

3)具有緩存性社痛,頁(yè)面重新渲染值不變化见转,計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果,而不必再次執(zhí)行函數(shù)蒜哀。

watch(偵聽(tīng)屬性):

1)watch支持異步斩箫,監(jiān)聽(tīng)props, $emit或本組件的值執(zhí)行異步操作。

2)監(jiān)聽(tīng)數(shù)據(jù)必須是data中聲明過(guò)或者父組件傳遞過(guò)來(lái)的props中的數(shù)據(jù)撵儿,當(dāng)數(shù)據(jù)變化時(shí)乘客,觸發(fā)其他操作。監(jiān)聽(tīng)的函數(shù)接收兩個(gè)參數(shù)淀歇,第一個(gè)參數(shù)是最新的值易核,第二個(gè)參數(shù)是輸入之前的值。

3)不支持緩存浪默,數(shù)據(jù)變牡直,直接會(huì)觸發(fā)相應(yīng)的操作。

13纳决、 計(jì)算屬性 computed 和事件 methods 有什么區(qū)別

將同一函數(shù)定義為一個(gè) method 或者一個(gè)計(jì)算屬性碰逸。對(duì)于最終的結(jié)果,兩種方式是相同的阔加。

不同點(diǎn):

computed:計(jì)算屬性是基于它們的依賴(lài)進(jìn)行緩存的饵史,只有在它的相關(guān)依賴(lài)發(fā)生改變時(shí)才會(huì)重新求值。

method:只要發(fā)生重新渲染胜榔, method 調(diào)用總會(huì)執(zhí)行該函數(shù)胳喷。

14、多頁(yè)面應(yīng)用與單頁(yè)面應(yīng)用的區(qū)別:

1)頁(yè)面的組成

多頁(yè)面夭织,由多個(gè)完整頁(yè)面吭露,例如:page1.html, page2.html

單頁(yè)面,由一個(gè)初始頁(yè)面和多個(gè)頁(yè)面模塊組成尊惰,例如:index.html和page1.html.js, page2.html.js

2)公共文件加載

多頁(yè)面奴饮,跳轉(zhuǎn)頁(yè)面前后纬向,js/css/img等公用文件重新加載

單頁(yè)面择浊,js/css/img等公用文件只在加載初始頁(yè)面時(shí)加載戴卜,更換頁(yè)面內(nèi)容前后無(wú)需重新加載

3)頁(yè)面跳轉(zhuǎn)/內(nèi)容更新

多頁(yè)面,頁(yè)面通過(guò)window.location.href = './index.html'跳轉(zhuǎn)

單頁(yè)面琢岩,通過(guò)使用js方法投剥,append/remove或者show/hide等方式來(lái)進(jìn)行頁(yè)面內(nèi)容的更換

4)頁(yè)面跳轉(zhuǎn)/內(nèi)容更新所需要數(shù)據(jù)的傳遞

多頁(yè)面,可以使用路徑攜帶數(shù)據(jù)傳遞的方式担孔,或者localstorage江锨,cookie等存儲(chǔ)方式

單頁(yè)面,直接通過(guò)參數(shù)傳遞糕篇,或者全局變量的方式進(jìn)行啄育,因?yàn)槎际窃谝粋€(gè)頁(yè)面的腳本環(huán)境下

5)用戶(hù)體驗(yàn)

多頁(yè)面,如果單個(gè)頁(yè)面加載的文件相對(duì)較大(多)拌消,頁(yè)面切換加載會(huì)很慢

單頁(yè)面挑豌,頁(yè)面片段切換較快,用戶(hù)體驗(yàn)較好墩崩,因?yàn)槌醮我呀?jīng)加載好相關(guān)文件氓英。但是初次加載頁(yè)面時(shí)需要調(diào)整優(yōu)化,因?yàn)榧虞d文件較多鹦筹。

6)使用場(chǎng)景

多頁(yè)面铝阐,適用于高度追求支持搜索引擎的應(yīng)用

單頁(yè)面,高要求的體驗(yàn)度铐拐,追求界面流暢的應(yīng)用

7)專(zhuān)場(chǎng)動(dòng)畫(huà)

多頁(yè)面徘键,不容易實(shí)現(xiàn)

單頁(yè)面,容易實(shí)現(xiàn)

總結(jié):?jiǎn)雾?yè)面模式相較有優(yōu)勢(shì)遍蟋,無(wú)論在用戶(hù)體驗(yàn)還是頁(yè)面切換的數(shù)據(jù)傳遞吹害,頁(yè)面切換動(dòng)畫(huà),都可以有比較答的操作空間匿值。

15赠制、Vue父子組件生命周期調(diào)用順序:

1)加載渲染過(guò)程:

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

2)子組件更新過(guò)程:

父fubeforeUpdate -> 子beforeUpdate -> 子updated -> 父updated

3)父組件更新過(guò)程:

父beforeUpdated -> 父updated

4)銷(xiāo)毀過(guò)程:

父beforeDestory -> 子beforeDestory -> 子destoryed -> 父destoryed

理解:

組件的調(diào)用順序都是先父后子,渲染完成的順序肯定是先子后父

組件的銷(xiāo)毀操作是先父后子挟憔,銷(xiāo)毀完成的順序是先子后父

16钟些、 Vue 組件 data 為什么必須是函數(shù)

因?yàn)?JS 本身的特性帶來(lái)的,如果 data 是一個(gè)對(duì)象绊谭,那么由于對(duì)象本身屬于引用類(lèi)型政恍,當(dāng)我們修改其中的一個(gè)屬性時(shí),會(huì)影響到所有 Vue 實(shí)例的數(shù)據(jù)达传。如果將 data 作為一個(gè)函數(shù)返回一個(gè)對(duì)象篙耗,那么每一個(gè)實(shí)例的 data 屬性都是獨(dú)立的迫筑,不會(huì)相互影響了。

17宗弯、Vue自定義過(guò)濾器

可以用全局方法Vue.filter(? )注冊(cè)一個(gè)自定義過(guò)濾器脯燃,它接收兩個(gè)參數(shù):過(guò)濾器ID和過(guò)濾器函數(shù)。過(guò)濾器函數(shù)以值為參數(shù)蒙保,返回轉(zhuǎn)換后的值辕棚。

js:Vue.filter('reverse',function(value){

? ? return value.split('').reverse().join('');

? ? })

html:<span v-text='message | reverse'></span>

18、Vue中自定義指令

全局定義指令:在vue對(duì)象的directive方法里面有兩個(gè)參數(shù)邓厕,一個(gè)是指令名稱(chēng)逝嚎,另一個(gè)是函數(shù)。

組件內(nèi)定義指令:directives

鉤子函數(shù):bind(綁定事件出發(fā))/ inserted(節(jié)點(diǎn)插入時(shí)候觸發(fā))/ update(組件內(nèi)相關(guān)更新)

鉤子函數(shù)參數(shù):el, binding

//注冊(cè)全局自定義指令详恼,v-focus

? Vue.directive('focus',{

? ? ? ? //當(dāng)被綁定的元素插入到DOM中時(shí)

? ? ? inserted: function(el){

? ? ? ? ? //聚焦元素

? ? ? ? ? el.focus()

? ? ? }

? })

//局部注冊(cè)

? ? directive:{

? ? ? focus:{

? ? ? ? ? ? //指令的定義

? ? ? ? ? ? inserted:function(el){

? ? ? ? ? ? ? ? el.focus();

? ? ? ? ? ? }

? ? ? ? }

? }

vuejs里的指令/組件/插件:

? ? ? ? 組件與指令的區(qū)別:

組件补君,通常都有對(duì)應(yīng)的html代碼,表示一塊具有特定樣式昧互,邏輯和功能的實(shí)體挽铁。

指令,通常用于給已存在DOM添加相應(yīng)的行為硅堆,例如v-if, v-for等屿储,定義指令的時(shí)候一般不需要特定的視圖。

? ? ? ? 組件與插件的區(qū)別:

組件渐逃,是用來(lái)構(gòu)成你的APP的業(yè)務(wù)模塊够掠,它的目標(biāo)是App.vue。

插件茄菊,是用來(lái)增強(qiáng)你的技術(shù)棧的功能模塊疯潭,它的目標(biāo)是Vue本身。

19面殖、Vue中常見(jiàn)性能優(yōu)化

1)編碼優(yōu)化:

不要將所有的數(shù)據(jù)都放在data中竖哩,data中的數(shù)據(jù)都會(huì)增加getter和setter,會(huì)收集對(duì)應(yīng)的watcher

vue在v-for時(shí)給每項(xiàng)元素綁定事件需要用事件代理

SPA頁(yè)面采用keep-alive緩存組件

拆分組件(提高復(fù)用性脊僚,增加代碼的可維護(hù)性相叁,減少不必要的渲染)

v-if當(dāng)值為false時(shí)內(nèi)部指令不會(huì)執(zhí)行,具有阻斷功能辽幌,很多情況下使用v-if替代v-show

key保證唯一性(默認(rèn)vue會(huì)采用就地復(fù)用策略)

Object.freeze凍結(jié)數(shù)據(jù)

合理使用路由懶加載增淹,異步組件

盡量采用runtime運(yùn)行時(shí)版本

數(shù)據(jù)持久化的問(wèn)題(防抖,節(jié)流)

2)vue加載性能優(yōu)化

第三方模塊按需導(dǎo)入(babel-plugin-component)

滾動(dòng)到可視區(qū)域動(dòng)態(tài)加載(https://tangbc.github.io/vue-virtual-scroll-list)

圖片懶加載(https://github.com/hilongjw/vue-lazyload)

3)用戶(hù)體驗(yàn)

app-skeleton骨架屏乌企,loading虑润,在加載過(guò)程中,可以提供loading圖標(biāo)

app-shell app殼 加酵,先加載頭和底部拳喻,給用戶(hù)正在加載哭当,不過(guò)加載較慢的錯(cuò)覺(jué)

pwa,serviceWorker

better-click防止iPhone點(diǎn)擊延遲冗澈,在開(kāi)發(fā)移動(dòng)端vuejs項(xiàng)目時(shí)钦勘,手指觸摸時(shí)會(huì)出現(xiàn)300ms的延遲效果,可以采用better-click對(duì)ipone系列的兼容體驗(yàn)優(yōu)化渗柿。

4)SEO優(yōu)化

預(yù)渲染插件prerender-spa-plugin

服務(wù)端渲染ssr

5)打包優(yōu)化

使用cdn的方式加載第三方模塊

多線(xiàn)程打包happypack

splitChunks抽離公共文件

sourceMap 生成个盆,屏蔽sourceMap,在index.js的通用配置文件分別對(duì)開(kāi)發(fā)環(huán)境和上線(xiàn)環(huán)境做了打包配置分類(lèi)朵栖,在build對(duì)象中的配置信息中,productionSourceMap修改成false柴梆。

6)緩存陨溅,壓縮

客戶(hù)端緩存,服務(wù)端緩存

服務(wù)端gzip壓縮绍在,對(duì)于項(xiàng)目代碼中的JS/CSS/等文件進(jìn)行g(shù)zip壓縮门扇,index.js的通用配置,productionGzip設(shè)置為true

20偿渡、為什么使用key:

當(dāng)有相同標(biāo)簽名的元素切換時(shí)臼寄,需要通過(guò)key特性設(shè)置唯一的值來(lái)標(biāo)記,讓Vue區(qū)分它們溜宽,否則Vue為了效率只會(huì)替換相同標(biāo)簽內(nèi)部的內(nèi)容吉拳。

21、自定義組件的雙向綁定(v-model):綁定value值适揉,監(jiān)聽(tīng)input事件留攒。

22、Vue組件化的理解:

定義:組件是可復(fù)用的Vue實(shí)例嫉嘀,準(zhǔn)確講它們是VueComponent的實(shí)例炼邀,繼承自Vue。

優(yōu)點(diǎn):組件化可以增加代碼的復(fù)用性剪侮,可維護(hù)性和可測(cè)試性拭宁。

使用場(chǎng)景:

通用組件,實(shí)現(xiàn)最基本的功能瓣俯,具有通用性杰标,復(fù)用性,例如按鈕組件降铸,輸入框在旱,布局組件

業(yè)務(wù)組件,完成具體業(yè)務(wù)推掸,具有一定的復(fù)用性桶蝎,例如登錄組件驻仅,輪播圖組件

頁(yè)面組件,組織應(yīng)用各部分獨(dú)立內(nèi)容登渣,需要時(shí)在不同頁(yè)面組件間切換噪服,例如列表頁(yè),詳情頁(yè)組件

如何使用組件:

定義胜茧,Vue.component()粘优,components選項(xiàng),sfc(單文件組件)

分類(lèi)呻顽,有狀態(tài)組件雹顺,fucntional(無(wú)狀態(tài),函數(shù)組件)廊遍,abstract(抽象組件嬉愧,沒(méi)有具體視圖)

通信,props喉前,$emit()/$on()没酣,provide/inject,$children/$parent/$root/$attrs/$listeners

內(nèi)容分發(fā)卵迂,<slot>裕便,<template>,v-slot (v-slot :后邊是插槽名稱(chēng)见咒,=后邊是組件內(nèi)部綁定作用域值的映射偿衰。)

使用及優(yōu)化,is论颅,keep-alive哎垦,異步組件

組件的本質(zhì):

vue中的組件經(jīng)歷如下過(guò)程:組件配置=》VueComponent實(shí)例=》render()=》virtual DOM=》DOM

所以組件的本質(zhì)是產(chǎn)生虛擬DOM

23、動(dòng)態(tài)路由

24恃疯、導(dǎo)航守衛(wèi):

全局守衛(wèi)漏设,每次路由跳轉(zhuǎn)都會(huì)被觸發(fā)

router.beforeEach((to,from,next)=>{ //全局前置守衛(wèi) });

router.beforeResolve((to,from,next)=>{ //全局解析守衛(wèi)})今妄;

router.afterEach((to,from)=>{ //全局后置鉤子})郑口;

路由獨(dú)享的守衛(wèi),寫(xiě)在配置里盾鳞,

beforeEnter(to,from,next)=>{? }

組件內(nèi)的守衛(wèi)犬性,可以在路由組件內(nèi)直接定義路由導(dǎo)航守衛(wèi)

beforeRouteEnter((to,from,next)=>{? })

beforeRouteUpdate((to,from,next)=>{? })

beforeRouteLeave((to,from,next)=>{? ? })

完整的導(dǎo)航解析流程(runQueue):

1)導(dǎo)航被觸發(fā)

2)在失活的組件里調(diào)用離開(kāi)守衛(wèi)

3)調(diào)用全局的beforeEach守衛(wèi)

4)在重用的組件里調(diào)用beforeRouterUpdate守衛(wèi)

5)在路由配置里調(diào)用beforeEnter

6)解析異步路由組件

7)在被激活的組件里調(diào)用beforeRouterEnter

8)調(diào)用全局的beforeResolve守衛(wèi)

9)導(dǎo)航被確認(rèn)

10)調(diào)用全局的afterEach鉤子

11)觸發(fā)DOM更新

12)用創(chuàng)建好的實(shí)例調(diào)用beforeRouteEnter守衛(wèi)中傳給next的回調(diào)函數(shù)

25、vue.js實(shí)現(xiàn)點(diǎn)擊按鈕腾仅,全頁(yè)面切換中英文乒裆?

1)所有組件配置當(dāng)前頁(yè)面所有json數(shù)據(jù),使用$bus.on和$bus.emit通知所有組件

2)配置在一個(gè)大的json中推励,放到app.Vue中鹤耍,讀取不同字段肉迫,通過(guò)props層層傳遞

3)使用Vue-i18n組件

26、vue數(shù)組/對(duì)象來(lái)渲染一個(gè)列表稿黄,修改數(shù)組的某個(gè)值喊衫,視圖是否會(huì)更新?為什么杆怕?

Vue.set(vm.items, indexOfItem, newValue)

Vue.items.splice(indexOfItem, 1, newvalue)

只有在data里初始化的數(shù)據(jù)才是響應(yīng)式的族购,Vue不能檢測(cè)到對(duì)象屬性的添加或刪除,沒(méi)有在data里聲明的屬性不是響應(yīng)式的陵珍。

27寝杖、router-link點(diǎn)擊事件失效,怎么解決的撑教?

在vue中綁定事件的方法:v-on:click=‘函數(shù)名稱(chēng)’;@click = ‘函數(shù)名稱(chēng)’;

在使用了 vue-router 路由時(shí)會(huì)使用 標(biāo)簽來(lái)代替 a 標(biāo)簽跳轉(zhuǎn)朝墩。

解決辦法:加 .native 修飾符

解釋?zhuān)?/p>

1: 因?yàn)樗亲远x標(biāo)簽,根本就沒(méi)有事件和方法伟姐,所以不觸發(fā),加個(gè)native 就是告訴vue 這個(gè)標(biāo)簽現(xiàn)在有主了 它是H5標(biāo)簽 可以加事件了亿卤。

2:父組件要想在子組件監(jiān)聽(tīng)自己的click事件就得加native愤兵,router-link 其實(shí)就是一個(gè)封裝好的 .vue 組件,所以需要 加.native修飾符才能綁定事件

28排吴、Vue常用的修飾符

表單修飾符:

? v-model.lazy,失去焦點(diǎn)秆乳,同步。

? ? v-model.number,讀輸入的值判斷是否可以轉(zhuǎn)換為number

? v-model.trim,輸入內(nèi)容钻哩,首位空格去除

事件修飾符:

? ? v-on:click.prevent--阻止默認(rèn)事件

? ? v-on:click.stop--阻止冒泡

? ? v-on:click.self要求click事件只有在e.target == e.currentTaget的時(shí)候才會(huì)執(zhí)行

? ? v-on:click.once只綁定一次click事件

? ? v-on:click.capture遵循事件捕獲順序屹堰,不是冒泡順序

v-on:scroll.passive = "onScroll" 在移動(dòng)端,觸發(fā)onscroll事件會(huì)讓網(wǎng)頁(yè)變卡街氢,使用這個(gè)修飾符扯键,相對(duì)于給onscroll事件整一個(gè).lazy修飾符。

v-on:click.native 該修飾符把一個(gè)vue組件轉(zhuǎn)化為一個(gè)普通的HTML標(biāo)簽珊肃。

按鍵修飾符:

? v-on:keyDown.enter,按鍵修飾符荣刑,只有enter鍵才執(zhí)行相對(duì)應(yīng)事件;tab,esc等按鍵

? ? v-on:keyDown.ctrl,alt,shift伦乔,meta系統(tǒng)修飾符,要按住相對(duì)應(yīng)的按鍵才能執(zhí)行事件

? v-on:click.right,middle,left鼠標(biāo)按鍵修飾符

29厉亏、axios的相關(guān)問(wèn)題:

axios是一個(gè)基于promise的HTTP庫(kù),可以用在瀏覽器和node.js中烈和。前端最流行的ajax請(qǐng)求庫(kù)爱只。

axios特點(diǎn):

1)基于promise的異步ajax請(qǐng)求庫(kù),支持promise所有的API

2)瀏覽器端/node端都可以使用招刹,瀏覽器中創(chuàng)建XMLHttpRequests

3)支持請(qǐng)求/響應(yīng)攔截器

4)支持請(qǐng)求取消

5)可以轉(zhuǎn)換請(qǐng)求數(shù)據(jù)和響應(yīng)數(shù)據(jù)恬试,并對(duì)響應(yīng)回來(lái)的內(nèi)容自動(dòng)轉(zhuǎn)換成JSON類(lèi)型的數(shù)據(jù)

6)批量發(fā)送多個(gè)請(qǐng)求

7)安全性更高窝趣,客戶(hù)端支持防御XSRF,就是讓你的每個(gè)請(qǐng)求都帶一個(gè)從cookie中拿到的key,根據(jù)瀏覽器同源策略忘渔,假冒的網(wǎng)站是拿不到你cookie中的key,這樣高帖,后臺(tái)就可以輕松辨別出這個(gè)請(qǐng)求是否是用戶(hù)在假冒網(wǎng)站上的誤導(dǎo)輸入,從而采取正確的策略畦粮。

axios常用語(yǔ)法

axios.get(url[, config]) //get請(qǐng)求用于列表和信息查詢(xún)

axios.delete(url[, config]) //刪除

axios.post(url[, data[, config]]) //post請(qǐng)求用于信息的添加

axios.put(url[, data[, config]]) //更新操作

axios.defaults.xxx //請(qǐng)求的默認(rèn)全局配置

axios.interceptors.request.use() //添加請(qǐng)求攔截器

axios.interceptors.response.use() //添加響應(yīng)攔截器

axios.Cancel() //用于創(chuàng)建取消請(qǐng)求的錯(cuò)誤對(duì)象

axios.CancelToken() //用于創(chuàng)建取消請(qǐng)求的token對(duì)象

axios.isCancel() //是否是一個(gè)取消請(qǐng)求的錯(cuò)誤

axios.all(promise) //用于批量執(zhí)行多個(gè)異步請(qǐng)求

axios.spread() //用來(lái)指定接收所有成功數(shù)據(jù)的回調(diào)函數(shù)的方法

axios為什么既能在瀏覽器環(huán)境運(yùn)行又能在服務(wù)器(node)環(huán)境運(yùn)行散址?

axios在瀏覽器端使用XMLHttpRequest對(duì)象發(fā)送ajax請(qǐng)求;在node環(huán)境使用http對(duì)象發(fā)送ajax請(qǐng)求宣赔。

var defaults.adapter = getDefaultAdapter();

function getDefaultAdapter () {

var adapter;

? if (typeof XMLHttpRequest !== 'undefined') {

? ? // 瀏覽器環(huán)境

? ? ? ? adapter = require('./adapter/xhr');

? ? } else if (typeof process !== 'undefined') {

? ? // node環(huán)境

? ? ? ? adapter = require('./adapter/http');

? }

? return adapter;

}

上述代碼预麸,可以看出XMLHttpRequest是一個(gè)API,它為客戶(hù)端提供了在客戶(hù)端和服務(wù)器之間傳輸數(shù)據(jù)的功能儒将;process對(duì)象是一個(gè)global(全局變量)吏祸,提供有關(guān)信息,控制當(dāng)前Node.js進(jìn)程钩蚊。

axios相關(guān)配置屬性:

‘url’是用于請(qǐng)求的服務(wù)器URL

‘method’是創(chuàng)建請(qǐng)求時(shí)使用的方法贡翘,默認(rèn)時(shí)get

‘baseURL’將自動(dòng)加在‘url’前面,除非‘url’是一個(gè)絕對(duì)URL砰逻。它可以通過(guò)設(shè)置一個(gè)‘baseURL’便于為axios實(shí)例的方法傳遞相對(duì)URL

‘transformRequset’允許在向服務(wù)器發(fā)送前鸣驱,修改請(qǐng)求數(shù)據(jù),只能用在‘PUT’蝠咆,‘POST’和‘PATCH’這幾個(gè)請(qǐng)求方法

‘headers’是即將被發(fā)送的自定義請(qǐng)求頭

‘params’是即將與請(qǐng)求一起發(fā)送的URL參數(shù)踊东,必須是一個(gè)無(wú)格式對(duì)象(plainobject)或URLSearchParams對(duì)象

‘a(chǎn)uth’表示應(yīng)該使用HTTP基礎(chǔ)驗(yàn)證,并提供憑據(jù)刚操,username, password

‘proxy’定義代理服務(wù)器的主機(jī)名稱(chēng)和端口

axios相比原生ajax的優(yōu)點(diǎn)(ajax的缺點(diǎn))

ajax是針對(duì)MVC的編程闸翅,不符合現(xiàn)在前端MVVM的浪潮

基于原生的XHR開(kāi)發(fā),XHR本身的架構(gòu)不清晰

30菊霜、懶加載(按需加載路由):

webpack中提供了require.ensure( )來(lái)實(shí)現(xiàn)按需加載坚冀。以前引入路由是通過(guò)import這樣的方式引入,改為const定義的方式進(jìn)行引入占卧。

不進(jìn)行頁(yè)面按需加載引入方式:import? home? from? '../../common/home.vue'

進(jìn)行頁(yè)面按需加載的引入方式:const? home=r=>require.ensure([ ],( )=>r(require('../../comon/home.vue')))

31遗菠、Vue-cli3.0和2.0的區(qū)別:

1)默認(rèn)進(jìn)行懶觀察(lazy observation)

在2.x版本里,不管數(shù)據(jù)多大华蜒,都會(huì)在一開(kāi)始就為其創(chuàng)建觀察者辙纬。當(dāng)數(shù)據(jù)很大時(shí),會(huì)在頁(yè)面載入時(shí)造成明顯的性能壓力叭喜。3.x版本贺拣,只會(huì)對(duì)‘被用于渲染初始可見(jiàn)部分的數(shù)據(jù)’創(chuàng)建觀察者。因此,3.x的觀察者更高效譬涡。

2)更精準(zhǔn)的變更通知

2.x版本中闪幽,使用Vue.set來(lái)給對(duì)象新增一個(gè)屬性時(shí),這個(gè)對(duì)象的所有watcher都會(huì)重新運(yùn)行涡匀;3.x版本中盯腌,只有依賴(lài)那個(gè)屬性的watcher才會(huì)重新運(yùn)行。

3)3.0新加了TypeScript以及PWA的支持陨瘩。

4)部分命令發(fā)生了變化

下載安裝npm? install? -g? vue@cli

刪除了vue list

創(chuàng)建項(xiàng)目vue create

啟動(dòng)項(xiàng)目 npm? run? serve

5)默認(rèn)項(xiàng)目目錄結(jié)構(gòu)也發(fā)生了變化

移除了配置文件目錄腕够,config和build文件夾

移除了static文件夾,新增public文件夾舌劳,并且index.html移動(dòng)到public中

在src文件夾中新增了views文件夾帚湘,用于分類(lèi)視圖組件和公共組件

32、Vue3.0新特性:

1)setup 是新的組件選項(xiàng)甚淡。充當(dāng)在組件內(nèi)部使用入口點(diǎn)大诸。

調(diào)用時(shí)間,創(chuàng)建組件實(shí)例時(shí)贯卦,在初始組件解析后立即調(diào)用资柔。在生命周期方面,它在beforeCreate之后撵割,created之前被調(diào)用建邓。

2)Proxy

3.0表示已經(jīng)放棄使用了Object.defineProperty,而選擇了使用更快的原生Proxy睁枕。消除了之前Vue2.0中基于Object.defineProperty的實(shí)現(xiàn)所存在的很多限制:無(wú)法監(jiān)聽(tīng)屬性的添加和刪除,數(shù)組索引和長(zhǎng)度的變更沸手,并可以支持Map外遇,Set,Weak Map契吉,Weak Set跳仿。

Proxy對(duì)象用于定義基本操作的自定義行為(如,屬性查找捐晶,賦值菲语,枚舉,函數(shù)調(diào)用等)惑灵。通俗講山上,就是在對(duì)目標(biāo)對(duì)象的操作之前提供了攔截,可以對(duì)外界的操作進(jìn)行過(guò)濾和改寫(xiě)英支,修改某些操作的默認(rèn)行為佩憾,這樣可以不直接操作對(duì)象本身,而是通過(guò)操作對(duì)象的代理對(duì)象來(lái)間接來(lái)操作對(duì)象,達(dá)到預(yù)期的目的妄帘。

語(yǔ)法:let? proxy = new Proxy(target楞黄,handler);

參數(shù)target是用Proxy包裝的目標(biāo)對(duì)象(可以是任何類(lèi)型的對(duì)象,包括原生數(shù)組抡驼,函數(shù)鬼廓,甚至另一個(gè)代理)。

參數(shù)handler也是一個(gè)對(duì)象致盟,其屬性是當(dāng)執(zhí)行一個(gè)操作時(shí)定義代理的行為的函數(shù)碎税,也就是子當(dāng)以的行為。

handler可以是空對(duì)象{ }勾邦,則并表示對(duì)proxy操作就是對(duì)目標(biāo)對(duì)象target操作蚣录;但不能設(shè)置為null,會(huì)拋出一個(gè)錯(cuò)誤---Cannot create proxy with a non-object? as? target or handler!

語(yǔ)法層:

new Proxy(target眷篇,handler);

target萎河,表示被代理的對(duì)象

handler,對(duì)代理的對(duì)象做了什么操作

handler {

set( ){ },? // 設(shè)置的時(shí)候干的事情

get( ){ },? // 獲取干的事情

deleteProperty( ){ },? // 刪除

has( ){ },? // 有沒(méi)有這個(gè)東西 ‘xxx’in? obj

apply( ){ },? // 調(diào)用函數(shù)處理

........

}

33蕉饼、vuex刷新數(shù)據(jù)消失:

監(jiān)聽(tīng)頁(yè)面是否刷新虐杯,如果頁(yè)面刷新了,將state對(duì)象存入到sessionStorage/localStorage中昧港。頁(yè)面打開(kāi)之后擎椰,判斷sessionStorage/localStorage中是否存在state對(duì)象,如果存在创肥,則說(shuō)明頁(yè)面是被刷新過(guò)的达舒,將sessionStorage/localStorage中存的數(shù)據(jù)取出來(lái)給vuex中的state賦值。如果不存在叹侄,說(shuō)明是第一次打開(kāi)巩搏,則取vuex中定義的state初始值。

//在頁(yè)面加載時(shí)讀取sessionStorage里的狀態(tài)信息

if (sessionStorage.getItem("store") ) {

this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))

}

//在頁(yè)面刷新時(shí)將vuex里的信息保存到sessionStorage里

window.addEventListener("beforeunload",()=>{

sessionStorage.setItem("store",JSON.stringify(this.$store.state))

})

34趾代、vue怎樣監(jiān)聽(tīng)數(shù)組

vue通過(guò)重寫(xiě)數(shù)組的某些方法來(lái)監(jiān)聽(tīng)數(shù)組變化贯底,重寫(xiě)后的方法中會(huì)手動(dòng)觸發(fā)通知該數(shù)組的所有依賴(lài)進(jìn)行更新(ob.dep.notify( ))。

35撒强、vue手機(jī)端白屏:

手機(jī)白屏主要是因?yàn)轫?yè)面渲染阻塞導(dǎo)致的禽捆,導(dǎo)致的原因有:

1)css文件加載需要一定的時(shí)間,在加載的過(guò)程中頁(yè)面是空白的

解決:將css代碼前置或者內(nèi)聯(lián)html即使用<style>

2)可能是等待異步加載數(shù)據(jù)在渲染頁(yè)面導(dǎo)致白屏飘哨,數(shù)據(jù)量大加載慢胚想,導(dǎo)致數(shù)據(jù)沒(méi)請(qǐng)求到,阻塞頁(yè)面渲染

解決:在手機(jī)顯示的首屏?xí)r同步渲染頁(yè)面杖玲,后續(xù)的數(shù)據(jù)在也頁(yè)面滾動(dòng)(滑屏)時(shí)顿仇,再采取異步請(qǐng)求渲染頁(yè)面

3)手機(jī)頁(yè)面的首屏JS的執(zhí)行會(huì)阻塞頁(yè)面的渲染

解決:盡量不要在首屏html代碼中放置內(nèi)聯(lián)腳本淘正。即:不要使用<script></script>

首頁(yè)白屏優(yōu)化實(shí)踐:

1)SSR,服務(wù)端渲染臼闻。在服務(wù)端將渲染邏輯處理好鸿吆,然后將處理好的HTML直接返回給前端顯示。也可以解決SEO的問(wèn)題述呐,因?yàn)椴恍枰獎(jiǎng)討B(tài)獲取數(shù)據(jù)了惩淳。

2)預(yù)渲染,用prerender-spa-plugin做預(yù)渲染乓搬。下面是常用prerender-spa-plugin的配置思犁,staticDir預(yù)渲染輸出的文件地址,routes要做預(yù)渲染的路由进肯,minify壓縮相關(guān)的配置激蹲,render渲染引擎相關(guān)的配置,可以傳入自自定義的渲染引擎或者直接使用默認(rèn)的PuppeteerRenderer, renderAfterDocumentEvent是渲染引擎配置中的一個(gè)屬性江掩,指當(dāng)某個(gè)事件觸發(fā)時(shí)才執(zhí)行預(yù)渲染学辱。

const path = require('path')

const PrerenderSPAPlugin = require('prerender-spa-plugin')

const Renderer = PrerenderSPAPlugin.PuppeteerRenderer

module.exports = {

? configureWebpack: config => {

? ? let plugins = []

? plugins.push(new PrerenderSPAPlugin({

? ? ? staticDir: path.resolve(__dirname, 'dist'),

? ? ? routes: ['/', '/about'],

? ? ? minify: {

? ? ? collapseBooleanAttributes: true,

? ? ? ? collapseWhitespace: true,

? ? ? ? decodeEntities: true,

? ? ? ? keepClosingSlash: true,

? ? ? ? sortAttributes: true

? ? },

? ? ? renderer: new Renderer({

? ? ? ? renderAfterDocumentEvent: 'custom-render-trigger'

? ? ? })

? }))

? ? config.plugins = [

? ? ? ...config.plugins,

? ? ...plugins

? ]

? }

}

3)骨架屏,loading

36环形、Vue監(jiān)聽(tīng)路由的變化:

1)通過(guò)watch

// 監(jiān)聽(tīng),當(dāng)路由發(fā)生變化的時(shí)候執(zhí)行

watch:{

? $route(to,from){

? ? console.log(to.path);

? }

},

或者

// 監(jiān)聽(tīng),當(dāng)路由發(fā)生變化的時(shí)候執(zhí)行

watch: {

? $route: {

? ? handler: function(val, oldVal){

? ? ? console.log(val);

? ? },

? ? // 深度觀察監(jiān)聽(tīng)

? ? deep: true

}

},

或者

// 監(jiān)聽(tīng),當(dāng)路由發(fā)生變化的時(shí)候執(zhí)行

watch: {

? '$route':'getPath'

},

methods: {

? getPath(){

? ? console.log(this.$route.path);

? }

}

2)通過(guò)vue-router的鉤子函數(shù)beforeRouterEnter / beforeRouteUpdate / beforeRouteLeave

// 監(jiān)聽(tīng)策泣,當(dāng)路由發(fā)生變化的時(shí)候執(zhí)行

beforeRouteEnter(to, from, next){

// 在渲染該組件的對(duì)應(yīng)路由被confirm前調(diào)用

// 不能獲取組件實(shí)例 'this'

// 因?yàn)楫?dāng)鉤子執(zhí)行前,組件實(shí)例還沒(méi)被創(chuàng)建

}抬吟,

beforeRouterUpdate( to, from, next){

// 在當(dāng)前路由改變萨咕,但是該組件被復(fù)用時(shí)調(diào)用

// 舉例來(lái)說(shuō),對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id火本,在/foo/1 和 /foo/2 之間調(diào)轉(zhuǎn)的時(shí)候

// 由于會(huì)渲染同樣的Foo組件危队,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用钙畔。

// 可以訪(fǎng)問(wèn)組件實(shí)例 'this'

},

deforeRouteLeave( to, from, next){

// 導(dǎo)航離開(kāi)該組件的對(duì)應(yīng)路由時(shí)調(diào)用

// 可以訪(fǎng)問(wèn)組件實(shí)例 'this'

}

37交掏、vue的路由跳轉(zhuǎn):

1)router-link

不帶參數(shù):<router-link :to="{name:'home'}">

帶參數(shù):

<router-link :to="{name:'home', params: {id:1}}">

// 路由配置 path: "/home/:id" 或者 path: "/home:id"

// 不配置path ,第一次可請(qǐng)求,刷新頁(yè)面id會(huì)消失

// 配置path,刷新頁(yè)面id會(huì)保留

// html 取參 $route.params.id

// script 取參 this.$route.params.id

<router-link :to="{name:'home', query: {id:1}}">

// query傳參數(shù) (類(lèi)似get,url后面會(huì)顯示參數(shù))

// 路由可不配置

// html 取參 $route.query.id

// script 取參 this.$route.query.id

2)this.$router.push( )---函數(shù)里面調(diào)用

不帶參數(shù)

this.$router.push('/home')

this.$router.push({name:'home'})

this.$router.push({path:'/home'})

query傳參

this.$router.push({name:'home',query: {id:'1'}})

this.$router.push({path:'/home',query: {id:'1'}})

// html 取參 $route.query.id

// script 取參 this.$route.query.id

params傳參

this.$router.push({name:'home',params: {id:'1'}}) // 只能用 name

// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,

// 不配置path ,第一次可請(qǐng)求,刷新頁(yè)面id會(huì)消失

// 配置path,刷新頁(yè)面id會(huì)保留

// html 取參 $route.params.id

// script 取參 this.$route.params.id

query和params區(qū)別:query類(lèi)似 get, 跳轉(zhuǎn)之后頁(yè)面 url后面會(huì)拼接參數(shù),類(lèi)似?id=1, 非重要性的可以這樣傳( 密碼之類(lèi)還是用params),刷新頁(yè)面id還在。params類(lèi)似 post, 跳轉(zhuǎn)之后頁(yè)面 url后面不會(huì)拼接參數(shù) , 但是刷新頁(yè)面id 會(huì)消失

3)this.$router.replace() (用法同上,push)

4)this.$router.go(n) ( )---向前或者向后跳轉(zhuǎn)n個(gè)頁(yè)面刃鳄,n可為正整數(shù)或負(fù)整數(shù)

區(qū)別:

this.$router.push----跳轉(zhuǎn)到指定url路徑,并向history棧中添加一個(gè)記錄钱骂,點(diǎn)擊后退會(huì)返回到上一個(gè)頁(yè)面

this.$router.replace----跳轉(zhuǎn)到指定的url路徑叔锐,但是history棧中不會(huì)有記錄,點(diǎn)擊返回跳轉(zhuǎn)到上上個(gè)頁(yè)面

this.$router.go(n)-----向前或者向后跳轉(zhuǎn)n個(gè)頁(yè)面见秽,n可為正整數(shù)或負(fù)整數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末愉烙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子解取,更是在濱河造成了極大的恐慌步责,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蔓肯,居然都是意外死亡遂鹊,警方通過(guò)查閱死者的電腦和手機(jī)灾梦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)虐先,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人馁筐,你說(shuō)我怎么就攤上這事调限≈勐剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵耻矮,是天一觀的道長(zhǎng)秦躯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)裆装,這世上最難降的妖魔是什么踱承? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮米母,結(jié)果婚禮上勾扭,老公的妹妹穿的比我還像新娘。我一直安慰自己铁瞒,他們只是感情好妙色,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著慧耍,像睡著了一般身辨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芍碧,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天煌珊,我揣著相機(jī)與錄音,去河邊找鬼泌豆。 笑死定庵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的踪危。 我是一名探鬼主播蔬浙,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贞远!你這毒婦竟也來(lái)了畴博?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蓝仲,失蹤者是張志新(化名)和其女友劉穎俱病,沒(méi)想到半個(gè)月后官疲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亮隙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年途凫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咱揍。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡颖榜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出煤裙,到底是詐尸還是另有隱情掩完,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布硼砰,位于F島的核電站且蓬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏题翰。R本人自食惡果不足惜恶阴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望豹障。 院中可真熱鬧冯事,春花似錦、人聲如沸血公。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)累魔。三九已至摔笤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垦写,已是汗流浹背吕世。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梯投,地道東北人命辖。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像分蓖,于是被迫代替她去往敵國(guó)和親吮龄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353