Vue3.0(三):Vue组件化深入理解

Vue组件化深入理解

生命周期

  • 每个组件都可能经历 创建、挂载、更新、卸载等一系列过程

  • 在每个阶段,我们可能会添加一些属于自己的逻辑代码

  • 在Vue中,生命周期通过生命周期函数实现

    • 生命周期函数实际上就是回调函数,在某个时间会被Vue源码调用
    • 通过 生命周期函数的回调,我们可以知道目前组件正在经历什么阶段

生命周期的流程

image.png
  • 初始化事件 生命周期
  • 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可以获取元素也可以获取组件的实例对象

image.png

动态组件

在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选项

image.png

  • 对于保持存活的组件 就没有销毁一说了,因此需要使用特殊的生命周期进行监听
    • 当切换到保持活跃的组件:使用 activated监听
    • 当隐藏保持活跃的组件:使用 deactivated监听

image.png

异步组件

在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>

image.png

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组件化基础 - 脚手架

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值