【vue3】10-vue组件化额外知识补充(下)-动态组件-组件缓存-v-model在组件上的应用

news2025/6/21 14:11:41

组件化-额外知识补充(下)

  • 动态组件的使用(了解)
  • keep-alive(理解)
    • 认识keep-alive
    • keep-alive的使用
  • 异步组件的使用
    • webpack分包处理(了解)
    • Vue中实现异步组件
  • 组件的v-model
  • 组件的混入Mixin(了解)

动态组件的使用(了解)

切换组件案例:

比如我们现在想要实现了一个功能:

  • 点击一个tab-bar,切换不同的组件显示;

在这里插入图片描述

这个案例我们可以通过两种不同的实现思路来实现:

  • 方式一:通过v-if来判断,显示不同的组件;
  • 方式二:动态组件的方式;

方式一代码示例:

<template>
    <div class="app">
        <div class="tabs">
            <template v-for="(item, index) in tabs" :key="item">
                <button @click="changeColor(index)" :class="{ active: index === currentIndex }">
                    {{ item }}
                </button>
            </template>
        </div>
        <div class="view">
            <!-- 1.第一种做法:v-if进行逻辑判断,决定要显示哪一个组件 -->
            <template v-if="currentIndex === 0">
            <home></home>
        </template>
        <template v-else-if="currentIndex ===1">
            <about></about>
        </template>
       
        <template v-else-if="currentIndex === 2">
            <category></category>
        </template>
            <!-- 最后一个写<template v-else> 也可以,但是不推荐-->
        </div>

    </div>
</template>
<script>
import About from "./views/About.vue";
import Category from "./views/Category.vue";
import Home from "./views/Home.vue";

export default {
    components: {
        Home,
        Category,
        About
    },
    data() {
        return {
            tabs: ["home", "about", "category"],
            currentIndex: 0
        }
    },
    methods: {
        changeColor(index) {
            this.currentIndex = index
        }
    }
}

</script>

动态组件方式实现

动态组件是使用component组件,通过一个特殊的attribute is来实现:

<template>
    <div class="app">
        <div class="tabs">
            <template v-for="(tab, index) in tabs" :key="item">
                <button @click="changeColor(tab)" :class="{ active: currentTab === tab }">
                    {{ tab }}
                </button>
            </template>
        </div>
        <div class="view">
          <!-- 2.第二种做法:动态组件:component -->
            <!-- is中的组件:(1)要么是全局注册的组件;(2)要么是局部注册过的组件 -->
            <!-- <component is="about"></component> -->

            <!-- 动态组件传参(了解),如果是数组类型就和age一样:  监听发送的事件也在component上 -->
            <!-- <component name="sevgilid" :age="19" :is="tabs[currentIndex]"></component> -->
            <component name="sevgilid" :age="19" :is="currentTab"></component>
        </div>

    </div>
</template>

在上面的演示中,我们可以看到:

  • 首先使用了component组件,is:组件名,来展示对应的组件;
  • 然后绑定事件点击按钮时获取对应的tab来作为组件名实现动态组件的展示
  • 传递参数和监听子组件事件正常在component组件内使用即可,如在home组件中使用props接收数据:
    在这里插入图片描述

(动态组件了解即可,后边会讲解路由,使用路由切换更为简洁遍历)


keep-alive(理解)

认识keep-alive

在 Vue.js 中, keep-alive 内置组件可以缓存不活动的组件实例,它通过包裹动态组件来实现缓存,避免了组件的频繁销毁和重建,从而提升了页面性能

我们先对之前的案例中Home组件进行改造:

  • 在其中增加了一个按钮,点击可以递增的功能;
    在这里插入图片描述

比如我们将counter点到10,那么在切换到about再切换回来Home时,状态是否可以保持呢?

  • 答案是否定的;
  • 这是因为默认情况下,我们在切换组件后,Home组件会被销毁掉,再次回来时会重新创建组件;

但是,在开发中某些情况我们希望继续保持组件的状态,而不是销毁掉,这个时候我们就可以使用一个内置组件: keep-alive

keep-alive的使用

使用 keep-alive 内置组件很简单,只需要将需要缓存的组件用 <KeepAlive> 标签包裹即可。例如在刚才的案例中:

在这里插入图片描述

像上面这样包裹后,我们在点击递增按钮到一定数值后来回切换发现已经数值不会再被重置;
但通过再各个组件内部使用created和unmounted钩子函数发现都没有回调,这说明里面被包裹的所有组件都被缓存了;


如果想要精准控制组件的缓存对保持keep-alive组件监听有没有切换该怎么办呢?

(1)精准控制组件缓存

keep-alive有一些属性:

  • include - string | RegExp |Array。只有名称匹配的组件会被缓存;
  • exclude - string | RegExp | Array。任何名称匹配的组件都不会被缓存;
  • max - number | string。最多可以缓存多少组件实例,一旦达到这个数字,那么缓存组件中最近没有被访问的实例会被销毁;

include和exclude prop允许组件有条件地缓存:

  • 二者都可以用逗号分隔字符串、正则表达式或一个数组来表示;
  • 匹配首先检查组件自身的name选项;

使用示例:

Home组件中:

<template>
    <h2>home组件</h2>
    <h2>计数器:{{ counter }}</h2>
    <button @click="counter++">+1</button>
</template>

<script>
export default {
    // 此处的name提供给Keep-Alive中的include属性使用的
    name: "home",
    data() {
        return {
            counter: 0
        }
    }

}
</script>

App根组件中:

在这里插入图片描述

(2)缓存组件的生命周期

对于缓存的组件来说,再次进入时,我们是不会执行created或者mounted等生命周期函数的:

  • 但是有时候我们确实希望监听到何时重新进入到了组件,何时离开了组件;
  • 这个时候我们可以使用activated和deactivated这两个生命周期钩子函数来监听;

在这里插入图片描述

需要注意的是,由于 keep-alive 是内置组件,所以不支持动态组件模式下的异步组件:

  • 因为异步组件的加载是异步的, keep-alive 无法知道异步组件何时完成加载,从而无法对其进行缓存;
  • 如果需要缓存异步组件,可以使用工厂函数与异步组件创建一个高阶组件,再将其包裹在 keep-alive 内;

异步组件的使用

在学习异步组件使用前,先来了解一下webpack的分包处理,因为异步组件打包时会进行分包的处理

webpack分包处理(了解)

默认的打包过程:

  • 默认情况下,在构建整个组件树的过程中,因为组件和组件之间是通过模块化直接依赖的,那么webpack在打包时就会将组件模块打包到一起(比如一个app.js文件中);
  • 这个时候随着项目的不断庞大,app.js文件的内容过大,会造成首屏的渲染速度变慢;

打包时,代码的分包:

  • 所以,对于一些不需要立即使用的组件,我们可以单独对它们进行拆分,拆分成一些小的代码块chunk.js;
  • 这些chunk.js会在需要时从服务器加载下来,并且运行代码,显示对应的内容;

那么webpack中如何可以对代码进行分包呢?

在这里插入图片描述

Vue中实现异步组件

如果我们的项目过大了,对于某些组件我们希望通过异步的方式来进行加载(目的是可以对其进行分包处理),那么Vue中给我们提供了一个函数: defineAsyncComponent

defineAsyncComponent接受两种类型的参数:

  • 类型一:工厂函数,该工厂函数需要返回一个Promise对象;
  • 类型二:接受一个对象类型,对异步函数进行配置;

工厂函数类型一的写法:

<script>
import { defineAsyncComponent } from "vue";
//  import Category from "./views/Category.vue";
// 异步组件写法一(了解):工厂函数:返回的是一个promise对象
const AsyncCategory = defineAsyncComponent(() => import("./views/Category.vue"))


export default {
    components: {
        Home,
        // 异步组件:打包的时候会进行分包处理
        Category: AsyncCategory,
    }

}

</script>

异步组件写法二(了解):

在这里插入图片描述

(异步组件的使用仅作了解即可,因为实际开发中路由懒加载的写法会更多)


组件的v-model

前面我们在input中可以使用v-model来完成双向绑定:

  • 这个时候往往会非常方便,因为v-model默认帮助我们完成了两件事;
  • v-bind:value的数据绑定@input的事件监听;

如果我们现在封装了一个组件,其他地方在使用这个组件时,是否也可以使用v-model来同时完成这两个功能呢?

  • 也是可以的,vue也支持在组件上使用v-model;

当我们在组件上使用的时候,等价于如下的操作:

  • 我们会发现和input元素不同的只是属性的名称和事件触发的名称而已;
    在这里插入图片描述

那么,为了我们的counter组件可以正常的工作,这个组件内的click必须:

  • 将其value attribute绑定到一个名叫modelValue 的prop上;
  • 在其click事件被触发时,将新的值通过自定义的update:modelValue事件抛出;

Counter组件代码如下:

<template>
    <h2>counter:{{ modelValue }}</h2>
    <button @click="changeCounter">修改counter</button>
</template>

<script>
    export default{
        props:{
            modelValue:{
                type:Number,
                default:0
            }
        },
        emits:["update:modelValue"],
        methods:{
            changeCounter(){
                // this.$emit("update:modelValue", 1000)
                this.$emit("update:modelValue", 999)
            }
        }
    }
</script>

v-model默认绑定的参数名和事件名是modelValue;
此处的@click绑定click事件;换成@input则表示的是绑定的是input事件,当input表有input输入时触发事件

绑定多个属性(高级用法):

我们现在通过v-model是直接绑定了一个属性,如果我们希望绑定多个属性呢?

  • 也就是我们希望在一个组件上使用多个v-model是否可以实现呢?
  • 我们知道,默认情况下的v-model其实是绑定了modelValue属性@update:modelValue的事件;
  • 如果我们希望绑定更多,可以给v-model传入一个参数,那么这个参数的名称就是我们绑定属性的名称;

默认绑定一个属性和绑定多个自定义属性的代码对比:

(1)子组件部分:

在这里插入图片描述
(2)父组件部分:

在这里插入图片描述

总结:

  1. v-model可以绑定多个自定义属性
  2. v-model在组件上的应用实际上是将一个代表数据的属性和一个代表数据修改的事件绑定到了一起,使得在父子组件之间进行数据通信变得简单和直观。 比如v-model:title相当于做了两件事:
  • 绑定了title属性;

  • 监听了@update:title的事件;


组件的混入Mixin(了解)

Mixin主要在Vue2中使用,在Vue3中基本不用

虽然mixin在Vue中给我们带来了很多的代码复用和逻辑复用的好处,但是也存在一些弊端:

  1. 命名冲突:mixin可以将通用的逻辑和代码分离出来,但是它也可能导致命名冲突。如果多个Mixin中有同名的选项,或者Mixin中的选项与组件中的选项重名,就会导致选项的合并冲突。而且如果有多个mixin混合使用可能会更加复杂,因为难以判断选项的来源和优先级。为了避免命名冲突,我们需要在编写Mixin时格外小心,同时在开发过程中也需要保持清晰的组织结构。
  2. 耦合性高:mixin虽然可以让我们方便地复用代码和逻辑,但是也可能导致组件与Mixin之间的耦合性增加。因为mixin需要了解组件的内部实现细节和数据结构,从而才能正确地暴露需要的数据和方法。这就导致了Mixin与组件之间的耦合度会比较高,一旦需要修改Mixins,可能会对组件产生意外的影响。

在Vue 3中,Composition API的出现主要是为了解决mixin中所存在的问题和局限性。Composition API可以更好地实现逻辑复用,并且可以更好地组织组件代码。通过Composition API,我们可以将逻辑功能组织成一组Hooks(钩子函数)并进行复用。


目前我们是使用组件化的方式在开发整个Vue的应用程序,但是组件和组件之间有时候会存在相同的代码逻辑,我们希望对相同的代码逻辑进行抽取

在Vue2和Vue3中都支持的一种方式就是使用Mixin来完成:

  • Mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能;
  • 一个Mixin对象可以包含任何组件选项;
  • 当组件使用Mixin对象时,所有Mixin对象的选项将被混合进入该组件本身的选项中;

(1)基本使用:

Vue中的Mixin分为全局Mixin与组件级Mixin。下面我们以组件级Mixin为例讲解其基本使用方法。
首先,定义一个名为myMixin的mixin:

var myMixin = {
  data: function () {
    return {
      message: 'Hello world!'
    }
  },
  methods: {
    greet: function () {
      console.log(this.message)
    }
  }
}

然后,可以在Vue组件中使用这个mixin了。我们需要在组件中使用mixins选项来将Mixin混入(mixin)到组件中。

Vue.component('my-component', {
  mixins: [myMixin],
  template: '<div>{{ message }}</div>',
  created: function () {
    this.greet() // 执行myMixin中的方法greet
  }
})

在上面的代码中,我们将myMixin混入到了my-component组件中。所以在my-component组件中,我们可以使用myMixin中定义的message实例属性和greet方法

(2)mixin的合并规则

多个Mixin共同作用于一个组件的时候,Vue中的Mixin会按照一定的规则进行合并;如果多个Mixin有相同的选项,这些选项会被合并到一个选项中,合并规则如下:

  • 数据对象:在组件和Mixin中定义的数据对象会被合并成一个对象。当组件与Mixin同名的属性冲突时,以组件数据为准。
  • 生命周期钩子函数:合并两个Mixin中的同名生命周期钩子时,都会被调用。Mixin的钩子总是在组件的钩子之前被调用。
  • 方法:Mixin中的方法会被合并到组件中,并且优先级高于组件中的同名方法。
  • 其他选项:如props、computed等,都会以和方法相同的方式进行合并。

(3)全局混入mixin

全局混入Mixin的主要作用是向所有的Vue实例添加一些全局的逻辑或方法。这样一来,我们就可以在所有Vue实例内使用这些全局的逻辑或方法。

比如,我们可以在全局Mixin中添加一个$myMethod方法:

Vue.mixin({
  methods: {
    $myMethod: function () {
      console.log('This is a global method.')
    }
  }
})

通过上面的代码,我们就向所有的Vue实例中添加了一个全局方法$myMethod,可以在任何Vue组件内使用。

new Vue({
  created: function () {
    this.$myMethod() //这里就可以调用到已经全局混合的$myMethod方法了
  }
})

总结:

  1. 全局的Mixin可以使用应用app的方法mixin来完成注册;
  2. 一旦注册,那么全局混入的选项将会影响每一个组件;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/631740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云弹性公网EIP收费价格表(按量/包年包月/配置费)

阿里云弹性公网EIP怎么收费&#xff1f;EIP地域不同价格不同&#xff0c;EIP计费模式分为包年包月和按量付费&#xff0c;弹性公网IP可以按带宽收费也可以按使用流量收费&#xff0c;阿里云百科分享阿里云弹性公网IP不同地域、不同计费模式、按带宽和按使用流量详细收费价格表&…

基于springboot+vue技术的在线考试系统源码数据库

源码看这里 https://download.csdn.net/download/2301_76965813/87881785 前台 学生登录&#xff1a; 如果没有账号&#xff0c;首先需要以学生的身份进行注册&#xff0c;即输入姓名、性别、密码以及班级&#xff0c;注册成功之后输入账户名和密码进行登录&#xff0c;进入…

conda虚拟环境配置和系统相关配置

一、conda虚拟环境 首先&#xff0c;尽量别在base中直接安装自己的包。原因有以下两个&#xff1a; 1.base环境是conda运行的基础&#xff0c;没法一键清除&#xff0c;如果损坏base环境要么滚回要么卸载重装&#xff0c;比较麻烦 2.base中很多包并不是项目需要的包&#xff0c…

Spring5

Spring5 文章目录 Spring5一.框架概述二.入门案例三.IOC容器1.IOC概念2.IOC底层原理3.IOC接口 四.IOC操做Bean管理1.Bean管理2.基于xml配置文件方式实现(1).创建对象(2).注入属性第一种注入:set方法第二种注入:有参数的构造p名称空间注入(了解)注入空值和特殊符号外部Bean内部B…

itop-3568开发板驱动学习笔记(27)设备树(六)pinctrl

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 pinctrl 子系统简介pinctrl 设备树语法pinctrl 客户端pinctrl 服务端瑞星微平台全志平台三星平台iMX 平台 pinctrl 子系统简介 Linux pinctrl 子系统用来管理 GPIO 引脚&#xff0c;它主要完成了以下三种功…

MySQL数据库,从入门到精通:第三篇——MySQL 数据库规范和基础查询语句

MySQL数据库&#xff0c;从入门到精通&#xff1a;第三篇——MySQL 数据库规范和基础查询语句 第三篇_MySQL 数据库规范和基础查询语句1. SQL概述1.1 SQL背景知识1.2 SQL语言排行榜1.3 SQL 分类 2. SQL语言的规则与规范2.2 SQL大小写规范 &#xff08;建议遵守&#xff09;2.3 …

设计模式-03.02-创建型-工厂建造者原型

工厂模式【常用】 工厂模式很重要&#xff0c;后面的很多架构设计&#xff0c;都是工厂模式联合着其它设计模式使用。 一般情况下&#xff0c;工厂模式分为三种更加细分的类型&#xff1a;简单工厂、工厂方法和抽象工厂。不过&#xff0c;在 GoF 的《设计模式》一书中&#xff…

docker资源控制cgroup

一、CPU控制 cgroups&#xff0c;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被namespace隔离起来的资源, 还可以为资源设置权重、计算使用量、操控进程启停等等。所以cgroups (Control groups) 实现了对资源的配额和度量。 cgroups有四大功能: 资源限制:可以…

SpringAOP详解

目录 前言&#xff1a; 相关概念 切点表达式规则 代码演示 SpringAOP实现原理 织入&#xff08;代理的生成时机&#xff09; JDK和CGLIB区别 小结&#xff1a; 前言&#xff1a; AOP&#xff08;Aspect Oriented Programming&#xff09;是思想&#xff08;面向切面编程…

文心一言 VS 讯飞星火 VS chatgpt (37)-- 算法导论5.4 1题

一、一个屋子里必须要有多少人&#xff0c;才能让某人和你生日相同的概率至少为1/2? 必须要有多少人&#xff0c;才能让至少两个人生日为 7月 4 日的概率大于 1/2? 文心一言&#xff1a; 一个屋子里必须要有多少人&#xff0c;才能让某人和你生日相同的概率至少为1/2&#…

Linux下ElasticSearch7.9.2安装配置(包含服务器配置、启动停止脚本、开放端口和elasticsearch-head插件的使用)

Linux下ElasticSearch7.9.2安装配置 前言1.下载安装1.1 使用wget的方式下载1.2 官网下载 2.上传到服务器并解压3.修改es配置文件3.1 es目录简介3.2 修改配置文件 4. 创建用户并赋权5. 服务器修改配置5.1 修改文件句柄数和线程数5.2 关闭swapping5.3 修改虚拟内存 6. 启动es6.1 …

“配置DHCP Snooping实验:保护网络中的DHCP服务和防止欺骗攻击“

"配置DHCP Snooping实验&#xff1a;保护网络中的DHCP服务和防止欺骗攻击" 【实验目的】 部署DHCP服务器。熟悉DHCP Snooping的配置方法。验证拓扑。 【实验拓扑】 实验拓扑如图所示。 设备参数如下表所示。 设备 接口 IP地址 子网掩码 默认网关 R1 F0/0 …

腾讯云轻量应用服务器和云服务器区别详细说明

腾讯云轻量应用服务器是什么&#xff1f;腾讯云轻量服务器和云服务器有什么区别&#xff1f;为什么轻量应用服务器费用更低&#xff1f;是因为轻量服务器CPU内存性能比云服务器CVM性能差吗&#xff1f;轻量应用服务器适合中小企业或个人开发者搭建企业官网、博客论坛、微信小程…

基于SPAD / SiPM技术的激光雷达方案

激光雷达(LiDAR)是一种测距技术&#xff0c;近年来越来越多地用于汽车先进驾驶辅助系统(ADAS)、手势识别和3D映射等应用。尤其在汽车领域&#xff0c;随着传感器融合的趋势&#xff0c;LiDAR结合成像、超声波、毫米波雷达&#xff0c;互为补足&#xff0c;为汽车提供全方位感知…

物联网Lora模块从入门到精通(五)光照与温湿度传感器

一、前言 在程序开发中&#xff0c;光照与温湿度的获取是十分常见与重要的&#xff0c;本文我们主要是使用M21温湿度光照三合一传感器&#xff0c;其中温湿度数据通过协议获取&#xff0c;而光照通过ADC获取。 二、代码实现 本文内容较为简单&#xff0c;且后续文章将在本文基…

网络编程Demo:Java的阻塞与非阻塞模式以及Netty

前言 IO既神秘&#xff0c;双简单 IO是什么 从表面理解&#xff0c;IO是输入&#xff08;input&#xff09;、输出(output)的英文首字母的缩写形式&#xff0c;可以简单理解为计算机的输入与输出&#xff0c;描述计算机的数据流动&#xff0c;如使用键盘输入了一个“hello w…

GreenPlum版本升级

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

C语言期末课程设计—【通讯录管理系统】让课程设计不再是痛苦

目录 摘要 第一章 绪论 1.1项目意义 1.2通讯录功能 第二章 详细设计与实现 2.1 Contact程序运行流程图 2.2 AddContact&#xff08;增加&#xff09;函数流程图 2.3 DelContact&#xff08;删除&#xff09;函数流程图 2.4 SearchConact&#xff08;查找&#xff09;…

碳排放预测模型 | Python实现基于机器回归分析的碳排放预测模型——数据清理和准备

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 碳排放预测模型 | Python实现基于机器回归分析的碳排放预测模型——数据清理和准备 研究内容 分析国家在设计用于预测和预测二氧化碳排放的机器学习模型方面的特定记录,利用来自全球绝大多数国家的记录。…

Spring Cloud - 带你认识微服务,简单demo实现服务拆分及远程调用

目录 一、微服务 1.1、简介 1.2、架构工作原理 1.3、架构特点 1.4、简单了解 SpringCloud 二、服务拆分和远程调用 2.1、服务拆分 2.2、微服务远程调用 2.2.1、远程调用分析 2.2.2、具体调用步骤 三、小结 一、微服务 1.1、简介 微服务是一种架构风格&#xff0c;…