Vue组件化深入理解
生命周期
-
每个组件都可能经历 创建、挂载、更新、卸载等一系列过程
-
在每个阶段,我们可能会添加一些属于自己的逻辑代码
-
在Vue中,生命周期通过生命周期函数实现
- 生命周期函数实际上就是回调函数,在某个时间会被Vue源码调用
- 通过 生命周期函数的回调,我们可以知道目前组件正在经历什么阶段
生命周期的流程
- 初始化事件 生命周期
- beforeCreate
- 创建组件实例:初始化 注入和响应式
- created:发送网络请求,事件监听,以及调用 this.$warch方法,data以及methods中的变量以及方法已经准备好
- template模板编译
- beforeMount
- 挂载到虚拟DOM 虚拟DOM–>真实DOM–>界面看到元素的显示
- **mounted:**元素已经被挂载,获取DOM,使用DOM
- 数据更新:比如message改变
- beforeUpdate
- 根据最新数据生成VNode 生成虚拟DOM–>真实DOM
- updated
- 组件准备销毁的时候,会先调用beforeUnmount
- 将之前挂载在虚拟DOM中的VNode从虚拟DOM移除
- unmounted(回收操作,取消事件监听)
$refs的使用
在某些情况下,我们需要获取元素对象或者子组件的实例,通常使用 $refs来获取
- $refs可以获取元素也可以获取组件的实例对象
动态组件
在Vue中有一个
<component is="组件名称"></component>
用于显示不同的组件
- 若要实现以下案例:有三个按钮,点击第一个按钮显示第一个组件,点击第二个按钮显示第二个组件,点击第三个按钮显示第三个组件
- 实现思路:
- 我们可以通过
v-if
进行判断,显示哪个组件 - 同时,可以通过
<component is="组件名称"></component>
进行操作
- 我们可以通过
<template>
<div>
<template v-for="item in tabList" :key="item.id">
<button @click="clickItem(item)">{{ item.label }}</button>
</template>
<component :is="currentItem"></component>
</div>
</template>
<script>
//引入组件
import Home from "./components/动态组件/Home.vue";
import Main from "./components/动态组件/Main.vue";
import Foot from "./components/动态组件/Foot.vue";
export default {
//注册组件
components: {
Home,
Main,
Foot,
},
data() {
return {
tabList: [
{
id: 0,
label: "首页",
value: "Home",
},
{
id: 1,
label: "主要内容",
value: "Main",
},
{
id: 2,
label: "页脚",
value: "Foot",
},
],
currentItem: "",
};
},
methods: {
clickItem(value) {
this.currentItem = value.value;
},
},
};
</script>
- is属性对应的值,应当是全局注册的组件或者局部注册的组件
- 同时,传递值的方法和正常的组件传递方法是一样的
Keep-alive让组件保持存活
当一个组件,我们需要缓存其组件中的状态,不希望在切换组件的时候,被销毁,就可以使用
<keep-alive></keep-alive>
进行包裹
- 可以单独包裹一个组件
<keep-alive>
<home v-if="flag"></home>
</keep-alive>
- 可以包裹多个组件
- 默认是全部都是保持存活的状态
<keep-alive>
<component :is="currentItem"></component>
</keep-alive>
- 可以设置部分存活
- 通过在 keep-alive中设置属性控制
- include:接受的参数:字符串/正则表达式/数组,代表那几个组件需要保持存活
- exclude:接受的参数:字符串/正则表达式/数组,代表除去设置的组件外,其余的组件保持存活
- 而二者匹配的是组件中,name选项,因此在创建组件的时候,要对组件设置name选项
- 对于保持存活的组件 就没有销毁一说了,因此需要使用特殊的生命周期进行监听
- 当切换到保持活跃的组件:使用 activated监听
- 当隐藏保持活跃的组件:使用 deactivated监听
异步组件
在webpack打包的时候,默认会把所有的组件都打包到app.js的文件中,导致打包的体积很大,有可能会造成首屏加载速度过慢
因此我们可以将一部分组件设置成异步组件,异步组件在webpack打包的时候,就会单独打包称一个文件
- 在 webpcak的学习中,JS文件有两种导入方式
- import直接导入:会被打包称一个文件
- import函数导入:会单独打包成一个文件:
import("./utils").then((res)=>console.log(res))
,返回的是一个Promise
- 而在局部注册的时候,应该如何操作
- 首先引入 defineAsyncComponent函数
- 在函数中传入一个箭头函数 ()=>import(‘组件路径’)
- 赋值即可
<template>
<div>
<home></home>
<MainVue></MainVue>
<!-- 异步组件 -->
<foot></foot>
</div>
</template>
<script>
//引入Vue中的defineAsyncComponent函数
import { defineAsyncComponent } from "vue";
//引入正常组件
import Home from "./components/动态组件/Home.vue";
import MainVue from "./components/动态组件/Main.vue";
//引入异步组件
const AsyncFoot = defineAsyncComponent(() =>
import("./components/动态组件/Foot.vue")
);
export default {
//注册组件
components: {
Home,
MainVue,
//将异步组件赋值给Foot
//Foot按照正常组件使用即可
Foot: AsyncFoot,
},
};
</script>
组件的v-model
在普通元素中使用v-model可以实现数据的双向绑定,那么在组件中使用v-model是怎么样的
v-model默认绑定的是 modelValue,执行的事件是 @update:modelValue
- 在普通元素中使用 v-model,实际上是做了两个步骤
- 使用 v-bind将value关联到message
- 之后通过事件,修改message
<input :value="message" @change="message = $event.target.value" />
- 而在组件中使用,依旧如此
- 通过 v-bind绑定到一个固定名称的变量:modelValue
- 而后通过 @update:modelValue事件改变值
----父组件
<home v-model="count"></home>
上面的写法等价于下面的写法
<home :modelValue="count" @update:modelValue="count = $event"></home>
-----子组件
<script>
export default {
//方便父组件有事件提示
emits: ["update:modelValue"],
//接收父组件传进来的参数
props: {
modelValue: {
type: Number,
},
},
methods: {
//发射事件
countChange() {
this.$emit("update:modelValue", 1);
},
},
};
</script>
绑定多个属性
若我们在绑定属性的时候,不想默认绑定modelValue和 @update:modelValue,我们可以通过 v-model:自定义名称=“变量”来改变
------父组件
<home v-model:nameText="text"></home>
------子组件
<script>
export default {
emits: ["update:text"],
props: {
text: {
type: String,
}
},
methods: {
textChange() {
this.$emit("update:text", "lisi");
}
},
};
</script>
Mixin混入
当多个组件中有共同的代码,可以抽离封装成一个文件,这时候就需要用到Mixin的混入了
- 首先创建一个 mixinTest.js文件
- 里面可以写任何options api以及生命生命周期函数
export default {
data() {
return {
message: "我是mixin",
};
},
created() {
console.log("mixincreated");
},
mehtods: {
hello() {
console.log("hello");
},
},
};
- 在组件中使用mixin
<template>
<div>Home组件 {{ message }}{{ name }}</div>
</template>
<script>
//引入混入文件
import mixinJS from "../mixin/mixin";
export default {
mixins: [mixinJS],
data() {
return {
name: "zhangcheng",
};
},
};
</script>
- mixin的混入规则
- 对于相同的,就会进行合并
- 对于不同的,以组件内部定义的为准
Vue3.0(二):Vue组件化基础 - 脚手架