Socket實現簡單聊天程式
1 vue初識
1.1 學習vue需要改變關注點
001 jQuery和原生js的關注點:節點
002 Vue的關注點:資料
1.2 如何使用vue?
1.2.1 例項化 new Vue()
001 配置選項
el:關聯Vue例項與頁面元素
data:將data中屬性新增到響應式系統中
methods:編寫方法、函式,方法中的this指向例項
002 指令
v-on:繫結事件
var data = { name: 'helloword' }
var vm = new Vue({
el: "#app",
data: data
});
1.2.2 在被接管的html標籤中使用資料{{ }}
1.3 框架模式
1.3.1 複雜的軟體必須有清晰合理的架構,更容易開發、維護和測試
1.3.2 MVVM
001 Model模型:資料處理
002 View檢視:資料展示
003 ViewModel採用雙向繫結
View的變動自動反映在ViewModel,反之亦然
004 核心思想
關注Model的變化,讓MVVM框架利用自己的機制去自動更新DOM,從而把開發者從操作DOM的繁瑣中解脫
005 雙向繫結model的原理:單向繫結+事件
Model -> View: v-bind:value="val"
View -> Model: v-on:input="val=$event.target.value"
<input type="text" v-model="scole.English">
2 配置引數
2.1 el 關聯檢視層 --型別為Selector | ELement
Vue例項的掛載目標(例項中的所有屬性|方法可直接在el中使用)掛載元素會被Vue生成的DOM替換
el:"#app"
2.2 data 關聯資料層
data下的屬性會自動成為vm下的屬性:Vue在例項化時,會遍歷data下所有屬性,把他們變成響應式屬性。
data: {
title: '',
datalist: [{
id: Date.now(),
title: '年前月薪過萬',
done: false,
selected: false
}]
}
2.3 methods 用於方法定義和事件處理函式
methods: {
addItem() {
let data = {
id: Date.now(),
title: this.title,
done: false,
selected: false
}
this.datalist.unshift(data);
this.title = "";
this.$refs.title.focus();
}
}
2.4 computed 寫在該屬性內的屬性為儲存器屬性
computed: {
selectAll: {
get() {
return this.datalist.every(item => item.selected)
},
set(val) {
this.datalist.forEach(item => {
item.selected = val
})
}
}
}
2.5 temmplate 模板
型別:String
如果不指定則以ele所在元素作為模板
2.6 render 渲染函式
型別:Function
template的代替方案
該渲染函式接收一個createElement(target, props, children)方法作為第一個引數用來建立VNode
2.7 watch 監聽屬性
監聽的值被修改時會自動呼叫函式,當需要在資料變化時執行非同步或者開銷較大的操作時,這個方法是最有用的
3 例項屬性
vm下的屬性|方法
可以寫在檢視層的資料是vm例項的屬性|方法
3.1 如何設定一個不可修改的屬性?
屬性特性:一種更深入控制屬性的方式
設定屬性特性:Object.defineProperty(obj, key, descriptor)
3.1.1 值屬性(有自己的值的屬性)
configurable:可配置性 -- 屬性特性的總開關
enumerable:可列舉性
writable:可寫性
value:值
3.1.2 儲存器屬性(本身沒有值,一般用於代理其他資料)
configurable:可配置性
enumberable:可列舉性
get:監聽讀取操作
set:監聽寫入操作
傳統方式設定的屬性,所有的屬性特性預設為true;而通過Object.defineProperty()設定的屬性特性預設為false
3.2 資料改變ui更新的原理:getter & setter
通過Object.defineproperty()把data下的屬性變為儲存器屬性,並寫入vue例項。當這些屬性值發生改變時,檢視將會產生“響應”,及匹配更新為新的值。
001 從new Vue開始,首先通過get、set監聽Data中的資料變化,同時建立Dep用來蒐集使用該Data的Watcher;
002 編譯模板,建立Watcher,並將Dep.target標識為當前Watcher;
003 編譯模板時,如果使用到了Data中的資料,就會觸發Data的get方法,同時呼叫Dep.addSub將Watcher蒐集起來;
004 資料更新時,會觸發Data的set方法,然後呼叫Dep.notify通知所有使用到該Data的Watcher去更新DOM。
3.3 如何設定響應式屬性?
第一種:初始化時寫入data屬性
第二種:Vue.set(target, key, val) | 例項物件.$set()
tip: target物件不能是vue例項,或者vue例項的根資料物件
第三種:數值變異方法
push() | unshift()
pop() | shift()
splice()
sort() | reverse()
4 指令(html的屬性:v-*)
4.1 v-for 可以遍歷陣列|物件
格式:v-for="item in namelist"
v-for="item of namelist"
4.2 v-bind(簡寫 : )
在屬性中新增變數要使用指令v-bind,可以用在任何屬性上,對style和class屬性進行增強
4.3 v-on(簡寫 @ )
本質上使用了事件委託
001 event物件的獲取:在事件觸發時自動寫入vm.$event
不傳參時預設第一個引數為event物件;
傳參必須手動傳遞$event;
002 阻止事件冒泡:v-on:click.stop=""
4.4 v-show(頻繁顯示隱藏)
通過display屬性控制元素的顯示隱藏
4.5 v-if | v-else-if | v-else(不頻繁顯示隱藏)
通過建立|移除的方式控制元素的顯示隱藏
影響頁面效能的幾大因素: 1 節點的頻繁操作
判斷一段js程式碼所花的時間console.time(name); | console.timeEnd(name);
2 事件繫結數量
5 虛擬DOM(Virtual DOM)一個結構類似於真實DOM節點的js物件
5.1 優化方法:優化節點操作 | 優化事件處理
5.2 虛擬DOM是怎樣優化效能的?
001 背後有一套強大的演算法:diff演算法
002 只改變物件初始 | 結束狀態不同部分
diff演算法是進行新舊虛擬節點元素的對比並返回一個用來儲存兩個節點不同的地方的patchs物件,最後再用patchs記錄訊息去區域性的更新檢視層的DOM。diff演算法的本質就是判斷兩個虛擬節點的差異,並將差異更新到真實DOM中。
5.3 diff演算法如何比較同級同類標籤的不同?
001 複用原則 -- 預設
002 key:唯一且穩定
是否使用key取決於實際開發中是否有節點的增加、刪除(結構變動)
// 虛擬DOM大概的樣子
// 初始狀態
{
type: 'div',
attrs: {},
children: [{
type: 'h1',
children: '暴富'
},{
type: 'ul',
children: [{
type: 'li',
children: '養生'
},{
type: 'li',
children: '早睡'
}]
}]
}
// 結束狀態
{
type: 'div',
attrs: {},
children: [{
type: 'h1',
children: '暴富22'
},{
type: 'ul',
children: [{
type: 'li',
children: '養生22'
},{
type: 'li',
children: '早睡22'
}]
}]
}
6 資料繫結
6.1 單向資料繫結(Model -> View)
{{ }}
v-bind: attr
v-text
v-html
6.2 雙向資料繫結
Model -> View: 單向繫結
View -> Model: 事件
v-model 原理: v:bind:value + v-on:input
bind: value = 'val';
v-on: input = '$val=$event.target.value';
例:Todolist
// 01 先完成簡單的結構 + 初始資料(例項物件) // 02 點選新增 View-> Model // 03 點選完成按鈕,切換完成狀態 // 04 點選刪除按鈕,刪除該資料 // 05 點選全選複選框,實現全選|全不選 // 06 使用者體驗優化
api
1 vue.nextTick()
因為DOM至少會在當前tick裡面的程式碼全部執行完畢再更新。所以不可能做到在修改資料後並且DOM更新後再執行,要保證在DOM更新以後再執行某一塊程式碼,就必須把這塊程式碼放在下一次事件迴圈裡面,比如setTimeout(fn, 0),這樣DOM更新後,就會立即執行這塊程式碼。