目錄:
1異步元件
1.1什麼是異步元件?
1.2為什麼要使用異步元件?
1.3如何使用異步元件?
2依賴注入
2.1什麼是依賴注入?
2.2如何使用依賴注入?
2.2.1 Prop 逐級透傳問題
2.2.2 Provide (提供)
2.2.3應用層 Provide
2.2.4 Inject (注入)
2.2.5總結
2.3示例
1 異步元件
在傳統的 Vue.js 開發中,元件是在應用程式啟動時就立即加載的。
這種方式雖然簡單,但是會導緻應用程式的初始加載時間變長,影響使用者體驗。
為了提高應用程式的性能和加載速度,Vue.js 提供了異步元件。
1.1 什麼是異步元件?
在大型項目中,我們可能需要拆分應用為更小的塊,并僅在需要時再從伺服器加載相關元件。
異步元件是一種延遲加載元件的方式,即隻有在需要使用該元件時才會進行加載。
Vue 提供了 defineAsyncComponent 方法來實作此功能。
1.2 為什麼要使用異步元件?
異步元件可以減少打包的結果
會将異步元件分開打包,會采用異步的方式加載元件,可以有效的解決一個元件過大的問題。
不使用異步元件,如果元件功能比較多打包出來的結果就會變大。
1.3 如何使用異步元件?
Vue 提供了 defineAsyncComponent 方法來實作此功能。
類似 Vite 和 Webpack 這樣的建構工具也支援此文法 (并且會将它們作為打包時的代碼分割點),是以我們也可以用它來導入 Vue 單檔案元件:
// 第一種方式
import { defineAsyncComponent } from 'vue'
// 異步加載元件
const AComponent = defineAsyncComponent(()=>{
return import("./components/AComponent.vue")
})
// 第二種方式
import { defineAsyncComponent } from 'vue'
// 異步加載元件
const AComponent = defineAsyncComponent(()=>
import("./components/AComponent.vue")
)
示例:
<template>
<h1>{{ title }}</h1>
<keep-alive>
<component
:is="dyComponent">
</component>
</keep-alive>
<hr>
<button @click="changeHandle">
切換元件
</button>
</template>
<script>
import { defineAsyncComponent } from 'vue'
// 異步加載元件
const AComponent = defineAsyncComponent(()=>{
return import("./components/AComponent.vue")
})
// import AComponent from './components/AComponent.vue';
import BComponent from './components/BComponent.vue';
export default {
data() {
return {
title: "動态元件",
dyComponent: "BComponent"
}
},
components: {
AComponent,
BComponent
},
methods: {
changeHandle() {
this.dyComponent = this.dyComponent === "AComponent" ? "BComponent" : "AComponent"
console.log("切換元件:"+this.dyComponent);
}
}
}
</script>
改造前:
改造後:
2 依賴注入
2.1 什麼事依賴注入?
依賴注入是一種設計模式。
他的目的是将元件之間的依賴關系解耦,使得元件之間的通信更加靈活和可維護。
在 vue 中,依賴注入是通過 provide 和 inject 兩個 API 實作的。
2.2 如何使用依賴注入?
引用官網資訊:https://cn.vuejs.org/guide/components/provide-inject.html#prop-drilling
2.2.1 Prop 逐級透傳問題
通常情況下,當我們需要從父元件向子元件傳遞資料時,會使用 props。想象一下這樣的結構:有一些多層級嵌套的元件,形成了一顆巨大的元件樹,而某個深層的子元件需要一個較遠的祖先元件中的部分資料。在這種情況下,如果僅使用 props 則必須将其沿着元件鍊逐級傳遞下去,這會非常麻煩:
注意,雖然這裡的 <Footer> 元件可能根本不關心這些 props,但為了使 <DeepChild> 能通路到它們,仍然需要定義并向下傳遞。如果元件鍊路非常長,可能會影響到更多這條路上的元件。
這一問題被稱為“prop 逐級透傳”,顯然是我們希望盡量避免的情況。
示例:
<template>
<h3>{{ title }}</h3>
<p>{{ title }} : {{ msg }}</p>
<Child :msg="msg"></Child>
</template>
<script>
import Child from './Child.vue';
export default {
data() {
return {
title: "Parent"
}
},
components: {
Child
},
props:{
msg:{
type:String
}
}
}
</script>
<template>
<h5>{{ title }}</h5>
<p>{{ title }} : {{ msg }}</p>
</template>
<script>
export default{
data(){
return {
title:"Child"
}
},
props:{
msg:{
type:String
}
}
}
</script>
<template>
<h1>{{ title }}</h1>
<Parent msg="依賴注入-root"></Parent>
</template>
<script>
import Parent from './components/Parent.vue';
export default {
data() {
return {
title:"依賴注入"
}
},
components:{
Parent
}
}
</script>
provide 和 inject 可以幫助我們解決這一問題。 [1] 一個父元件相對于其所有的後代元件,會作為依賴提供者。任何後代的元件樹,無論層級有多深,都可以注入由父元件提供給整條鍊路的依賴。
2.2.2 Provide (提供)
要為元件後代提供資料,需要使用到 provide 選項:
export default {
provide: {
title: 'hello!'
}
}
對于 provide 對象上的每一個屬性,後代元件會用其 key 為注入名查找期望注入的值,屬性的值就是要提供的資料。
如果我們需要提供依賴目前元件執行個體的狀态 (比如那些由 data() 定義的資料屬性),那麼可以以函數形式使用 provide:
export default {
data() {
return {
title: 'hello!'
}
},
provide() {
// 使用函數的形式,可以通路到 `this`
return {
title: this.message
}
}
}
然而,請注意這不會使注入保持響應性。
2.2.3 應用層 Provide
除了在一個元件中提供依賴,我們還可以在整個應用層面提供依賴:
import { createApp } from 'vue'
const app = createApp({})
app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
在應用級别提供的資料在該應用内的所有元件中都可以注入。
這在你編寫插件時會特别有用,因為插件一般都不會使用元件形式來提供值。
2.2.4 Inject (注入)
要注入上層元件提供的資料,需使用 inject 選項來聲明:
export default {
inject: ['title'],
created() {
console.log(this.message) // injected value
}
}
注入會在元件自身的狀态之前被解析,是以你可以在 data() 中通路到注入的屬性:
export default {
inject: ['title'],
data() {
return {
// 基于注入值的初始資料
fullMessage: this.message
}
}
}
2.2.5 總結
注意:provide 和 inject 隻能由上到下的傳遞,不能反向傳遞
2.3 示例
<template>
<h5>{{ title }}</h5>
<p>{{ message }}</p>
<p>{{ parentMessage }}</p>
<p>{{ title }} : {{ msg }}</p>
</template>
<script>
export default{
inject: ['message','parentMessage'],
data(){
return {
title:"Child"
}
},
props:{
msg:{
type:String
}
}
}
</script>
<template>
<h3>{{ title }}</h3>
<p>{{ title }} : {{ msg }}</p>
<Child :msg="msg"></Child>
</template>
<script>
import Child from './Child.vue';
export default {
provide(){
return {
parentMessage:"provide - Parent - "+this.title
}
},
data() {
return {
title: "Parent"
}
},
components: {
Child
},
props:{
msg:{
type:String
}
}
}
</script>
<template>
<h1>{{ title }}</h1>
<Parent msg="依賴注入-root"></Parent>
</template>
<script>
import Parent from './components/Parent.vue';
export default {
data() {
return {
title: "依賴注入"
}
},
provide: {
message: "provide: 依賴注入"
},
components: {
Parent
}
}
</script>