天天看點

Vue3從入門到精通 14

作者:繪芽研究社1号
Vue3從入門到精通 14

目錄:

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 異步元件

Vue3從入門到精通 14

在傳統的 Vue.js 開發中,元件是在應用程式啟動時就立即加載的。

這種方式雖然簡單,但是會導緻應用程式的初始加載時間變長,影響使用者體驗。

為了提高應用程式的性能和加載速度,Vue.js 提供了異步元件。

Vue3從入門到精通 14

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>           

改造前:

Vue3從入門到精通 14

改造後:

Vue3從入門到精通 14

2 依賴注入

Vue3從入門到精通 14

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 則必須将其沿着元件鍊逐級傳遞下去,這會非常麻煩:

Vue3從入門到精通 14

注意,雖然這裡的 <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>           
Vue3從入門到精通 14

provide 和 inject 可以幫助我們解決這一問題。 [1] 一個父元件相對于其所有的後代元件,會作為依賴提供者。任何後代的元件樹,無論層級有多深,都可以注入由父元件提供給整條鍊路的依賴。

Vue3從入門到精通 14

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>           
Vue3從入門到精通 14

繼續閱讀