點(diǎn)擊在線閱讀饮醇,體驗(yàn)更好 | 鏈接 |
---|---|
現(xiàn)代JavaScript高級小冊 | 鏈接 |
深入淺出Dart | 鏈接 |
現(xiàn)代TypeScript高級小冊 | 鏈接 |
linwu的算法筆記?? | 鏈接 |
Vue 3 簡介
Vue 3 是一個(gè)流行的開源JavaScript框架茧球,用于構(gòu)建用戶界面和單頁面應(yīng)用切黔。它帶來了許多新特性和改進(jìn)摔敛,包括更好的性能翼雀、更小的打包大小欢峰、更好的TypeScript支持瓦呼、全新的組合式 API,以及一些新的內(nèi)置組件庐椒。
1. Vue 3 的新特性
Vue 3引入了許多新特性椒舵,包括:
- 組合式API:這是Vue 3最重要的新特性之一,它允許更靈活约谈、更邏輯化地組織代碼笔宿。
- 更好的性能:Vue 3的虛擬DOM重寫,提供了更快的掛載棱诱、修補(bǔ)和渲染速度泼橘。
- 更小的打包大小:由于新的架構(gòu)和樹搖技術(shù)迈勋,Vue 3的打包大小比Vue 2小炬灭。
- 更好的TypeScript支持:Vue 3在內(nèi)部使用了TypeScript,因此它為開發(fā)者提供了更好的TypeScript支持靡菇。
2. 與 Vue 2 的區(qū)別
Vue 3與Vue 2的主要區(qū)別包括:
- 構(gòu)建:Vue 3使用monorepo架構(gòu)重归,更容易管理和維護(hù)。
- API:Vue 3引入了新的組合式API厦凤,它提供了更靈活的代碼組織方式鼻吮。
- 性能:Vue 3提供了更好的性能,包括更快的渲染速度和更小的打包大小较鼓。
- TypeScript:Vue 3提供了更好的TypeScript支持狈网。
3. 全新的核心架構(gòu)
Vue 3的核心架構(gòu)進(jìn)行了全面的重寫和優(yōu)化,以提高性能和靈活性。此外拓哺,Vue 3還引入了許多新的API和組件勇垛,以滿足現(xiàn)代web開發(fā)的需求。
基礎(chǔ)
1. 創(chuàng)建 Vue 3 項(xiàng)目
首先士鸥,我們需要通過Vite創(chuàng)建一個(gè)新的Vue 3項(xiàng)目闲孤。你可以通過下面的命令安裝Vite:
pnpm create vite
然后,你可以通過下面的命令創(chuàng)建一個(gè)新的Vue 3項(xiàng)目:
pnpm create vite my-vue-app --template vue-ts
2. 應(yīng)用和組件編寫
在Vue 3中烤礁,我們可以使用新的組合式API創(chuàng)建和管理組件讼积。下面是一個(gè)簡單的Vue 3組件示例:
<template>
<div>
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => { count.value++ }
return {
count,
increment
}
}
}
</script>
在這個(gè)示例中,我們首先導(dǎo)入了 ref
函數(shù)脚仔,然后在 setup
函數(shù)中使用 ref
創(chuàng)建了一個(gè)響應(yīng)式值 count
勤众。我們還定義了一個(gè) increment
函數(shù),用于增加 count
的值鲤脏。最后们颜,我們將 count
和 increment
返回給模板,以便在模板中使用它們猎醇。
響應(yīng)式系統(tǒng)
1. 響應(yīng)式原理
Vue的響應(yīng)式系統(tǒng)是其核心特性之一窥突,它使得數(shù)據(jù)變更能夠自動(dòng)更新到UI上缝左。在Vue 3中褒链,這個(gè)系統(tǒng)基于JavaScript的
Proxy
對象重寫,提供了更好的性能和更多的功能部默。
2. ref 和 reactive
Vue 3提供了兩個(gè)主要的函數(shù)來創(chuàng)建響應(yīng)式數(shù)據(jù):ref
和 reactive
沦疾。
ref
函數(shù)創(chuàng)建一個(gè)響應(yīng)式引用称近。在模板中,你可以直接使用響應(yīng)式引用的值哮塞,而在JavaScript代碼中煌茬,你需要通過 .value
屬性來訪問或修改它的值。
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
count.value++ // 1
reactive
函數(shù)創(chuàng)建一個(gè)響應(yīng)式對象彻桃。你可以直接訪問和修改它的屬性。
import { reactive } from 'vue'
const state = reactive({ count: 0 })
console.log(state.count) // 0
state.count++ // 1
3. 實(shí)現(xiàn)機(jī)制區(qū)別
ref
和 reactive
的主要區(qū)別在于晾蜘,ref
是為了讓基本類型(如數(shù)字和字符串)可以變?yōu)轫憫?yīng)式邻眷,而 reactive
是為了讓對象變?yōu)轫憫?yīng)式。
ref
創(chuàng)建的響應(yīng)式數(shù)據(jù)需要通過 .value
屬性進(jìn)行訪問和修改剔交,而 reactive
創(chuàng)建的響應(yīng)式對象可以直接訪問和修改其屬性肆饶。因此,ref
更適合于處理基本類型岖常,而 reactive
更適合于處理對象驯镊。
組合式 API
組合式API是Vue 3的重要新特性,它提供了一種更靈活、更邏輯化的方式來組織和復(fù)用代碼板惑。
1. setup 函數(shù)
在Vue 3中橄镜,你可以使用 setup
函數(shù)來使用組合式API。setup
函數(shù)是組件的入口點(diǎn)冯乘,在組件實(shí)例被創(chuàng)建和初始化之后洽胶,但在渲染發(fā)生之前被調(diào)用。
export default {
setup() {
// 在這里使用組合式 API
}
}
2. 響應(yīng)式編程
你可以在 setup
函數(shù)中使用 ref
和 reactive
來創(chuàng)建響應(yīng)式數(shù)據(jù)裆馒。
import
{ ref, reactive } from 'vue'
export default {
setup() {
const count = ref(0)
const state = reactive({ name: 'Vue' })
return {
count,
state
}
}
}
3. 計(jì)算屬性與監(jiān)視
你可以使用 computed
和 watch
來創(chuàng)建計(jì)算屬性和監(jiān)視響應(yīng)式數(shù)據(jù)的變化姊氓。
import { ref, computed, watch } from 'vue'
export default {
setup() {
const count = ref(0)
const doubled = computed(() => count.value * 2)
watch(count, (newValue, oldValue) => {
console.log(`count changed from ${oldValue} to ${newValue}`)
})
return {
count,
doubled
}
}
}
4. 生命周期鉤子
你可以在
setup
函數(shù)中使用生命周期鉤子,比如 onMounted
喷好、onUpdated
和 onUnmounted
翔横。
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('component mounted')
})
onUpdated(() => {
console.log('component updated')
})
onUnmounted(() => {
console.log('component unmounted')
})
}
}
5. 自定義 hooks
你可以創(chuàng)建自定義的hooks來復(fù)用代碼。一個(gè)自定義hook就是一個(gè)函數(shù)梗搅,它可以使用其他的響應(yīng)式數(shù)據(jù)和組合式API禾唁。
import { ref, onMounted } from 'vue'
function useCounter() {
const count = ref(0)
const increment = () => {
count.value++
}
onMounted(() => {
console.log('counter mounted')
})
return {
count,
increment
}
}
export default {
setup() {
const counter = useCounter()
return {
counter
}
}
}
高級功能
1. 淺層響應(yīng)式
在某些情況下,你可能想要?jiǎng)?chuàng)建一個(gè)淺層的響應(yīng)式對象些膨,這樣其內(nèi)部的屬性不會被轉(zhuǎn)化為響應(yīng)式的蟀俊。這可以通過 shallowReactive
函數(shù)來實(shí)現(xiàn)。
import { shallowReactive } from 'vue'
const state = shallowReactive({ count: 0 })
2. 只讀數(shù)據(jù)
你可以使用 readonly
函數(shù)來創(chuàng)建一個(gè)只讀的響應(yīng)式對象订雾。任何試圖修改只讀對象的操作都將在開發(fā)環(huán)境下引發(fā)一個(gè)錯(cuò)誤肢预。
import { readonly } from 'vue'
const state = readonly({ count: 0 })
3. 自定義 Ref
你可以使用 customRef
函數(shù)來創(chuàng)建一個(gè)自定義的響應(yīng)式引用。這允許你控制和觀察當(dāng)引用的值發(fā)生變化時(shí)的行為洼哎。
import { customRef } from 'vue'
const count = customRef((track, trigger) => {
let value = 0
return {
get() {
track()
return value
},
set(newValue) {
value = newValue
trigger()
}
}
})
4. toRefs 和 toRef
當(dāng)我們從 setup
函數(shù)返回一個(gè)響應(yīng)式對象時(shí)烫映,對象的屬性將失去響應(yīng)式。為了防止這種情況噩峦,我們可以使用 toRefs
或 toRef
函數(shù)锭沟。
import { reactive, toRefs } from 'vue'
export default {
setup() {
const state = reactive({ count: 0 })
return {
...toRefs(state)
}
}
}
新組件
1. Fragment
在Vue 3中,你可以在一個(gè)組件的模板中有多個(gè)根節(jié)點(diǎn)识补,這被稱為 Fragment族淮。
<template>
<div>Hello</div>
<div>World</div>
</template>
2. Teleport
Teleport 組件允許你將子組件渲染到DOM的任何位置,而不僅僅是它的父組件中凭涂。
<teleport to="#modal">
<div>This will be rendered wherever the #modal element is.</div>
</teleport>
3. Suspense
Suspense 組件允許你等待一個(gè)或多個(gè)異步組件祝辣,然后顯示一些備用內(nèi)容,直到所有的異步組件都被解析切油。
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
深入編譯優(yōu)化
Vue 3在編譯優(yōu)化上做出了很大的提升蝙斜。在編譯過程中,Vue 3對模板進(jìn)行靜態(tài)分析澎胡,提取出不會改變的部分孕荠,預(yù)編譯為純JavaScript娩鹉,這大大提高了運(yùn)行時(shí)的渲染效率。下面詳細(xì)介紹一下這些優(yōu)化稚伍。
靜態(tài)節(jié)點(diǎn)提升
在 Vue 3 中弯予,如果你的模板中有不會改變的部分,例如:
<template>
<div>
<h1>Hello, world!</h1>
<p>Welcome to Vue 3</p>
</div>
</template>
在編譯時(shí)槐瑞,"Hello, world!" 和 "Welcome to Vue 3" 這些靜態(tài)節(jié)點(diǎn)將會被提升熙涤,避免了每次渲染時(shí)都需要重新創(chuàng)建。
片段困檩、模板并用
在 Vue 3 中祠挫,你可以在一個(gè)組件模板中有多個(gè)根節(jié)點(diǎn),這就是片段:
<template>
<header>Header</header>
<main>Main content</main>
<footer>Footer</footer>
</template>
在這個(gè)示例中悼沿,我們有三個(gè)根節(jié)點(diǎn)等舔,這在 Vue 2 中是不允許的。但在 Vue 3 中糟趾,這是完全正常的慌植。
動(dòng)態(tài)編譯
Vue 3 的動(dòng)態(tài)編譯可以讓我們在運(yùn)行時(shí)編譯模板字符串,例如义郑,我們可以動(dòng)態(tài)創(chuàng)建一個(gè)Hello組件
:
import { compile, h } from 'vue'
const template = `<h1>{{ greeting }} World!</h1>`
const render = compile(template)
export default {
data() {
return {
greeting: 'Hello',
}
},
render
}
在這個(gè)例子中蝶柿,我們在運(yùn)行時(shí)編譯了模板字符串,并將結(jié)果設(shè)置為組件的渲染函數(shù)非驮。這種技術(shù)在需要?jiǎng)討B(tài)生成模板的場景中非常有用交汤,比如在一個(gè) CMS 中渲染用戶提供的模板。
深入組件化
Vue 3在組件化方面也有很多進(jìn)步劫笙,下面詳細(xì)介紹一下芙扎。
動(dòng)態(tài)組件
Vue 3支持使用component
標(biāo)簽來動(dòng)態(tài)加載組件,組件可以是一個(gè)組件選項(xiàng)對象填大,也可以是一個(gè)組件的名字戒洼。這個(gè)特性在根據(jù)不同的狀態(tài)顯示不同組件時(shí)非常有用。
<component :is="currentComponent"></component>
異步組件
Vue 3 支持異步組件允华,你可以使用defineAsyncComponent
方法來定義一個(gè)異步組件圈浇,該方法接收一個(gè)返回 Promise 的工廠函數(shù),Promise 需要解析為一個(gè)組件靴寂。
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
高階組件
高階組件(Higher-Order Component磷蜀,簡稱 HOC)是一種設(shè)計(jì)模式,它是接收一個(gè)組件并返回一個(gè)新組件的函數(shù)榨汤。在 Vue 3 中,你可以使用組合式 API 來更容易地創(chuàng)建高階組件怎茫。
import { ref } from 'vue'
export default function withHover(Component) {
return {
setup(props, { slots }) {
const isHovered = ref(false)
return () => (
<div
onMouseenter={() => (isHovered.value = true)}
onMouseleave={() => (isHovered.value = false)}
>
<Component {...props} isHovered={isHovered.value} v-slots={slots} />
</div>
)
}
}
}
在這個(gè)例子中收壕,withHover
函數(shù)接收一個(gè)組件妓灌,并返回一個(gè)新的組件,新的組件有一個(gè) isHovered
屬性蜜宪,表示鼠標(biāo)是否懸停在組件上虫埂。這種模式可以幫助我們在不同的組件間復(fù)用邏輯。
其它組合API
computed
computed
函數(shù)用于創(chuàng)建一個(gè)響應(yīng)式的計(jì)算屬性圃验。這個(gè)屬性的值是由提供的 getter 函數(shù)計(jì)算得出掉伏,并且只有當(dāng)它的依賴項(xiàng)改變時(shí)才會重新計(jì)算。
import { ref, computed } from 'vue'
export default {
setup() {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
return {
count,
doubleCount
}
}
}
在這個(gè)示例中澳窑,我們創(chuàng)建了一個(gè) doubleCount
計(jì)算屬性斧散,它的值始終是 count
的兩倍。
watch 和 watchEffect
watch
和 watchEffect
函數(shù)用于觀察一個(gè)或多個(gè)響應(yīng)式引用或函數(shù)摊聋,并在其值改變時(shí)執(zhí)行副作用鸡捐。
import { ref, watch, watchEffect } from 'vue'
export default {
setup() {
const count = ref(0)
watch(count, (newCount, oldCount) => {
console.log(`Count changed from ${oldCount} to ${newCount}`)
})
watchEffect(() => {
console.log(`Count is ${count.value}`)
})
return {
count
}
}
}
在這個(gè)示例中,我們使用 watch
函數(shù)觀察 count
麻裁,并在其值改變時(shí)打印消息箍镜。我們還使用 watchEffect
函數(shù)創(chuàng)建了一個(gè)副作用,它會在 count
改變時(shí)立即執(zhí)行煎源。
lifecycle hooks
在 Vue 3 中色迂,你可以在 setup
函數(shù)中直接使用生命周期鉤子函數(shù),例如 onMounted
手销,onUpdated
和 onUnmounted
歇僧。
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('Component is mounted')
})
onUpdated(() => {
console.log('Component is updated')
})
onUnmounted(() => {
console.log('Component is unmounted')
})
}
}
在這個(gè)示例中,我們在組件掛載原献、更新和卸載時(shí)打印消息馏慨。
這些是 Vue 3 中提供的更為高級的響應(yīng)式 API,讓我們逐一了解它們姑隅。
shallowReactive 與 shallowRef
shallowReactive
和 shallowRef
允許我們創(chuàng)建一個(gè)淺層的響應(yīng)式對象写隶。對于 shallowReactive
,只有對象的第一層屬性會變?yōu)轫憫?yīng)式的讲仰,對象的更深層次的屬性不會被轉(zhuǎn)換慕趴。shallowRef
是 ref
的淺層版本,它不會自動(dòng)解包內(nèi)部的值鄙陡。
import { shallowReactive, shallowRef } from 'vue'
const obj = shallowReactive({ a: { b: 1 } })
obj.a.b // 這不是一個(gè)響應(yīng)式的值
const num = shallowRef(1)
num.value // 你需要使用 .value 才能訪問到值
readonly 與 shallowReadonly
readonly
和 shallowReadonly
允許我們創(chuàng)建一個(gè)只讀的響應(yīng)式對象冕房。對于 readonly
,對象的所有屬性(包括嵌套屬性)都會變?yōu)橹蛔x趁矾。shallowReadonly
是 readonly
的淺層版本耙册,只有對象的第一層屬性會變?yōu)橹蛔x。
import { readonly, shallowReadonly } from 'vue'
const obj = readonly({ a: { b: 1 } })
obj.a = 2 // 這會拋出一個(gè)錯(cuò)誤
const shallowObj = shallowReadonly({ a: { b: 1 } })
shallowObj.a.b = 2 // 這不會拋出錯(cuò)誤
toRaw 與 markRaw
toRaw
和 markRaw
允許我們逃避 Vue 的響應(yīng)式系統(tǒng)毫捣。toRaw
可以返回一個(gè)對象的原始版本详拙,而 markRaw
可以防止一個(gè)對象被轉(zhuǎn)換為響應(yīng)式的帝际。
import { reactive, toRaw, markRaw } from 'vue'
const obj = reactive({ a: 1 })
const rawObj = toRaw(obj) // rawObj 是 obj 的原始版本
const nonReactiveObj = markRaw({ a: 1 }) // nonReactiveObj 不會被轉(zhuǎn)換為響應(yīng)式的
customRef
customRef
允許我們創(chuàng)建一個(gè)自定義的 ref,我們可以控制它何時(shí)觸發(fā)依賴追蹤和更新饶辙。
import { customRef } from 'vue'
const myRef = customRef((track, trigger) => ({
get() {
track()
return someValue
},
set(newValue) {
someValue = newValue
trigger()
}
}))
provide 與 inject
provide
和 inject
是 Vue 3 的依賴注入 API蹲诀,可以用于在組件樹中傳遞值,而不必一層一層地通過 props 傳遞弃揽。
import { provide, inject } from 'vue'
// 在父組件中
provide('myValue', 123)
// 在子組件中
const myValue = inject('myValue') // myValue 現(xiàn)在是 123
響應(yīng)式判斷
Vue 3 提供了 isReactive
和 isRef
函數(shù)脯爪,用于檢查一個(gè)值是否是響應(yīng)式的或者一個(gè) ref。
import { reactive, ref, isReactive, isRef } from 'vue'
const obj = reactive({ a: 1 })
isReactive(obj) // true
const num = ref(1)
isRef(num) // true
這些 API 提供了更多的控制和靈活性矿微,使我們能夠根據(jù)需要來選擇如何使用 Vue 的響應(yīng)式系統(tǒng)痕慢。
深入響應(yīng)式系統(tǒng)
Vue 3 的響應(yīng)式系統(tǒng)構(gòu)建在一個(gè)名為 effect
的函數(shù)基礎(chǔ)之上,它被用來收集依賴項(xiàng)(依賴追蹤)和觸發(fā)副作用冷冗。當(dāng)一個(gè)響應(yīng)式對象的屬性被訪問時(shí)守屉,effect
將其收集為依賴項(xiàng);當(dāng)一個(gè)響應(yīng)式對象的屬性被修改時(shí)蒿辙,它將觸發(fā)關(guān)聯(lián)的副作用拇泛。
effect、reactive思灌、ref
reactive
和 ref
是 Vue 3 的兩種基本響應(yīng)式 API俺叭。它們都使用 effect
來跟蹤依賴項(xiàng)和觸發(fā)更新。
import { effect, reactive, ref } from 'vue'
// 使用 reactive
const state = reactive({ a: 1 })
effect(() => {
console.log(state.a)
})
state.a = 2 // 打印 "2"
// 使用 ref
const count = ref(0)
effect(() => {
console.log(count.value)
})
count.value++ // 打印 "1"
在這個(gè)示例中泰偿,我們創(chuàng)建了一個(gè)響應(yīng)式對象和一個(gè) ref熄守,然后使用 effect
創(chuàng)建了兩個(gè)副作用,它們分別打印出對象和 ref 的值耗跛。當(dāng)這些值被改變時(shí)裕照,副作用就會被觸發(fā)。
track调塌、trigger
track
和 trigger
是 Vue 3 的底層 API晋南,它們分別被用來收集依賴項(xiàng)和觸發(fā)更新。
import { reactive, effect, track, trigger } from 'vue'
const state = reactive({ a: 1 })
effect(() => {
// 手動(dòng)進(jìn)行依賴追蹤
track(state, 'a')
console.log(state.a)
})
state.a = 2 // 打印 "2"
// 手動(dòng)觸發(fā)更新
trigger(state, 'a')
在這個(gè)示例中羔砾,我們使用 track
手動(dòng)收集了 state.a
作為依賴項(xiàng)负间,然后使用 trigger
手動(dòng)觸發(fā)了更新。
嵌套結(jié)構(gòu)處理
Vue 3 的響應(yīng)式系統(tǒng)可以處理嵌套的響應(yīng)式對象姜凄。
import { reactive, effect } from 'vue'
const state = reactive({
user: {
name: 'Alice'
}
})
effect(() => {
console.log(state.user.name)
})
state.user.name = 'Bob' // 打印 "Bob"
在這個(gè)示例中政溃,我們創(chuàng)建了一個(gè)嵌套的響應(yīng)式對象,并使用 effect
創(chuàng)建了一個(gè)副作用态秧,它打印出用戶的名字董虱。當(dāng)用戶的名字被改變時(shí),副作用就會被觸發(fā)申鱼。
Render 函數(shù)
在 Vue 3 中愤诱,Render 函數(shù)是一種提供了更大靈活性的高級功能藏鹊。雖然 Vue 的模板系統(tǒng)已經(jīng)足夠強(qiáng)大,但在某些情況下转锈,直接使用 JavaScript 編寫渲染邏輯會更加方便。
Render 函數(shù)的工作原理是通過返回一個(gè)虛擬節(jié)點(diǎn)(VNode)來告訴 Vue 如何渲染界面楚殿。Vue 3 提供了 h
函數(shù)用于創(chuàng)建 VNode撮慨。
import { h } from 'vue'
export default {
render() {
return h('div', {}, 'Hello, world!')
}
}
在這個(gè)例子中,我們使用 h
函數(shù)創(chuàng)建了一個(gè) div
元素脆粥,然后在 Render 函數(shù)中返回它砌溺。
編譯優(yōu)化
參考上一章節(jié)
Vue 3 的編譯器在編譯時(shí)做了許多優(yōu)化,例如靜態(tài)節(jié)點(diǎn)提升和動(dòng)態(tài)節(jié)點(diǎn)綁定变隔,從而在運(yùn)行時(shí)減少了不必要的工作规伐。靜態(tài)節(jié)點(diǎn)提升可以將不會改變的節(jié)點(diǎn)從渲染函數(shù)中提取出來,從而避免在每次渲染時(shí)都重新創(chuàng)建它們匣缘。動(dòng)態(tài)節(jié)點(diǎn)綁定則是對那些可能改變的節(jié)點(diǎn)進(jìn)行優(yōu)化猖闪,只有當(dāng)這些節(jié)點(diǎn)的綁定值發(fā)生變化時(shí),才會重新渲染節(jié)點(diǎn)肌厨。
手動(dòng)編寫渲染邏輯
有時(shí)培慌,我們可能需要手動(dòng)編寫渲染邏輯。比如柑爸,當(dāng)我們需要根據(jù)一組數(shù)據(jù)動(dòng)態(tài)生成一個(gè)列表時(shí)吵护,我們可以在 Render 函數(shù)中使用 JavaScript 的數(shù)組方法。
import { h } from 'vue'
export default {
data() {
return {
items: ['Apple', 'Banana', 'Cherry']
}
},
render() {
return h('div', {}, this.items.map(item => h('div', {}, item)))
}
}
在這個(gè)例子中表鳍,我們使用 map
方法動(dòng)態(tài)生成了一個(gè)列表的元素馅而,然后在 Render 函數(shù)中返回它。
Render 函數(shù)提供了一種強(qiáng)大的方式來控制 Vue 應(yīng)用的渲染過程譬圣,使得我們能夠更好地控制和優(yōu)化應(yīng)用的性能瓮恭。
vue生態(tài)配套
狀態(tài)管理
Pinia 是 Vue 3 提供的一種新型狀態(tài)管理庫,它提供了 Vuex 的核心功能胁镐,但在 API 設(shè)計(jì)上更加簡潔且易用偎血。
Pinia 的主要優(yōu)點(diǎn)包括:
- 它有更簡潔的 API,減少了模板代碼的數(shù)量盯漂。
- 它通過 TypeScript 提供了更好的類型支持颇玷。
- 它提供了基于組件的狀態(tài)存儲,只在需要時(shí)加載狀態(tài)就缆。
下面是一個(gè) Pinia 使用示例:
首先帖渠,安裝 Pinia:
npm install pinia
然后,創(chuàng)建一個(gè) Pinia store:
// src/stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++
}
}
})
然后竭宰,在你的 main.js 或 main.ts 文件中創(chuàng)建 Pinia 插件空郊,并將其添加到你的 Vue 應(yīng)用中:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
然后份招,你可以在組件中使用該 store:
<template>
<button @click="increment">{{ count }}</button>
</template>
<script>
import { useCounterStore } from '@/stores/counter'
export default {
setup() {
const counter = useCounterStore()
return {
count: counter.count,
increment: counter.increment
}
}
}
</script>
以上就是 Pinia 的基本用法,它提供了一種更簡潔狞甚、更靈活的方式來管理 Vue 應(yīng)用的狀態(tài)锁摔。
路由管理 - Vue Router
Vue Router 是 Vue.js 的路由庫,你可以使用它構(gòu)建單頁面應(yīng)用程序哼审,如下面的例子所示:
首先谐腰,創(chuàng)建一個(gè) router:
import { createRouter, createWebHistory } from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
})
然后,在 Vue 應(yīng)用中使用這個(gè) router:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
最后涩盾,在組件中使用 <router-link>
和 <router-view>
來導(dǎo)航和渲染路由:
<template>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-view></router-view>
</template>
UI 框架 - Element UI
Element UI 是一個(gè)為 Vue.js 開發(fā)的 UI 框架十气,它提供了一套豐富多樣的組件,可以幫助我們更容易地構(gòu)建出漂亮的界面:
<template>
<el-button type="primary">主要按鈕</el-button>
<el-button type="success">成功按鈕</el-button>
<el-button type="warning">警告按鈕</el-button>
</template>
測試方案 - Vitest
Vitest 是一個(gè)由 Vite 提供支持的極速單元測試框架春霍。
import { assert, describe, it } from 'vitest'
describe.skip('skipped suite', () => {
it('test', () => {
// 已跳過此測試套件砸西,無錯(cuò)誤
assert.equal(Math.sqrt(4), 3)
})
})
describe('suite', () => {
it.skip('skipped test', () => {
// 已跳過此測試,無錯(cuò)誤
assert.equal(Math.sqrt(4), 3)
})
})
其他改變
在 Vue 3 中址儒,開發(fā)者會注意到一些重要的變化芹枷,主要體現(xiàn)在全局 API 的轉(zhuǎn)移等,以及對 TypeScript 的更好支持上莲趣。
全局 API 轉(zhuǎn)移
在 Vue 3 中杖狼,一些全局 API 已經(jīng)被轉(zhuǎn)移到了 globalProperties
上,例如 Vue.prototype
在 Vue 3 中變成了 app.config.globalProperties
妖爷。這樣做是為了更好地隔離全局 API蝶涩,并為未來可能的更改提供更大的靈活性。
例如絮识,原本在 Vue 2 中我們可能會這樣添加一個(gè)全局的方法:
Vue.prototype.$myGlobalMethod = function () {
return 'Hello World!'
}
在 Vue 3 中绿聘,我們需要這樣做:
const app = createApp(App)
app.config.globalProperties.$myGlobalMethod = function () {
return 'Hello World!'
}
然后我們就可以在任何組件中使用這個(gè)方法:
this.$myGlobalMethod()
刪除的 API
Vue 3 為了簡化框架并避免未來的維護(hù)負(fù)擔(dān),刪除了一些在 Vue 2 中已經(jīng)被廢棄的 API次舌,例如 Vue.set
熄攘、Vue.delete
和 Vue.observable
。
TypeScript 支持
Vue 3 從一開始就在內(nèi)部使用了 TypeScript 重寫彼念,因此在 TypeScript 的支持上有了顯著的提升挪圾。這包括更好的類型推斷、自動(dòng)補(bǔ)全逐沙,以及更強(qiáng)大的類型安全性哲思。
例如,在 Vue 2 中吩案,我們可能需要使用 Vue.extend() 或者 @Component
裝飾器來確保 TypeScript 類型正確棚赔,但在 Vue 3 中,我們可以直接使用 defineComponent
方法,它能正確地推斷出組件的類型:
import { defineComponent } from 'vue'
export default defineComponent({
// type inference enabled
})