最全系列的vue3入門教程『圖文并茂』

點(diǎn)擊在線閱讀,體驗(yàn)更好 鏈接
現(xiàn)代JavaScript高級(jí)小冊(cè) 鏈接
深入淺出Dart 鏈接
現(xiàn)代TypeScript高級(jí)小冊(cè) 鏈接
linwu的算法筆記?? 鏈接

Vue 3 簡(jiǎn)介

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è)簡(jiǎn)單的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 的值。最后,我們將 countincrement 返回給模板,以便在模板中使用它們。

響應(yīng)式系統(tǒng)

1. 響應(yīng)式原理


Vue的響應(yīng)式系統(tǒng)是其核心特性之一,它使得數(shù)據(jù)變更能夠自動(dòng)更新到UI上。在Vue 3中,這個(gè)系統(tǒng)基于JavaScript的 Proxy 對(duì)象重寫,提供了更好的性能和更多的功能。

2. ref 和 reactive

Vue 3提供了兩個(gè)主要的函數(shù)來創(chuàng)建響應(yīng)式數(shù)據(jù):refreactive。

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)式對(duì)象。你可以直接訪問和修改它的屬性。

import { reactive } from 'vue'

const state = reactive({ count: 0 })
console.log(state.count) // 0
state.count++ // 1

3. 實(shí)現(xiàn)機(jī)制區(qū)別

refreactive 的主要區(qū)別在于,ref 是為了讓基本類型(如數(shù)字和字符串)可以變?yōu)轫憫?yīng)式,而 reactive 是為了讓對(duì)象變?yōu)轫憫?yīng)式。

ref 創(chuàng)建的響應(yīng)式數(shù)據(jù)需要通過 .value 屬性進(jìn)行訪問和修改,而 reactive 創(chuàng)建的響應(yīng)式對(duì)象可以直接訪問和修改其屬性。因此,ref 更適合于處理基本類型,而 reactive 更適合于處理對(duì)象。

組合式 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ù)中使用 refreactive 來創(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)視

你可以使用 computedwatch 來創(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、onUpdatedonUnmounted。

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
    }
  }
}

高級(jí)功能

1. 淺層響應(yīng)式

在某些情況下,你可能想要?jiǎng)?chuàng)建一個(gè)淺層的響應(yīng)式對(duì)象,這樣其內(nèi)部的屬性不會(huì)被轉(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)式對(duì)象。任何試圖修改只讀對(duì)象的操作都將在開發(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)式對(duì)象時(shí),對(duì)象的屬性將失去響應(yīng)式。為了防止這種情況,我們可以使用 toRefstoRef 函數(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對(duì)模板進(jìn)行靜態(tài)分析,提取出不會(huì)改變的部分,預(yù)編譯為純JavaScript,這大大提高了運(yùn)行時(shí)的渲染效率。下面詳細(xì)介紹一下這些優(yōu)化。

靜態(tài)節(jié)點(diǎn)提升

在 Vue 3 中,如果你的模板中有不會(huì)改變的部分,例如:

<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)將會(huì)被提升,避免了每次渲染時(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)編譯可以讓我們?cè)谶\(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è)例子中,我們?cè)谶\(yùn)行時(shí)編譯了模板字符串,并將結(jié)果設(shè)置為組件的渲染函數(shù)。這種技術(shù)在需要?jiǎng)討B(tài)生成模板的場(chǎng)景中非常有用,比如在一個(gè) CMS 中渲染用戶提供的模板。

深入組件化

Vue 3在組件化方面也有很多進(jìn)步,下面詳細(xì)介紹一下。

動(dòng)態(tài)組件

Vue 3支持使用component標(biāo)簽來動(dòng)態(tài)加載組件,組件可以是一個(gè)組件選項(xiàng)對(duì)象,也可以是一個(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,簡(jiǎn)稱 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)是否懸停在組件上。這種模式可以幫助我們?cè)诓煌慕M件間復(fù)用邏輯。

其它組合API

computed

computed 函數(shù)用于創(chuàng)建一個(gè)響應(yīng)式的計(jì)算屬性。這個(gè)屬性的值是由提供的 getter 函數(shù)計(jì)算得出,并且只有當(dāng)它的依賴項(xiàng)改變時(shí)才會(huì)重新計(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

watchwatchEffect 函數(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è)副作用,它會(huì)在 count 改變時(shí)立即執(zhí)行。

lifecycle hooks

在 Vue 3 中,你可以在 setup 函數(shù)中直接使用生命周期鉤子函數(shù),例如 onMounted,onUpdatedonUnmounted

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è)示例中,我們?cè)诮M件掛載、更新和卸載時(shí)打印消息。

這些是 Vue 3 中提供的更為高級(jí)的響應(yīng)式 API,讓我們逐一了解它們。

shallowReactive 與 shallowRef

shallowReactiveshallowRef 允許我們創(chuàng)建一個(gè)淺層的響應(yīng)式對(duì)象。對(duì)于 shallowReactive,只有對(duì)象的第一層屬性會(huì)變?yōu)轫憫?yīng)式的,對(duì)象的更深層次的屬性不會(huì)被轉(zhuǎn)換。shallowRefref 的淺層版本,它不會(huì)自動(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

readonlyshallowReadonly 允許我們創(chuàng)建一個(gè)只讀的響應(yīng)式對(duì)象。對(duì)于 readonly,對(duì)象的所有屬性(包括嵌套屬性)都會(huì)變?yōu)橹蛔x。shallowReadonlyreadonly 的淺層版本,只有對(duì)象的第一層屬性會(huì)變?yōu)橹蛔x。

import { readonly, shallowReadonly } from 'vue'

const obj = readonly({ a: { b: 1 } })
obj.a = 2 // 這會(huì)拋出一個(gè)錯(cuò)誤

const shallowObj = shallowReadonly({ a: { b: 1 } })
shallowObj.a.b = 2 // 這不會(huì)拋出錯(cuò)誤

toRaw 與 markRaw

toRawmarkRaw 允許我們逃避 Vue 的響應(yīng)式系統(tǒng)。toRaw 可以返回一個(gè)對(duì)象的原始版本,而 markRaw 可以防止一個(gè)對(duì)象被轉(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 不會(huì)被轉(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


provideinject 是 Vue 3 的依賴注入 API,可以用于在組件樹中傳遞值,而不必一層一層地通過 props 傳遞。

import { provide, inject } from 'vue'

// 在父組件中
provide('myValue', 123)

// 在子組件中
const myValue = inject('myValue') // myValue 現(xiàn)在是 123

響應(yīng)式判斷

Vue 3 提供了 isReactiveisRef 函數(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)式對(duì)象的屬性被訪問時(shí),effect 將其收集為依賴項(xiàng);當(dāng)一個(gè)響應(yīng)式對(duì)象的屬性被修改時(shí),它將觸發(fā)關(guān)聯(lián)的副作用。

effect、reactive、ref

reactiveref 是 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)式對(duì)象和一個(gè) ref,然后使用 effect 創(chuàng)建了兩個(gè)副作用,它們分別打印出對(duì)象和 ref 的值。當(dāng)這些值被改變時(shí),副作用就會(huì)被觸發(fā)。

track、trigger

tracktrigger 是 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)式對(duì)象。

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)式對(duì)象,并使用 effect 創(chuàng)建了一個(gè)副作用,它打印出用戶的名字。當(dāng)用戶的名字被改變時(shí),副作用就會(huì)被觸發(fā)。

Render 函數(shù)


在 Vue 3 中,Render 函數(shù)是一種提供了更大靈活性的高級(jí)功能。雖然 Vue 的模板系統(tǒng)已經(jīng)足夠強(qiáng)大,但在某些情況下,直接使用 JavaScript 編寫渲染邏輯會(huì)更加方便。

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)提升可以將不會(huì)改變的節(jié)點(diǎn)從渲染函數(shù)中提取出來,從而避免在每次渲染時(shí)都重新創(chuàng)建它們。動(dòng)態(tài)節(jié)點(diǎn)綁定則是對(duì)那些可能改變的節(jié)點(diǎn)進(jìn)行優(yōu)化,只有當(dāng)這些節(jié)點(diǎn)的綁定值發(fā)生變化時(shí),才會(huì)重新渲染節(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ì)上更加簡(jiǎn)潔且易用。

Pinia 的主要優(yōu)點(diǎn)包括:

  1. 它有更簡(jiǎn)潔的 API,減少了模板代碼的數(shù)量。
  2. 它通過 TypeScript 提供了更好的類型支持。
  3. 它提供了基于組件的狀態(tài)存儲(chǔ),只在需要時(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 的基本用法,它提供了一種更簡(jiǎn)潔、更靈活的方式來管理 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>

測(cè)試方案 - Vitest

Vitest 是一個(gè)由 Vite 提供支持的極速單元測(cè)試框架。

import { assert, describe, it } from 'vitest'

describe.skip('skipped suite', () => {
  it('test', () => {
    // 已跳過此測(cè)試套件,無錯(cuò)誤
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('suite', () => {
  it.skip('skipped test', () => {
    // 已跳過此測(cè)試,無錯(cuò)誤
    assert.equal(Math.sqrt(4), 3)
  })
})

其他改變

在 Vue 3 中,開發(fā)者會(huì)注意到一些重要的變化,主要體現(xiàn)在全局 API 的轉(zhuǎn)移等,以及對(duì) TypeScript 的更好支持上。

全局 API 轉(zhuǎn)移

在 Vue 3 中,一些全局 API 已經(jīng)被轉(zhuǎn)移到了 globalProperties 上,例如 Vue.prototype 在 Vue 3 中變成了 app.config.globalProperties。這樣做是為了更好地隔離全局 API,并為未來可能的更改提供更大的靈活性。

例如,原本在 Vue 2 中我們可能會(huì)這樣添加一個(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 為了簡(jiǎn)化框架并避免未來的維護(hù)負(fù)擔(dān),刪除了一些在 Vue 2 中已經(jīng)被廢棄的 API,例如 Vue.setVue.deleteVue.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
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容