Vue组件化深入理解
生命周期
每个组件都可能经历 创建、挂载、更新、卸载等一系列过程
在每个阶段,我们可能会添加一些属于自己的逻辑代码
在Vue中,生命周期通过生命周期函数实现
生命周期函数实际上就是回调函数,在某个时间会被Vue源码调用通过 生命周期函数的回调,我们可以知道目前组件正在经历什么阶段生命周期的流程
初始化事件 生命周期beforeCreate创建组件实例:初始化 注入和响应式created:发送网络请求,事件监听,以及调用 this.$warch方法,data以及methods中的变量以及方法已经准备好template模板编译beforeMount挂载到虚拟DOM 虚拟DOM–>真实DOM–>界面看到元素的显示**mounted:**元素已经被挂载,获取DOM,使用DOM数据更新:比如message改变beforeUpdate根据最新数据生成VNode 生成虚拟DOM–>真实DOMupdated组件准备销毁的时候,会先调用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组件化基础 - 脚手架