Vue中,key值的作用和原理
作用
key的作用是為了在diff算法執(zhí)行時(shí)更快的找到對(duì)應(yīng)的節(jié)點(diǎn),提高diff速度
key具有唯一性
原理
其原理是vue 在patch中的patchVode下的updateChildren會(huì)處理新老子節(jié)點(diǎn)可以通過(guò)key精準(zhǔn)判斷倆個(gè)節(jié)點(diǎn)是否是同一個(gè),如果沒(méi)有加key就會(huì)強(qiáng)應(yīng)的更新,從而會(huì)有頻繁的更新過(guò)程,性能會(huì)很差,加了key還會(huì)可以使整個(gè)patch 過(guò)程更加高效,減少dom 操作,提高性能
V-model底層原理
綁定了value屬性與監(jiān)聽(tīng)了input事件,一旦數(shù)據(jù)改變了,input事件執(zhí)行了。
V-model的修飾符
lazy
默認(rèn)同步更新,加了之后等光標(biāo)離開(kāi)之后才會(huì)更新
number
如果這個(gè)值無(wú)法被parseFloat解析,會(huì)原樣返回,如果可以被解析,會(huì)返回解析后的值
trim
掉前后空格
雙向數(shù)據(jù)綁定的原理
在Vue中創(chuàng)建vm實(shí)例,通過(guò)Object.defineProperty方法為數(shù)據(jù)動(dòng)態(tài)添加setter.getter方法,在setter方法完成后觸發(fā)watcher方法,從而數(shù)據(jù)改變了,視圖更新
computed,watch,method區(qū)別
computed
可以依賴多個(gè)屬性的變化,是自執(zhí)行的,依賴緩存進(jìn)行,每次只有相關(guān)依賴發(fā)生變化才會(huì)請(qǐng)求值,只有g(shù)etter屬性,不接受傳參,必須有return
watch
只能監(jiān)聽(tīng)一個(gè)變量的改變,當(dāng)需要異步請(qǐng)求或者開(kāi)銷(xiāo)較大的時(shí)候使用watch方法,只有setter屬性,接受傳參,沒(méi)有return
method
computed中的方法都可以通過(guò)method實(shí)現(xiàn),每次調(diào)用都需要請(qǐng)求,setter、getter都有
為什么data必須是一個(gè)函數(shù)
當(dāng)我們的data是一個(gè)函數(shù)的時(shí)候,每一個(gè)實(shí)例的data屬性都是獨(dú)立的,組件內(nèi)數(shù)據(jù)不會(huì)相互影響
正向代理 反向代理
所謂正向代理就是順著請(qǐng)求的方向進(jìn)行的代理,即代理服務(wù)器他是由你配置為你服務(wù),去請(qǐng)求目標(biāo)服務(wù)器地址。
所謂反向代理正好與正向代理相反,代理服務(wù)器是為目標(biāo)服務(wù)器服務(wù)的,雖然整體的請(qǐng)求返回路線都是一樣的都是Client到Proxy到Server。
單頁(yè)應(yīng)用的原理
原理就是通過(guò)檢測(cè)地址欄變化后將對(duì)應(yīng)的路由組件進(jìn)行切換(卸載和安裝)
hash與history的區(qū)別
hash模式較丑,history模式較優(yōu)雅
hash兼容IE8以上,history兼容IE10以上
history模式需要后端配合將所有訪問(wèn)都指向index.html,否則用戶刷新頁(yè)面,會(huì)導(dǎo)致404錯(cuò)誤
路由守衛(wèi)
全局路由守衛(wèi)
router.beforeEach 全局前置守衛(wèi) 進(jìn)入路由之前
router.beforeResolve 全局解析守衛(wèi)在beforeRouteEnter調(diào)用之后調(diào)用
router.afterEach 全局后置鉤子 進(jìn)入路由之后
獨(dú)享守衛(wèi)
beforeRouteEnter 進(jìn)入路由前
beforeRouteUpdate路由復(fù)用同一個(gè)組件時(shí)
beforeRouteLeave 離開(kāi)當(dāng)前路由時(shí)
Vuex
解決多組件之間數(shù)據(jù)共享的問(wèn)題,將組件與組件之間的關(guān)系進(jìn)行了解耦,強(qiáng)調(diào)集中式管理,變成了組件與倉(cāng)庫(kù)之間的關(guān)系了
Vuex和本地儲(chǔ)存的區(qū)別
Vuex
儲(chǔ)存在內(nèi)存中,主要用于組件之間傳值,刷新頁(yè)面的時(shí)候vuex中儲(chǔ)存的值消失
localstorage
以文件的形式儲(chǔ)存在本地,只能儲(chǔ)存字符串類(lèi)型,用于頁(yè)面之間傳值,一直存在
sessionStorage
臨時(shí)保存,只能儲(chǔ)存字符串類(lèi)型,用于頁(yè)面之間傳值,關(guān)閉頁(yè)面就清除掉了
P.S.
在數(shù)據(jù)不改變的時(shí)候,localstorage可以代替vuex,但是如果兩個(gè)組件共用一個(gè)數(shù)據(jù)時(shí),如果其中一個(gè)組件改變了數(shù)據(jù),希望另一個(gè)組件響應(yīng)該發(fā)生變化的時(shí),localstorage、sessionstorage
Vuex五個(gè)核心屬性
State:定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu),可以在這里設(shè)置默認(rèn)的初始狀態(tài)。
Getter:允許組件從 Store 中獲取數(shù)據(jù),mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性。
Mutation:是唯一更改 store 中狀態(tài)的方法,且必須是同步函數(shù)。
Action:用于提交 mutation,而不是直接變更狀態(tài),可以包含任意異步操作。
Module:可以將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割
Vuex的項(xiàng)目結(jié)構(gòu)
Vuex 并不限制你的代碼結(jié)構(gòu)。但是,它規(guī)定了一些需要遵守的規(guī)則:
1.應(yīng)用層級(jí)的狀態(tài)應(yīng)該集中到單個(gè) store 對(duì)象中。
2.提交mutation是更改狀態(tài)的唯一方法,并且這個(gè)過(guò)程是同步的。
3.異步邏輯都應(yīng)該封裝到action里面。
Vuex持久化
vuex有一個(gè)痛點(diǎn),就是刷新以后vuex里面存儲(chǔ)的state就會(huì)被瀏覽器釋放掉,因?yàn)閟tate都是存儲(chǔ)在內(nèi)存中的。
通過(guò) vuex-persistedstate這個(gè)插件,來(lái)實(shí)現(xiàn)將數(shù)據(jù)存儲(chǔ)到本地
Axios的高級(jí)功能
攔截器的封裝
//引入axios和 qs
import axios from "axios";
import qs from "qs";
/****** 創(chuàng)建axios實(shí)例 ******/
const serve = axios.create({
baseURL: process.env.BASE_URL, // api的基本url,也可以直接寫(xiě)定好的url
timeout: 5000 // 請(qǐng)求超時(shí)時(shí)間
});
serve.interceptors.request.use(config => {
config.method === 'post'
? config.data = qs.stringify({...config.data})
: config.params = {...config.params};
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
return config;
}, error => { //請(qǐng)求錯(cuò)誤處理
Promise.reject(error)
}
);
用axios攔截器
請(qǐng)求之前的攔截 : 一般可以在發(fā)送請(qǐng)求給后端的時(shí)候,攜帶一些數(shù)據(jù)給他們
響應(yīng)之后的攔截 : 可以根據(jù)響應(yīng)后的不同的狀態(tài)碼進(jìn)行判斷分析,給前端返回不同的符合條件的數(shù)據(jù)
什么時(shí)候使用攔截器
一般在登錄功能的時(shí)候,通過(guò)vue-router提供的路由守衛(wèi)攔截,token失效了(axios的攔截器進(jìn)行了)
null和undefined的區(qū)別?
type數(shù)據(jù)類(lèi)型不同
null
沒(méi)有對(duì)象,即此處不該有值
undefined
缺少值,此處應(yīng)該有一個(gè)值,還沒(méi)有定義
自定義指令
作用
操作真實(shí)DOM元素
如何定義自定義指令
全局Vue.directive() 局部directives
自定義指令鉤子函數(shù)
bind
inserted
update
componentUpdated
unbind
JS事件中的冒泡事件什么意思
事件到達(dá)事件目標(biāo)之后不會(huì)結(jié)束,會(huì)逐級(jí)向上層冒泡,直到document對(duì)象
阻止事件冒泡
e.stopPropagation()
e.cancelBubble = true
實(shí)例
搜索框,點(diǎn)擊出現(xiàn)下拉菜單,光標(biāo)依舊存在輸入框
什么是回調(diào)函數(shù)
將B函數(shù)作為參數(shù)傳入到A函數(shù)中,在執(zhí)行A的時(shí)候執(zhí)行B,那就叫做B函數(shù)為回調(diào)函數(shù),如果沒(méi)有函數(shù)名稱就叫做匿名函數(shù)
應(yīng)用
Vue在Created異步請(qǐng)求數(shù)據(jù)
Vue組件中父子組件之間如何互相傳值的
通過(guò)屬性傳遞的方法傳遞數(shù)據(jù)
父組件聲明一條數(shù)據(jù),寫(xiě)一個(gè)更改自身的方法,將更改自身的方法通過(guò)屬性傳遞的方式傳給子組件
子組件用props接受父組件傳遞的屬性,調(diào)用父組件傳遞的方法
子父通信
通過(guò)事件傳遞的方法傳遞數(shù)據(jù)
父組件綁定一個(gè)自定義方法,子組件通過(guò)this.$emit觸發(fā)自定義方法
兄弟通信
通過(guò)公共實(shí)例傳值
on綁定一個(gè)等待觸發(fā)的自定義事件
隔代傳遞
通過(guò)綁定ref鏈
ref.$children[0].
怎么將Vue項(xiàng)目中的所有異常信息發(fā)到后臺(tái)
利用vue自帶的攔截器
Vue.config.errorHandler = function (err, vm, info) {
// 參數(shù)解析:
// 1.err:錯(cuò)誤對(duì)象;
// 2.vm:Vue實(shí)例;
// 3.info:Vue 特定的錯(cuò)誤信息,比如錯(cuò)誤所在的生命周期鉤子
// 錯(cuò)誤被捕獲后,不會(huì)再在控制臺(tái)輸出錯(cuò)誤信息,可以補(bǔ)輸出:
console.error(err)
// 然后完成錯(cuò)誤上報(bào),一般是發(fā)送到一個(gè)收集錯(cuò)誤的 API 接口
// 如有必要,你還可以把 navigator 對(duì)象(客戶端信息)一起上報(bào)
}
瀏覽器兼容問(wèn)題
透明度
opcatity=0.5
filter:alpha(opacity=50)
列表縮進(jìn)問(wèn)題
消除ul、ol等列表的縮進(jìn)時(shí),樣式應(yīng)寫(xiě)成:list-style:none;margin:0px;padding:0px;
經(jīng)驗(yàn)證,在IE中,設(shè)置margin:0px可以去除列表的上下左右縮進(jìn)、空白以及列表編號(hào)或圓點(diǎn),設(shè)置padding對(duì)樣式?jīng)]有影響;在 Firefox 中,設(shè)置margin:0px僅僅可以去除上下的空白,設(shè)置padding:0px后僅僅可以去掉左右縮進(jìn),還必須設(shè)置list- style:none才能去除列表編號(hào)或圓點(diǎn)。也就是說(shuō),在IE中僅僅設(shè)置margin:0px即可達(dá)到最終效果,而在Firefox中必須同時(shí)設(shè)置margin:0px、 padding:0px以及l(fā)ist-style:none三項(xiàng)才能達(dá)到最終效果。
圖片間隙
IE6下圖片會(huì)有間隙,改變html的排版,或者設(shè)置img為display:block或者設(shè)置vertical-align屬性為vertical-align:top/bottom/middle/text-bottom都可以解決.
es6新增數(shù)組語(yǔ)法
from
把一些集合,或者長(zhǎng)的像數(shù)組的偽數(shù)組轉(zhuǎn)換成真的數(shù)組
of
把參數(shù)合并成一個(gè)數(shù)組返回
fill
//數(shù)組中的每一個(gè)元素替換成指定值
let arr = [1, 2, 3, 4] arr.fill(5) //arr全變成了5
//指定范圍替換
arr.fill(6, 1, 3) //arr=[1,6,6,4]
entries/keys/values
let arr=['a', 'b', 'c'] for(let key of arr.keys()){} //取鍵
for(let value of arr.values()){} //取值
for(let [key, value] of arr.entries()){} //都取
includes
var a = function(){}
[1, 2, 3, 4, a].includes(a) //true
JS 垃圾回收機(jī)制的原理
內(nèi)存泄漏:
不再用到的內(nèi)存,沒(méi)有及時(shí)釋放,就叫做內(nèi)存泄漏。
解決內(nèi)存的泄露,垃圾回收機(jī)制會(huì)定期找出那些不再用到的內(nèi)存(變量),然后釋放其內(nèi)存。
現(xiàn)在各大瀏覽器通常采用的垃圾回收機(jī)制有兩種方法:標(biāo)記清除,引用計(jì)數(shù)。
標(biāo)記清除:
js中最常用的垃圾回收方式就是標(biāo)記清除。當(dāng)變量進(jìn)入環(huán)境時(shí),例如,在一個(gè)函數(shù)中聲明一個(gè)變量,就將這個(gè)變量標(biāo)記為"進(jìn)入環(huán)境",從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境變量所占用的內(nèi)存,因?yàn)橹灰獔?zhí)行流進(jìn)入相應(yīng)的環(huán)境,就可能會(huì)用到它們。而當(dāng)變量離開(kāi)環(huán)境時(shí),則將其標(biāo)記為"離開(kāi)環(huán)境"。
function test(){
var a = 10; //被標(biāo)記"進(jìn)入環(huán)境"
var b = "hello";} //被標(biāo)記"進(jìn)入環(huán)境"
test(); //執(zhí)行完畢后之后,a和b又被標(biāo)記"離開(kāi)環(huán)境",被回收
引用計(jì)數(shù):
言引擎有一張"引用表",保存了內(nèi)存里面所有資源(通常是各種值)的引用次數(shù)。如果一個(gè)值的引用次數(shù)是0,就表示這個(gè)值不再用到了,因此可以將這塊內(nèi)存釋放。
//如果一個(gè)值不再需要了,引用數(shù)卻不為0,垃圾回收機(jī)制無(wú)法釋放這塊內(nèi)存,從而導(dǎo)致內(nèi)存泄漏。
const arr = [1,2,3,4];
console.log("hello world")
//上面的代碼中,數(shù)組[1,2,3,4]是一個(gè)值,會(huì)占用內(nèi)存。變量arr是僅有的對(duì)這個(gè)值的引用,因此引用次數(shù)為1盡管后面的代碼沒(méi)有用到arr,它是會(huì)持續(xù)占用內(nèi)存。
//如果增加一行代碼,解除arr對(duì)[1,2,3,4]引用,這塊內(nèi)存就可以被垃圾回收機(jī)制釋放了。
let arr = [1,2,3,4];
console.log("hello world");
arr = null;
//上面代碼中,arr重置為null,就解除了對(duì)[1,2,3,4]的引用,引用次數(shù)變成了0,內(nèi)存就可以釋放出來(lái)了。
//因此,并不是說(shuō)有了垃圾回收機(jī)制,程序員就輕松了。你還是需要關(guān)注內(nèi)存占用:那些很占空間的值,一旦不再用到,你必須檢查是否還存在對(duì)它們的引用。如果是的話,就必須手動(dòng)解除引用
filter()、forEach()、map()、reduce()、reduceRight()的區(qū)別
every():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)每一項(xiàng)都返回 true ,則返回 true。
some():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)任一項(xiàng)返回 true ,則返回 true
filter():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回該函數(shù)會(huì)返回 true 的項(xiàng)組成的數(shù)組。
forEach():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)。這個(gè)方法沒(méi)有返回值。
map():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。