vue(十二) 组件二 动态组件(Component)和异步组件(defineAsyncComponent)

文章目录

  • 组件注册
    • 1.全局注册
    • 2.局部注册
    • 3.组件名格式
  • 动态组件
  • 异步组件
    • 1.基本使用
    • 2.加载与错误状态
    • 3.搭配Suspense 组件使用


组件注册

一个 Vue 组件在使用前需要先被“注册”,这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式:全局注册和局部注册。

1.全局注册

使用 Vue 应用实例的 .component() 方法,让组件在当前 Vue 应用中全局可用。

import { createApp } from 'vue'
const app = createApp({})
app.component(// 注册的名字'MyComponent',// 组件的实现{/* ... */}
)
  1. 单文件组件,注册被导入的 .vue 文件:
    import MyComponent from './App.vue'
    app.component('MyComponent', MyComponent)
    // 可以链式调用
    app.component('ComponentA', ComponentA).component('ComponentB', ComponentB).component('ComponentC', ComponentC)
    // 全局注册的组件可以在此应用的任意组件的模板中使用:
    // <!-- 这在当前应用的任意组件中都可用 -->
    <ComponentA/>
    <ComponentB/>
    <ComponentC/>
    

注:所有的子组件也可以使用全局注册的组件,这意味着这三个组件也都可以在彼此内部使用。

  1. 存在的问题
  • 全局注册,没有被使用的组件无法在生产打包时被自动移除 (也叫“tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中。
  • 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性

2.局部注册

局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。

  1. 使用 <script setup> 的单文件组件中,导入的组件可以直接在模板中使用,无需注册:
    import ComponentA from './ComponentA.vue'
    </script><template><ComponentA />
    </template>在这里插入代码片
    
  2. <script setup>,则需要使用 components 选项来显式注册:
    import ComponentA from './ComponentA.js'
    export default {components: {ComponentA},setup() {// ...}
    }
    
  3. components 对象里的属性,它们的 key 名就是注册的组件名,而值就是相应组件的实现。上面的例子中使用的是 ES2015 的缩写语法,等价于:
    export default {components: {ComponentA: ComponentA}// ...
    }
    //ComponentA 注册后仅在当前组件可用,而在任何的子组件或更深层的子组件中都不可用。
    

注:局部注册的组件在后代组件中不可用

3.组件名格式

使用 ComponentA作为组件名的注册格式,这是因为:

  • ComponentA是合法的 JavaScript 标识符。这使得在 JavaScript 中导入和注册组件都很容易,同时 IDE 也能提供较好的自动补全。
  • <ComponentA/> 在模板中更明显地表明了这是一个 Vue 组件,而不是原生 HTML 元素。同时也能够将 Vue 组件和自定义元素 (web components) 区分开来。

在单文件组件和内联字符串模板中,我们都推荐这样做。但是,ComponentA 的标签名在 DOM 内模板中是不可用的,详情参见 DOM 内模板解析注意事项。

Vue 支持将模板中使用 kebab-case 的标签解析为使用 ComponentA注册的组件。这意味着一个以 ComponentA为名注册的组件,在模板中可以通过 <component-a> <component-a> 引用。能够使用同样的 JavaScript 组件注册代码来配合不同来源的模板。

动态组件

  1. 动态组件的概念

多个组件通过component标签挂载在同一个组件中,通过触发动作进行动态切换。常搭配<keep-alive></keep-alive>使用,多用于tab栏的切换等场景

  1. 动态组件的使用和实现
    通过设置<component>标签的is属性来指定要渲染的组件。
// Component.vue
<template><div><buttonv-for="(item, index) in tabs":key="index"@click="currentTab = item.comName">{{ item.name }}</button><component :is="currentTab" class="tab"></component></div>
</template><script lang="ts">
import { reactive, reactive, shallowRef } from 'vue'
import ComA from './components/ComA.vue'
import ComB from './components/ComB.vue'
import { reactive, shallowRef } from 'vue'
export default {setup () {// reactive 会使数据变成响应式,此处为了节省性能开销,可以使用 shallowRef 或者 markRaw 跳过 proxy 代理const currentTab = shallowRef(ComA)const tabs = reactive([{name: 'ComA',comName: shallowRef(ComA)},{name: 'ComB',comName: shallowRef(ComB)},])return {currentTab,tabs,}}}
</script>
  1. vue 3 和vue2.0区别
  • <component :is=>标签可以动态渲染不同的组件,可以根据变量的值来动态切换不同的子组件。
  • vue 2 中is接收的是组件名称,
  • vue 3 中is接收的是组件实例。
  • 也可以使用 is attribute 来创建一般的 HTML 元素。
  • 为了节省性能开销,可以使用shallowRef或者markRaw跳过proxy代理。
  • 当使用 <component :is="..."> 来在多个组件间作切换时,被切换掉的组件会被卸载。可以通过 <KeepAlive> 组件强制被切换掉的组件仍然保持“存活”的状态。

异步组件

1.基本使用

在大型项目中,可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。Vue 提供了defineAsyncComponent 方法来实现此功能:

  1. 获取组件

    import { defineAsyncComponent } from 'vue'
    const AsyncComp = defineAsyncComponent(() => {return new Promise((resolve, reject) => {// ...从服务器获取组件resolve(/* 获取到的组件 */)})
    })
    // ... 像使用其他一般组件一样使用 `AsyncComp`
    

    defineAsyncComponent 方法接收一个返回 Promise 的加载函数。这个 Promise 的 resolve 回调方法应该在从服务器获得组件定义时调用。你也可以调用 reject(reason) 表明加载失败。

  2. ES module动态导入

    ES 模块动态导入也会返回一个 Promise,所以多数情况下会将它和 defineAsyncComponent 搭配使用。类似 Vite 和 Webpack 这样的构建工具也支持此语法 (并且会将它们作为打包时的代码分割点),因此可以用它来导入 Vue 单文件组件:

    <template><div>异步组件<AsyncComponent /></div>
    </template><script lang="ts">
    import { defineAsyncComponent, defineComponent } from 'vue'
    const AsyncComponent = defineAsyncComponent(() => import('./components/myAsyncCom.vue'))
    export default defineComponent({components: {AsyncComponent},setup () {return {}}
    })
    </script>
    <style scoped>
    </style>
    

    最后得到的AsyncComp是一个外层包装过的组件,仅在页面需要它渲染时才会调用加载内部实际组件的函数。它会将接收到的props和插槽传给内部组件,所以你可以使用这个异步的包装组件无缝地替换原始组件,同时实现延迟加载。

    与普通组件一样,异步组件可以使用app.component()全局注册:

    app.component('MyAsyncCom', defineAsyncComponent(() =>import('./components/MyAsyncCom.vue')
    ))
    

    也可以直接在父组件中直接定义它们:

    <template><div>异步组件<AsyncComponent /></div>
    </template><script lang="ts">
    import { defineAsyncComponent, defineComponent } from 'vue'
    const AsyncComponent = defineAsyncComponent(() => import('./components/myAsyncCom.vue'))
    export default defineComponent({components: {AsyncComponent},setup () {return {}}
    })
    </script>
    <style scoped>
    </style>
    

2.加载与错误状态

异步操作不可避免地会涉及到加载和错误状态,因此 defineAsyncComponent() 也支持在高级选项中处理这些状态:

const AsyncComp = defineAsyncComponent({// 加载函数loader: () => import('./Foo.vue'),// 加载异步组件时使用的组件loadingComponent: LoadingComponent,// 展示加载组件前的延迟时间,默认为 200msdelay: 200,// 加载失败后展示的组件errorComponent: ErrorComponent,// 如果提供了一个 timeout 时间限制,并超时了// 也会显示这里配置的报错组件,默认值是:Infinitytimeout: 3000
})
  • 如果提供了一个加载组件,它将在内部组件加载时先行显示。在加载组件显示之前有一个默认的 200ms 延迟——这是因为在网络状况较好时,加载完成得很快,加载组件和最终组件之间的替换太快可能产生闪烁,反而影响用户感受。
  • 如果提供了一个报错组件,则它会在加载器函数返回的 Promise 抛错时被渲染。可以指定一个超时时间,在请求耗时超过指定时间时也会渲染报错组件。

3.搭配Suspense 组件使用

异步组件可以搭配内置的 <Suspense> 组件一起使用,后面组件会对 <Suspense> 进行专门介绍。

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

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

相关文章

git拉取项目前需要操作哪些?

1.输入 $ ssh-keygen -t rsa -C "秘钥说明" 按enter键 2.出现 ssh/id_rsa&#xff1a;(输入也可以不输入也可以) 然后按enter键 3.出现empty for no passphrase&#xff1a;(输入也可以不输入也可以) 然后按enter键 4.出现same passphrase again: (输入也可以不输入也…

程序员如何减肥

目录 基本的生化知识减肥三板斧关于减肥药 基本的生化知识 人体供能顺序。是糖原——脂肪——蛋白质&#xff0c;只有先将肝糖原耗尽&#xff0c;机体才会动用脂肪。因为糖原分解靠的是三羧酸循环&#xff0c;脂肪分解靠的是脂肪动员和丙酮分解。如果一个人动用蛋白质来供能&a…

linux下直接使用别人的anaconda环境,copy别人环境

1.直接使用别人的anaconda安装环境 source /home/XXX/anaconda3/bin/activate conda activate labelme 2.copy anaconda环境 cp -r /home/XXX/anaconda3/envs/x-anylabeling /home/YYY/anaconda3/envs conda config --append envs_dirs /home/YYY/anaconda3/envs conda activa…

20240516-Flyme AIOS 特种兵发布会

目录 1 Flyme AIOS 2 路演功能 2.1 拖拽流转 2.2 任务剧本自定义 2.3 智能体商店 2.4 实况通知 2.5 AI壁纸 3 MYVU 3.1 翻译功能 3.2 AR导航-骑行 3.3 AI语音转文字-科技向善 3.4 Flyme AR-提词器增强 1 Flyme AIOS 1&#xff09;目标&#xff1a;All in AI&#…

AI绘图Stable Diffusion,如何无损高清放大图片,保姆级教程建议收藏!

前言 我们在用 stable diffusion 制作AI图片时&#xff0c;默认生成图片的尺寸为512*512&#xff0c;即使是竖图一般也就是512*768&#xff0c;如果再把尺寸设置大一些&#xff0c;就会因为硬件算力不够而造成系统崩溃&#xff0c;今天就来跟大家聊一聊&#xff0c;如何将制作…

RocketMQ-Dashboard 控制台使用详解

1 安装部署 具体部署启动请参考&#xff1a;RocketMQ从安装、压测到运维一站式文档_rocketmq benchmark压测-CSDN博客 RocketMq的dashboard&#xff0c;有运维页面&#xff0c;驾驶舱&#xff0c;集群页面&#xff0c;主题页面&#xff0c;消费者页面&#xff0c;生产者页面&…

[解决]静态方法不能使用泛型

public static Result<T> success(T data){Result<T> result new Result<>(data);result.setCode("200");result.setMsg("success");return result;}会报错&#xff0c;因为静态方法不能使用泛型 解决方法&#xff1a; 在static后加上…

【Kubenetes】边缘计算KubeEdge架构设计详解

文章目录 前言KubeEdge云边通信方式云端架构设计EdgeController:云到边&#xff1a;边到云 DeviceController:云到边边到云 边缘端架构设计EdgedPod的管理部分Pod的监控部分Pod的卷管理Pod的垃圾回收Pod同步管理 MetaMangger从云到边缘的更新 (Update From Cloud To Edge)从边缘…

入门篇:Kafka基础知识·

目录 一、Kafka简介 二、Kafka核心组件 三、Kafka安装与配置 1.下载与解压 2.配置环境变量 3.配置server.properties 4.启动Kafka服务 四、Kafka基本操作 1.创建Topic 2.查看Topic列表 3.发送消息 4.接收消息 五、Kafka进阶使用 1.消息持久化与存储 2.消息顺序与…

react 使用WebAssembly实战

在React中使用WebAssembly&#xff08;WASM&#xff09;的示例可以通过以下步骤实现&#xff1a; 1. 准备WebAssembly模块 首先&#xff0c;确保你有一个已编译的WebAssembly模块&#xff08;.wasm文件&#xff09;。如果你还没有&#xff0c;可以通过Emscripten等工具将C/C代…

Covalent长期数据设施,支持基于 “blob” 、总锁仓54亿美元的L2

Covalent Network&#xff08;CQT&#xff09;是领先的历史数据可用性网络&#xff0c;通过其在 Web3 中超过 225 个区块链上的结构化数据基础设施&#xff0c;为数千名客户和开发人员提供支持。Covalent Network&#xff08;CQT&#xff09;正在与未来以太坊的进步需求相匹配&…

SQL慢查询学习篇

https://www.cnblogs.com/isyues/p/17733015.html 1. 对扫到的SQL慢查询语句执行 explain explain select task_id, channel, count(task_id) as count from tablename where send_time > "2024-05-10 16:13:59" and send_time < "2024-05-14 16:13:59…

api接口、api文档、api调试、api测试

应用程序接口是一组定义、程序及协议的集合&#xff0c;通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过调用 API 函数对应用程序进行开发&#xff0c;可以减轻编程任务。 API 同时也是一种中间件&#xff0c;为各种不同平台提供数…

展馆展厅设计施工流程

1、需求分析和确定&#xff1a; 与客户沟通&#xff0c;了解客户需求&#xff0c;对展馆展厅的用途、面积、功能、展品特点等进行分析&#xff0c;并确定设计方案。 2、方案设计 根据需求确定设计方案&#xff0c;包括平面布局、展品陈列、展示方式、照明等。设计师需要提供设计…

Linux-yum命令使用详解

目录 一、yum 命令 二、本地yum源配置 1、把光驱挂载到临时挂载点 2、定义本地yum源 3、清空并加载 4、配置国内yum源 5、配置epel源 三、安装软件 一、yum 命令 yum list installed 找出系统上已安装的包 yum list installed > fileName 找出系统上已安装包的列表…

如何在Spring启动的时候执行一些操作

如何在Spring启动的时候执行一些操作 在Spring启动的时候执行一些操作有多种方式。你可以通过实现ApplicationRunner或者CommandLineRunner接口&#xff0c;在Spring Boot应用程序启动后执行特定操作。另外&#xff0c;你也可以使用PostConstruct注解&#xff0c;在Spring Bea…

【考研数学】张宇《1000题》强化阶段正确率多少算合格?

张宇1000题真的很练人心态.... 基础不好&#xff0c;建议别碰1000题 基础好&#xff0c;1000题建议在两个月以内刷完 如果自己本身在基础阶段学的比较水&#xff0c;自己的薄弱点刷了一小部分题没有针对性完全解决&#xff0c;转身去刷1000题就会发现&#xff0c;会的题目刷…

Electron - 跨平台桌面应用开发工具的使用总结

文章目录 一、使用electron-vite新建项目二、目录结构三、渲染进程调用主进程1、方式一 —— 允许有返回值 src/main/index.js src/preload/index.js src/renderer/index.html 2、方式二—— 允许有返回值 (推荐写法) src/main/index.js src/preload/index.js src/renderer/ind…

shell脚本-重定向与管道符

一、重定向 因为shell脚本有着批量操作的特殊性&#xff0c;大部分操作处于后台执行&#xff0c;不需要用户进行干预&#xff0c;所以提取、过滤并执行信息十分需要重定向和管道。重定向的意思是不输出到默认设备上&#xff0c;而是输出到你指定的位置&#xff08;文件、其他输…

scrapy 使用Selenium与Scrapy处理动态加载网页内容的解决方法

引言 在爬虫技术领域&#xff0c;处理动态加载的网页内容常常是一项挑战&#xff0c;尤其是对于那些通过用户滚动或其他交互动态加载更多内容的网站。本文将介绍如何结合使用Selenium和Scrapy来有效处理这类网页。 初探Selenium与Scrapy的结合 首先&#xff0c;我们探索如何使…