vue基本使用
1. 文本插值
- JS表達式 yes(只能是表達式霜大,不能是 js 語句)
- 動態(tài)屬性 id
2. watch
watch如何深度監(jiān)聽
watch監(jiān)聽引用類型拟杉,拿不到oldVal
<template>
<div>
<input v-model="name"/>
<input v-model="info.city"/>
</div>
</template>
<script>
export default {
data() {
return {
name: '哈哈',
info: {
city: '北京'
}
}
},
watch: {
name(oldVal, val) {
// eslint-disable-next-line
console.log('watch name', oldVal, val) // 值類型介蛉,可正常拿到 oldVal 和 val
},
info: {
handler(oldVal, val) {
// eslint-disable-next-line
console.log('watch info', oldVal, val) // 引用類型辉哥,拿不到 oldVal 读处。因為指針相同峭跳,此時已經(jīng)指向了新的 val
},
deep: true // 深度監(jiān)聽
}
}
}
</script>
3. computed
computed有緩存,data不變則不會重新計算
<template>
<div>
<p>num {{num}}</p>
<p>double1 {{double1}}</p>
<input v-model="double2"/>
</div>
</template>
<script>
export default {
data() {
return {
num: 20
}
},
computed: {
double1() {
return this.num * 2
},
double2: { // 雙向綁定必須有g(shù)et和set方法
get() {
return this.num * 2
},
set(val) {
this.num = val/2
}
}
}
}
</script>
4. class和style
<template>
<div>
<p :class="{ black: isBlack, yellow: isYellow }">使用 class</p>
<p :class="[black, yellow]">使用 class (數(shù)組)</p>
<p :style="styleData">使用 style</p>
</div>
</template>
<script>
export default {
data() {
return {
isBlack: true,
isYellow: true,
black: 'black',
yellow: 'yellow',
styleData: {
fontSize: '40px', // 轉(zhuǎn)換為駝峰式
color: 'red',
backgroundColor: '#ccc' // 轉(zhuǎn)換為駝峰式
}
}
}
}
</script>
<style scoped>
.black {
background-color: #999;
}
.yellow {
color: yellow;
}
</style>
4. 條件渲染
- v-if v-else 的用法侧漓,可使用變量锅尘,也可使用 === 表達式
- v-if 和 v-show的區(qū)別?
? v-if是通過控制dom節(jié)點的存在與否來控制元素的顯隱布蔗;v-show是通過設(shè)置DOM元素的display樣式藤违,block為顯示忙菠,none為隱藏。
- 使用場景
? 如果需要非常頻繁地切換纺弊,則使用 v-show 較好牛欢;如果在運行時條件很少改變,則使用 v-if 較好淆游。
5. 循環(huán)(列表)渲染
可以用v-for遍歷對象和數(shù)組
key的重要性 (盡量和業(yè)務(wù)相關(guān))
v-for 和v-if 不能一起使用
6. 事件
自定義傳參
事件修飾符:
7. 表單
常見表單項 textarea checkbox radio select
修飾符 lazy number trim
8. vue組件使用
- 父子組件間通訊 props 和 $emit
- 兄弟之間通訊: 自定義事件
? 在外面新建一個名字叫 event.js 的文件傍睹,里面寫
import Vue from 'vue'
export default new Vue()
創(chuàng)建一個vue的實例 就可以調(diào)用 event.on 最后卸載時執(zhí)行event.$off銷毀
- 生命周期(單個組件)
created是vue實例已經(jīng)初始化完成了,但是還沒有渲染 mounted是頁面已經(jīng)渲染完畢 -
生命周期(父子組件)
9. vue高級特性
- 自定義v-model
// 父組件
<p>{{name}}</p>
<CustomVModel v-model="name"/>
// 子組件
<template>
<!-- 例如:vue 顏色選擇 -->
<input type="text"
:value="text1"
@input="$emit('change1', $event.target.value)"
>
<!--
1. 上面的 input 使用了 :value 而不是 v-model
2. 上面的 change1 和 model.event1 要對應(yīng)起來
3. text1 屬性對應(yīng)起來
-->
</template>
<script>
export default {
model: {
prop: 'text1', // 對應(yīng) props text1
event: 'change1'
},
props: {
text1: String,
default() {
return ''
}
}
}
</script>
- $nextTick
vue是異步渲染犹菱,data改變后dom不會立刻渲染拾稳,$nextTick會在DOM渲染后在回調(diào),以獲取最新的dom節(jié)點腊脱。頁面渲染時會將data的修改做整合访得,多次data修改只能渲染一次
- slot 基本使用
? 作用域插槽
// 父組件使用名字叫ScopedSlotDemo的子組件 在父組件里展示子組件的website的title
<ScopedSlotDemo :url="website.url">
<template v-slot="slotProps">
{{slotProps.slotData.title}}
</template>
</ScopedSlotDemo>
<template>
<a :href="url">
<slot :slotData="website">
{{website.subTitle}} <!-- 默認值顯示 subTitle ,即父組件不傳內(nèi)容時 -->
</slot>
</a>
</template>
? 具名插槽
? 在slot上綁定一個name=“名字”陕凹,在父組件里在template里寫v-slot:名字
-
動態(tài)悍抑、異步組件
- 動態(tài)組件:需要根據(jù)數(shù)據(jù),動態(tài)渲染的場景杜耙。即組件類型不確定
<component :is= "子組件的名字" />
- 異步組件:用法
<demo v-if="showDemo"/> <button @click=" showDemo = true "></button> 當(dāng)點擊按鈕時搜骡,顯示demo組件時,加載demo組件 components: { demo: () => import('組件路徑') }
-
keep-alive (緩存組件): 需要頻繁切換且不需要重復(fù)渲染的時候
將需要緩存的組件用<keep-alive>標(biāo)簽包裹起來
-
mixin 可以將多個組件的相同的邏輯抽離出來
將共同的邏輯抽離出來放在一個JS文件里佑女,在需要的頁面通過import引用记靡,在和data同級的位置寫
mixins: [引用的js文件的名字] 可以添加多個,會自動合并起來 這樣就可以在當(dāng)前頁面用引入來的js文件里的data团驱、方法
缺點:
-
變量來源不明確摸吠,不利用閱讀
- 多 mixin 可能會造成命名沖突
- mixin 和組件可能出現(xiàn)多對多的關(guān)系,復(fù)雜度較高
-
10. vuex
- state
- getters
- mutation
- action
api
- dispatch
- commit
- mapState
- mapGetters
- mapActions
- mapMutations
11. vue-router
- 路由模式(hash嚎花、history)
- 路由配置(動態(tài)路由寸痢、懶加載)
vue原理
1. 如何理解MVVM模型
數(shù)據(jù)驅(qū)動視圖,不用我們操作DOM贩幻,只需要關(guān)注數(shù)據(jù)轿腺,數(shù)據(jù)變了,視圖就會變
MVVM分為三個部分:分別是M(Model丛楚,模型層 )族壳,V(View,視圖層)趣些,VM(ViewModel仿荆,V與M連接的橋梁,也可以看作為控制器)
1、 M:模型層拢操,主要負責(zé)業(yè)務(wù)數(shù)據(jù)相關(guān)锦亦;
2、 V:視圖層令境,顧名思義杠园,負責(zé)視圖相關(guān),細分下來就是html+css層舔庶;
3抛蚁、 VM:V與M溝通的橋梁,負責(zé)監(jiān)聽M或者V的修改惕橙,是實現(xiàn)MVVM雙向綁定的要點瞧甩;
MVVM支持雙向綁定,意思就是當(dāng)M層數(shù)據(jù)進行修改時弥鹦,VM層會監(jiān)測到變化肚逸,并且通知V層進行相應(yīng)的修改,反之修改V層則會通知M層數(shù)據(jù)進行修改彬坏,以此也實現(xiàn)了視圖與模型層的相互解耦朦促;
2. vue響應(yīng)式
核心API - Object.defineProperty
深度監(jiān)聽對象的時候需要用到 for in 定義一個方法 ,遍歷對象苍鲜,通過判斷遍歷出來的屬性是一個值還是對象思灰,如果是對象的話玷犹,就需要再次調(diào)用這個方法混滔,再次遍歷,直到遍歷到底歹颓。
Object.defineProperty 的缺點
- 深度監(jiān)聽坯屿,需要遞歸到底,一次性計算量大
- 無法監(jiān)聽新增屬性/刪除屬性(vue.set vue.delete)
- 無法監(jiān)聽數(shù)組巍扛,需要特殊處理
3. 虛擬DOM(vdom)和 diff
vodm:用js模擬DOM結(jié)構(gòu)领跛,計算出最小的變更,操作DOM
用js模擬DOM結(jié)構(gòu)
vdom核心概念: h vnode patch diff key 等
- patch:path(elem, vnode) 和 patch(vnode, newvnode)
vdom存在的價值:數(shù)據(jù)驅(qū)動試圖撤奸,控制DOM操作
你知道Vue中key的作用和工作原理嗎吠昭?說說你對它的理解。
- key的主要作用是為了高效的更新虛擬DOM胧瓜,其原理是vue在patch過程中通過key可以精準(zhǔn)判斷兩個節(jié)點是否是同一個矢棚,從而避免頻繁更新不同元素,使得整個patch過程更加高效府喳,減少DOM操作量蒲肋,提高性能。
- 另外,若不設(shè)置key還可能在列表更新時引發(fā)一些隱藏的bug
- vue中在使用相同標(biāo)簽名元素的過渡切換時兜粘,也會使用到key屬性申窘,其目的也是為了讓vue可以區(qū)分它們,否則vue只會替換其內(nèi)部屬性而不會觸發(fā)過渡效果孔轴。
4. 模板編譯
- 會將template編譯成一個 render函數(shù)剃法,里面是with語法的函數(shù)體(類似于h函數(shù)),最后返回vnode路鹰。
- 基于vnode在執(zhí)行patch和diff玄窝。
- 使用webpack-vue-loader,會在開發(fā)環(huán)境編譯模板
const template = `
<div id="div1" class="container">
<img :src="imgUrl"/>
</div>`
with(this){return _c('div', // 標(biāo)簽
{staticClass:"container",attrs:{"id":"div1"}}, // 屬性
[
_c('img',{attrs:{"src":imgUrl}})])} // 子元素
5. 組件渲染/更新過程
- 初次渲染過程
- 解析模板為render函數(shù)(或在開發(fā)環(huán)境已完成悍引, vue-loader)
- 觸發(fā)響應(yīng)式恩脂,監(jiān)聽data屬性getter,setter
- 執(zhí)行render函數(shù)趣斤,生成vnode俩块,path(elem, vnode)
- 更新過程
- 修改data,觸發(fā)setter(此前在getter中已被監(jiān)聽)
- 重新執(zhí)行render函數(shù)浓领,生成newVnode
-
patch(vnode, newvnode)
6. 異步渲染
- $nextTick
- 匯總data的修改玉凯,一次性更新視圖
- 減少DOM操作次數(shù),提高性能