目录:
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>