以下內容僅爲個人見解,如有錯誤歡迎指正~
vue
雙向綁定
原理:
vue.js 則是採用數據劫持結合發佈者-訂閱者模式的方式,
通過Object.defineProperty()來劫持各個屬性的setter,getter,
在數據變動時發佈消息給訂閱者,觸發相應的監聽回調。
延伸:
* Object.defineProperty() 是ES5 中一個無法 shim 的特性, 這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的原因。
* Object.defineProperty(對象,屬性,屬性描述符) 用於在一個對象上定義一個新的屬性, 或者修改一個對象現有的屬性,並返回這個對象
實現:
通過Obeject.defineProperty()來監聽數據屬性變動,將數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter和getter。
詳解:
*實現一個監聽器Observer:
給對象的某個值賦值 ==> 觸發setter(監聽到數據變化)==> 通知訂閱者(notify(在調用訂閱者的update方法))
*實現一個訂閱者Watcher:
可以收到屬性的變化通知並執行相應的函數,從而更新視圖。(getter(const dep = new Dep();然後清空,減少性能浪費))
*實現一個解析器Compile:
可以掃描和解析每個節點的相關指令,並根據初始化模板數據以及初始化相應的訂閱器。
watch | computer
共同點:
希望在數據發生改變的時候,數據根據預先定義好的函數,發生“自動”的變化。
區別:
watch擅長處理的場景:一個數據影響多個數據
computed擅長處理的場景:一個數據受多個數據影響
組件傳值
父改子:
ref $ref
父傳子:
props
子傳父:
$emit
兄弟組件:
$on
通用:
利用緩存(store locationstrage 後端....)
延伸:vue監聽子組件生命週期
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
或者
<Child @hook:mounted="doSomething"/>
keep-alive
原理:
Vue 的緩存機制並不是直接存儲 DOM 結構,而是將 DOM 節點抽象成了一個個 VNode節點。
因此,Vue 的 keep-alive 緩存也是基於 VNode節點 而不是直接存儲 DOM 節點。
用法:
<keep-alive>是Vue的內置組件,能在組件切換過程中將狀態保留在內存中,防止重複渲染DOM。
include: 字符串或正則表達式。只有匹配的組件會被緩存。
exclude: 字符串或正則表達式。任何匹配的組件都不會被緩存。
max:最多幾個(vue2之前不生效)
v-if v-for 使用
v-for 優先級高,因此不建議同時使用,可在上層dom 使用 v-if
路由(hash | history + 路由守衛)
hash:
就是指 url 尾巴後的 # 號以及後面的字符,window.location.hash獲取hash值
history:
window.history(可直接寫成history)指向History對象,它表示當前窗口的瀏覽歷史
路由守衛
全局
router.beforeEach((to, from, next) => { // ...})
router.afterEach((to, from) => { // ... })
路由獨享的守衛
const router = new VueRouter({
routes: [ {
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => { // ... }
} ]
})
組件內的守衛
beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave
虛擬dom優缺點
什麼是虛擬dom:
用js模擬一顆dom樹,放在瀏覽器內存中.當你要變更時,虛擬dom使用diff算法進行新舊虛擬dom的比較,將變更放到變更隊列中,
反應到實際的dom樹,減少了dom操作.虛擬DOM將DOM樹轉換成一個JS對象樹,
diff算法逐層比較,刪除,添加操作,但是,如果有多個相同的元素,可能會浪費性能,所以,
react和vue-for引入key值進行區分.
優點:
*虛擬DOM具有批處理和高效的Diff算法,最終表現在DOM上的修改只是變更的部分,可以保證非常高效的渲染,優化性能.
缺點:
*性能差(雖然虛擬 DOM + 合理的優化,足以應對絕大部分應用的性能需求,但在一些性能要求極高的應用中虛擬 DOM 無法進行針對性的極致優化。)
*首次渲染大量DOM時,由於多了一層虛擬DOM的計算,會比innerHTML插入慢。
es6
promise
先執行getData1,在執行getData2
let getData1=new Promise(function(resolve,reject){
$.ajax({
type:"get",
url:".../getData1",
success:function(data){
if(data.state=="200"){
resolve(data.data) // 在異步操作成功時調用
}else{
reject(data.msg); //在異步操作失敗時調用
}
}
});
})
let getData2=new Promise(function(resolve,reject){
$.ajax({
type:"get",
url:".../getData2",
success:function(data){
if(data.state=="200"){
resolve(data.data) // 在異步操作成功時調用
}else{
reject(data.msg); //在異步操作失敗時調用
}
}
});
})
getData1.then(function(res){
return getData2(res)
}).then(function(res){
console.log(res)
}).catch(function(err){
console.log(err)
})
先執行getData1和getData2,在執行getData3
let getData3=new Promise(function(resolve,reject){
$.ajax({
type:"get",
url:".../getData3",
success:function(data){
if(data.state=="200"){
resolve(data.data) // 在異步操作成功時調用
}else{
reject(data.msg); //在異步操作失敗時調用
}
}
});
})
Promise的all方法,等數組中的所有promise對象都完成執行
Promise.all([getData1,getData2]).then(function([ResultJson1,ResultJson2]){
//這裏寫等這兩個ajax都成功返回數據才執行的業務邏輯
getData3()
})
for in | for of
for in 循環的是 index
for of 循環的是 item
proxy
js
數組方法
1.splice(index,howmany,[item1,...]):從數組中添加/刪除元素,返回被刪除項,注意:這個操作會改變原始數組。
2.slice(start,[end]):從已有數組中返回選定元素,此操作不會修改原始數組。
3.shift():刪除數組第一個元素,返回刪除項,改變原始數組,不產生新數組。
4.unshift(newelement1,[...]):在數組開頭添加一或多個元素,並返回新的長度。改變原數組,不產生新數組。
5.pop():刪除數組最後一個元素,並返回刪除的值,若是操作空數組,返回undefined。改變原數組。
6.push(element1,[......]):向數組末尾添加一個或多個元素,返回數組長度。直接修改原數組。
7.concat(arrayX,......):連接兩個或多個數組,返回被連接數組的副本,不會改變原始數組。
8.reverse():顛倒數組元素順序,改變原始數組,不會創建新數組。
9.sort():對現有數組進行排序,改變原始數組。此方法會在排序之前首先對數組的每一項調用toString()方法,再進行排序
10.join([separator]):對數組元素以指定的分隔符進行分隔,參數爲空,默認以“,”進行分隔。返回值是分隔後形成的字符串
數據類型
基本數據類型包括undefined、null、number、boolean、string;
對象類型Object,比如:Object、array、function、data等;
從輸入URL到頁面展示的詳細過程
1、輸入網址
2、DNS解析
3、建立tcp連接
4、客戶端發送HTPP請求
5、服務器處理請求
6、服務器響應請求
7、瀏覽器展示HTML
8、瀏覽器發送請求獲取其他在HTML中的資源。
閉包
閉包是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
通俗的來說就是:JavaScript中所有的function都是一個閉包。不過一般來說,嵌套的function所產生的閉包更爲強大,也是大部分時候我們所謂的“閉包”
當函數a的內部函數b被函數a外的一個變量引用的時候,就創建了一個閉包。