Vue中,key值的作用和原理
作用
key的作用是為了在diff算法執(zhí)行時更快的找到對應(yīng)的節(jié)點偎血,提高diff速度
key具有唯一性
原理
其原理是vue 在patch中的patchVode下的updateChildren會處理新老子節(jié)點可以通過key精準(zhǔn)判斷倆個節(jié)點是否是同一個,如果沒有加key就會強應(yīng)的更新完慧,從而會有頻繁的更新過程柑潦,性能會很差,加了key還會可以使整個patch 過程更加高效市殷,減少dom 操作,提高性能
V-model底層原理
綁定了value屬性與監(jiān)聽了input事件束倍,一旦數(shù)據(jù)改變了被丧,input事件執(zhí)行了盟戏。
V-model的修飾符
lazy
默認(rèn)同步更新,加了之后等光標(biāo)離開之后才會更新
number
如果這個值無法被parseFloat解析甥桂,會原樣返回柿究,如果可以被解析,會返回解析后的值
trim
掉前后空格
雙向數(shù)據(jù)綁定的原理
在Vue中創(chuàng)建vm實例黄选,通過Object.defineProperty方法為數(shù)據(jù)動態(tài)添加setter.getter方法蝇摸,在setter方法完成后觸發(fā)watcher方法,從而數(shù)據(jù)改變了办陷,視圖更新
computed,watch,method區(qū)別
computed
可以依賴多個屬性的變化貌夕,是自執(zhí)行的,依賴緩存進(jìn)行民镜,每次只有相關(guān)依賴發(fā)生變化才會請求值啡专,只有g(shù)etter屬性,不接受傳參制圈,必須有return
watch
只能監(jiān)聽一個變量的改變们童,當(dāng)需要異步請求或者開銷較大的時候使用watch方法,只有setter屬性鲸鹦,接受傳參慧库,沒有return
method
computed中的方法都可以通過method實現(xiàn),每次調(diào)用都需要請求馋嗜,setter齐板、getter都有
為什么data必須是一個函數(shù)
當(dāng)我們的data是一個函數(shù)的時候,每一個實例的data屬性都是獨立的葛菇,組件內(nèi)數(shù)據(jù)不會相互影響
正向代理 反向代理
所謂正向代理就是順著請求的方向進(jìn)行的代理甘磨,即代理服務(wù)器他是由你配置為你服務(wù),去請求目標(biāo)服務(wù)器地址熟呛。
所謂反向代理正好與正向代理相反宽档,代理服務(wù)器是為目標(biāo)服務(wù)器服務(wù)的,雖然整體的請求返回路線都是一樣的都是Client到Proxy到Server庵朝。
單頁應(yīng)用的原理
原理就是通過檢測地址欄變化后將對應(yīng)的路由組件進(jìn)行切換(卸載和安裝)
hash與history的區(qū)別
hash模式較丑,history模式較優(yōu)雅
hash兼容IE8以上又厉,history兼容IE10以上
history模式需要后端配合將所有訪問都指向index.html九府,否則用戶刷新頁面,會導(dǎo)致404錯誤
路由守衛(wèi)
全局路由守衛(wèi)
router.beforeEach 全局前置守衛(wèi) 進(jìn)入路由之前
router.beforeResolve 全局解析守衛(wèi)在beforeRouteEnter調(diào)用之后調(diào)用
router.afterEach 全局后置鉤子 進(jìn)入路由之后
獨享守衛(wèi)
beforeRouteEnter 進(jìn)入路由前
beforeRouteUpdate路由復(fù)用同一個組件時
beforeRouteLeave 離開當(dāng)前路由時
Vuex
解決多組件之間數(shù)據(jù)共享的問題覆致,將組件與組件之間的關(guān)系進(jìn)行了解耦侄旬,強調(diào)集中式管理,變成了組件與倉庫之間的關(guān)系了
Vuex和本地儲存的區(qū)別
Vuex
儲存在內(nèi)存中煌妈,主要用于組件之間傳值儡羔,刷新頁面的時候vuex中儲存的值消失
localstorage
以文件的形式儲存在本地宣羊,只能儲存字符串類型,用于頁面之間傳值汰蜘,一直存在
sessionStorage
臨時保存仇冯,只能儲存字符串類型,用于頁面之間傳值族操,關(guān)閉頁面就清除掉了
P.S.
在數(shù)據(jù)不改變的時候苛坚,localstorage可以代替vuex,但是如果兩個組件共用一個數(shù)據(jù)時色难,如果其中一個組件改變了數(shù)據(jù)泼舱,希望另一個組件響應(yīng)該發(fā)生變化的時,localstorage枷莉、sessionstorage
Vuex五個核心屬性
State:定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu)娇昙,可以在這里設(shè)置默認(rèn)的初始狀態(tài)。
Getter:允許組件從 Store 中獲取數(shù)據(jù)笤妙,mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計算屬性冒掌。
Mutation:是唯一更改 store 中狀態(tài)的方法,且必須是同步函數(shù)危喉。
Action:用于提交 mutation宋渔,而不是直接變更狀態(tài),可以包含任意異步操作辜限。
Module:可以將 store 分割成模塊(module)皇拣。每個模塊擁有自己的 state、mutation薄嫡、action氧急、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割
Vuex的項目結(jié)構(gòu)
Vuex 并不限制你的代碼結(jié)構(gòu)毫深。但是吩坝,它規(guī)定了一些需要遵守的規(guī)則:
1.應(yīng)用層級的狀態(tài)應(yīng)該集中到單個 store 對象中。
2.提交mutation是更改狀態(tài)的唯一方法哑蔫,并且這個過程是同步的钉寝。
3.異步邏輯都應(yīng)該封裝到action里面。
Vuex持久化
vuex有一個痛點闸迷,就是刷新以后vuex里面存儲的state就會被瀏覽器釋放掉嵌纲,因為state都是存儲在內(nèi)存中的。
通過 vuex-persistedstate這個插件腥沽,來實現(xiàn)將數(shù)據(jù)存儲到本地
Axios的高級功能
攔截器的封裝
//引入axios和 qs
import axios from "axios";
import qs from "qs";
/****** 創(chuàng)建axios實例 ******/
const serve = axios.create({
baseURL: process.env.BASE_URL, // api的基本url逮走,也可以直接寫定好的url
timeout: 5000 // 請求超時時間
});
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 => { //請求錯誤處理
Promise.reject(error)
}
);
用axios攔截器
請求之前的攔截 : 一般可以在發(fā)送請求給后端的時候,攜帶一些數(shù)據(jù)給他們
響應(yīng)之后的攔截 : 可以根據(jù)響應(yīng)后的不同的狀態(tài)碼進(jìn)行判斷分析今阳,給前端返回不同的符合條件的數(shù)據(jù)
什么時候使用攔截器
一般在登錄功能的時候师溅,通過vue-router提供的路由守衛(wèi)攔截茅信,token失效了(axios的攔截器進(jìn)行了)
null和undefined的區(qū)別?
type數(shù)據(jù)類型不同
null
沒有對象墓臭,即此處不該有值
undefined
缺少值蘸鲸,此處應(yīng)該有一個值,還沒有定義
自定義指令
作用
操作真實DOM元素
如何定義自定義指令
全局Vue.directive() 局部directives
自定義指令鉤子函數(shù)
bind
inserted
update
componentUpdated
unbind
JS事件中的冒泡事件什么意思
事件到達(dá)事件目標(biāo)之后不會結(jié)束起便,會逐級向上層冒泡棚贾,直到document對象
阻止事件冒泡
e.stopPropagation()
e.cancelBubble = true
實例
搜索框,點擊出現(xiàn)下拉菜單榆综,光標(biāo)依舊存在輸入框
什么是回調(diào)函數(shù)
將B函數(shù)作為參數(shù)傳入到A函數(shù)中妙痹,在執(zhí)行A的時候執(zhí)行B,那就叫做B函數(shù)為回調(diào)函數(shù)鼻疮,如果沒有函數(shù)名稱就叫做匿名函數(shù)
應(yīng)用
Vue在Created異步請求數(shù)據(jù)
Vue組件中父子組件之間如何互相傳值的
通過屬性傳遞的方法傳遞數(shù)據(jù)
父組件聲明一條數(shù)據(jù)怯伊,寫一個更改自身的方法,將更改自身的方法通過屬性傳遞的方式傳給子組件
子組件用props接受父組件傳遞的屬性判沟,調(diào)用父組件傳遞的方法
子父通信
通過事件傳遞的方法傳遞數(shù)據(jù)
父組件綁定一個自定義方法耿芹,子組件通過this.$emit觸發(fā)自定義方法
兄弟通信
通過公共實例傳值
on綁定一個等待觸發(fā)的自定義事件
隔代傳遞
通過綁定ref鏈
ref.$children[0].
怎么將Vue項目中的所有異常信息發(fā)到后臺
利用vue自帶的攔截器
Vue.config.errorHandler = function (err, vm, info) {
// 參數(shù)解析:
// 1.err:錯誤對象;
// 2.vm:Vue實例挪哄;
// 3.info:Vue 特定的錯誤信息吧秕,比如錯誤所在的生命周期鉤子
// 錯誤被捕獲后,不會再在控制臺輸出錯誤信息迹炼,可以補輸出:
console.error(err)
// 然后完成錯誤上報砸彬,一般是發(fā)送到一個收集錯誤的 API 接口
// 如有必要,你還可以把 navigator 對象(客戶端信息)一起上報
}
瀏覽器兼容問題
透明度
opcatity=0.5
filter:alpha(opacity=50)
列表縮進(jìn)問題
消除ul斯入、ol等列表的縮進(jìn)時砂碉,樣式應(yīng)寫成:list-style:none;margin:0px;padding:0px;
經(jīng)驗證,在IE中刻两,設(shè)置margin:0px可以去除列表的上下左右縮進(jìn)增蹭、空白以及列表編號或圓點,設(shè)置padding對樣式?jīng)]有影響磅摹;在 Firefox 中滋迈,設(shè)置margin:0px僅僅可以去除上下的空白,設(shè)置padding:0px后僅僅可以去掉左右縮進(jìn)户誓,還必須設(shè)置list- style:none才能去除列表編號或圓點杀怠。也就是說,在IE中僅僅設(shè)置margin:0px即可達(dá)到最終效果厅克,而在Firefox中必須同時設(shè)置margin:0px、 padding:0px以及l(fā)ist-style:none三項才能達(dá)到最終效果橙依。
圖片間隙
IE6下圖片會有間隙证舟,改變html的排版,或者設(shè)置img為display:block或者設(shè)置vertical-align屬性為vertical-align:top/bottom/middle/text-bottom都可以解決.
es6新增數(shù)組語法
from
把一些集合硕旗,或者長的像數(shù)組的偽數(shù)組轉(zhuǎn)換成真的數(shù)組
of
把參數(shù)合并成一個數(shù)組返回
fill
//數(shù)組中的每一個元素替換成指定值
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 垃圾回收機制的原理
內(nèi)存泄漏:
不再用到的內(nèi)存,沒有及時釋放女责,就叫做內(nèi)存泄漏漆枚。
解決內(nèi)存的泄露,垃圾回收機制會定期找出那些不再用到的內(nèi)存(變量)抵知,然后釋放其內(nèi)存墙基。
現(xiàn)在各大瀏覽器通常采用的垃圾回收機制有兩種方法:標(biāo)記清除,引用計數(shù)刷喜。
標(biāo)記清除:
js中最常用的垃圾回收方式就是標(biāo)記清除残制。當(dāng)變量進(jìn)入環(huán)境時,例如掖疮,在一個函數(shù)中聲明一個變量初茶,就將這個變量標(biāo)記為"進(jìn)入環(huán)境",從邏輯上講浊闪,永遠(yuǎn)不能釋放進(jìn)入環(huán)境變量所占用的內(nèi)存恼布,因為只要執(zhí)行流進(jìn)入相應(yīng)的環(huán)境,就可能會用到它們搁宾。而當(dāng)變量離開環(huán)境時折汞,則將其標(biāo)記為"離開環(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)記"離開環(huán)境"爽待,被回收
引用計數(shù):
言引擎有一張"引用表",保存了內(nèi)存里面所有資源(通常是各種值)的引用次數(shù)奸忽。如果一個值的引用次數(shù)是0堕伪,就表示這個值不再用到了,因此可以將這塊內(nèi)存釋放栗菜。
//如果一個值不再需要了欠雌,引用數(shù)卻不為0,垃圾回收機制無法釋放這塊內(nèi)存疙筹,從而導(dǎo)致內(nèi)存泄漏富俄。
const arr = [1,2,3,4];
console.log("hello world")
//上面的代碼中,數(shù)組[1,2,3,4]是一個值而咆,會占用內(nèi)存霍比。變量arr是僅有的對這個值的引用,因此引用次數(shù)為1盡管后面的代碼沒有用到arr暴备,它是會持續(xù)占用內(nèi)存悠瞬。
//如果增加一行代碼,解除arr對[1,2,3,4]引用,這塊內(nèi)存就可以被垃圾回收機制釋放了浅妆。
let arr = [1,2,3,4];
console.log("hello world");
arr = null;
//上面代碼中望迎,arr重置為null,就解除了對[1凌外,2辩尊,3,4]的引用康辑,引用次數(shù)變成了0摄欲,內(nèi)存就可以釋放出來了。
//因此疮薇,并不是說有了垃圾回收機制胸墙,程序員就輕松了。你還是需要關(guān)注內(nèi)存占用:那些很占空間的值惦辛,一旦不再用到劳秋,你必須檢查是否還存在對它們的引用。如果是的話胖齐,就必須手動解除引用
filter()玻淑、forEach()、map()呀伙、reduce()补履、reduceRight()的區(qū)別
every():對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對每一項都返回 true 剿另,則返回 true箫锤。
some():對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對任一項返回 true 雨女,則返回 true
filter():對數(shù)組中的每一項運行給定函數(shù)谚攒,返回該函數(shù)會返回 true 的項組成的數(shù)組。
forEach():對數(shù)組中的每一項運行給定函數(shù)氛堕。這個方法沒有返回值馏臭。
map():對數(shù)組中的每一項運行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組讼稚。