vue基礎
傳統組件,只是靜態渲染,更新還要依賴於操作dom
vue mvvm用數據驅動視圖
view > dom
viewModel > vue(通過dom監聽,指令等更新渲染)
Model> data
1.computed和watch
-
computed有緩存,data不變則不會重新計算
-
watch監聽引用類型拿不到oldVal,如何進行深度監聽
watch: {
handler(oldVal, val){
// 其中oldVal和val是同一個引用地址
},
deep:true
}
2.v-if和v-show的區別和使用場景
-
v-if是元素直接刪除和生成(交互不頻繁用)
-
v-show是元素顯示和隱藏(經常交互使用)
3.列表循環
-
v-for和v-if不建議一起使用
-
key的重要性
key 的特殊屬性主要用在 Vue 的虛擬 DOM 算法,在新舊 nodes 對比時辨識 VNodes。如果不使用 key,Vue 會使用一種最大限度減少動態元素並且儘可能的嘗試修復/再利用相同類型元素的算法。使用 key,它會基於 key 的變化重新排列元素順序,並且會移除 key 不存在的元素。
key值的作用是:
更精準–>在虛擬dom節點中賦予key值,會更加快速的拿到需要的目標節點,不會造成就地複用的情況,對於節點的把控更加精準。
4.組件通訊方式props和$emit
props:父組件傳值給子組件.
$emit:子組件通過觸發事件去處理事情.
5.生命週期
掛載階段
-
beforeCreated,vue實例還沒初始化
-
created頁面還沒有開始渲染,但是vue實例已經初始化完畢
-
beforeMount虛擬dom替換真實dom前
-
mouted頁面渲染完畢
父子組件中
- 父組件先created,再子組件
- 之後子組件先mouted頁面,再父組件組件
更新階段
- beforeUpdated虛擬dom替換真實dom前
- updated頁面渲染完畢
父子組件中
- 父組件先beforeUpdated,再子組件beforeUpdated
- 之後子組件先updated,再父組件組件updated
銷燬階段
- beforeDestroy銷燬前
- destroyed銷燬完畢
高級特性
1. 自定義v-model
//子組件
<template>
<input type="text" :value="val" @input="$emit('change',$event.target.value)" />
</template>
<script>
export default {
model: {
prop: 'val',
event: 'change'
},
props: {
val: String,
default(){
return ''
}
}
}
</script>
//父組件
<Child v-model="name"></Child>
2.$nextTick
vue是異步渲染,data改變後,Dom不會立刻渲染,$nextTick會在dom渲染後觸發,以獲得最新Dom節點
eg: 比如給一個ul裏新增li,push完成後,雖然頁面也顯示,但是直接取新增的li值是拿不到的.
//等dom全部渲染完再回調
this.$nextTick(()=>{
//操作dom
})
3.solt
2.6後用v-slot和vm.$slots獲取插槽裏面的值
//父頁面
<todo-list>
<template v-slot:todo="slotProps" >
{{slotProps.user.firstName}}
</template>
</todo-list>
//slotProps 可以隨意命名
//slotProps 接取的是子組件標籤slot上屬性數據的集合所有v-bind:user="user"
//子頁面
<slot name="todo" :user="user" :test="test">
{{ user.lastName }}
</slot>
data() {
return {
user:{
lastName:"last",
firstName:"first"
},
test:[1,2,3,4]
}
},
//顯示
// first
// {{ user.lastName }}是默認數據 v-slot:todo 當父頁面沒有(="slotProps")
// 時顯示 last
4.動態組件
根據值動態選擇渲染組件時候使用。
<component :is="currentView"></component>
5. 異步加載組件
使用的時候纔會加載需要的組件,大型組件時候使用可以優化性能
<mycomponent v-if="isShow"></mycomponent>
components:{
mycomponent:()=>import('../mycomponent')
}
6. keep-alive
tap切換使用,單頁面系統
作用:
- 緩存組件
- 平凡切換時候不會重複渲染
- 有兩個單獨的生命週期,activated 和 deactivated
7. mixin
即把一個公共的邏輯部分(data,methods,mounted等)與主頁面進行混合
多個組件共同邏輯抽離。
使用
mixins:[myMinxin]
帶來問題
- 數據來源不明
- 命名衝突
vue原理部分
1. vue響應式原理
核心: Object.defineProperty(2.0)
Proxy(3.0)
(對象)
通過observer定義響應式,裏面通過defineReactive去重新定義屬性進行屬性監聽,其中通過Object.defineProperty中set觸發更新視圖
(數組)
重新定義原型上的幾個數組方法(push,pop,shift,splice…),調用這些方法則會觸發視圖更新
Object.defineProperty缺點
- 深度監聽,需要遞歸到底,一次性計算量大
- 新增屬性/刪除屬性監聽不到(得用vue.set/vue.delete)
- 無法原生監聽數組,需要單獨處理
2.虛擬dom和diff算法
虛擬dom:
用js模擬dom結構,計算出最小變更,操作dom
存在價值:
數據驅動視圖,控制dom操作
vdom結構
<div class="header" id="div1">
<p>內容<p/>
</div>
(tag標籤,props屬性,children子元素)
{
tag:'div',
props:{
className:'header',
id:'div1'
},
children:[
{
tag:"p",
children:'內容'
}
]
}
原因:dom操作非常耗費性能,js計算則很快
diff算法:
- 只比較同一層級,不跨級比較
- tag不同則直接刪除重建,不進行深度比較
- tag和key,兩者都相同,則認爲是相同節點,不再深度比較
3. 模板編譯
- vue template complier將模板編譯爲render函數
- 執行render函數生成vnode
render函數
Vue.component('heading',{
render: function(createElement){
return createElement(
'div',
[createElement('a',{
attrs:{
name:'qw',
href:'www.baidu.com',
},'鏈接'
})]
)
}
})
4. vue組件渲染過程
初次渲染
- 解析模板爲render函數(或在開發環境已完成,vue-loader)
- 觸發響應式,監聽data屬性getter(模板用到了其中屬性就會觸發get)
- 執行render函數,生成vnode,patch(elem,vnode)
更新過程
- 修改data,觸發setter(此前在getter中已經被監聽)
- 重新執行render函數, 生成newVnode
- patch(vnode,newVnode)
異步渲染
- $nextTick
- 彙總data的修改,一次性更新
- 減少dom操作次數,提高性能
前端路由原理
http: 協議 protocol
hostname ip/域名 127.0.0.1
host 127.0.0.1:8881
port 8881
pathname /index.html
search ?a=1&b=2
hash 哈希 ‘#/aaa/bbb’
hash特點
-
hash變化會觸發網頁跳轉,即瀏覽器前進或者後退
-
hash變化不會刷新頁面,spa必須的特點
-
hash變化不會提交到server端
-
通過
window.onhashchange
監聽
h5 history
需要後端配合,只返回index主頁
-
用url規範的路由,但是跳轉不刷新頁面
-
history.pushState({name:'page1'},' ','page1')
-
window.onpopstate = (event)=> {console.log('onpopstate',event.state,location.pathname)}
選擇哪種
-
toB系統,後臺管理系統,推薦用hash,簡單易用,對url規範不敏感
-
toC 的系統,可以考慮H5 history,但是需要服務器支持