vue3学习(八)--- 组件相关

news2025/3/12 19:15:37

文章目录

  • 全局组件
    • 批量注册全局组件
  • 局部组件
  • 递归组件
    • 组件定义名称方式
      • 1.增加一个script 通过 export 添加name
      • 2.直接使用文件名当组件名
      • 3.使用插件 unplugin-vue-define-options
  • 动态组件
  • 异步组件

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

全局组件

例如组件使用频率非常高(table,Input,button等)这些组件 几乎每个页面都在使用便可以封装成全局组件

使用方法
main.ts 引入我们的组件跟随在createApp(App) 后面 ,切记不能放到mount 后面这是一个链式调用

import { createApp } from 'vue'
import App from './App.vue'
import './assets/css/reset/index.less'
import Card from './components/Card/index.vue'
 
 
createApp(App).component('Card',Card).mount('#app')

注册完之后直接在其他vue页面 立即使用即可 无需引入。

批量注册全局组件

可以参考element-ui 其实就是遍历一下然后通过 app.component 注册
在这里插入图片描述


局部组件

全局注册虽然很方便,但有以下几个问题:

  1. 全局注册,但并没有被使用的组件无法在生产打包时被自动移除 (也叫“tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中。

  2. 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。

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

在使用 <script setup> 的单文件组件中,导入的组件可以直接在模板中使用,无需注册

<template>
  <ComponentA />
</template>

<script setup>
import ComponentA from './ComponentA.vue'
</script>

如果没有使用 <script setup>,则需要使用 components 选项来显式注册:


<template>
  <ComponentA />
</template>

<script>
import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  setup() {
    // ...
  }
}
</script>

递归组件

原理跟我们写js递归是一样的,自己调用自己通过一个条件来结束递归,否则导致内存泄漏。

父组件
<template>
  <child :data="data"></child>
</template>

<script lang="ts" setup>
import { reactive } from 'vue'
import child from './child.vue'

type TreeList = {
  name: string
  checked?: boolean
  children?: TreeList[]
}
const data = reactive<TreeList[]>([
  {
    name: '1',
    checked: true,
    children: [
      {
        name: '1-1',
        checked: false,

        children: [
          {
            name: '1-1-1',
            checked: false,
            children: [
              {
                name: '1-1-1-1',
                checked: false,
              },
            ],
          },
        ],
      },
    ],
  },
  {
    name: '2',
    checked: false,

    children: [
      {
        name: '2-1',
        checked: false,
      },
    ],
  },
  {
    name: '3',
    checked: false,
  },
])
</script>

<style scoped></style>

子组件
<template>
  <div class="tree" v-for="item in data">
    <input type="checkbox" v-model="item.checked" />
    <span>{{ item.name }}</span>
    这里做的递归组件
    <recursion v-if="item?.children?.length" :data="item?.children"></recursion>
  </div>
</template>

<script lang="ts" setup>
import {} from 'vue'
type TreeList = {
  name: string
  checked?: boolean
  children?: TreeList[]
}
const props = defineProps<{
  data?: TreeList[]
}>()
</script>

这种写法可以直接使用name作为递归组件名称 新写一个script
<script lang="ts">
export default {
  name:'recursion'
}
</script>

<style scoped>
.tree{
  margin-left: 20px;
}
</style>

组件定义名称方式

1.增加一个script 通过 export 添加name

<script lang="ts">
export default {
  name:"TreeItem"
}
</script>

2.直接使用文件名当组件名

一个单文件组件可以通过它的文件名被其自己所引用。例如:名为 FooBar.vue 的组件可以在其模板中用 <FooBar/> 引用它自己。
请注意这种方式相比于导入的组件优先级更低。如果有具名的导入和组件自身推导的名字冲突了,可以为导入的组件添加别名:

import { FooBar as FooBarChild } from './components'

3.使用插件 unplugin-vue-define-options

 npm i unplugin-vue-define-options -D

配置vite.config.ts

import { defineConfig } from 'vite'
import DefineOptions from 'unplugin-vue-define-options/vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue(), DefineOptions()],
})

在tsconfig.json设置types(typescript项目中,如果不设置该属性,会报红。)

{
    "compilerOptions": {
       "types": ["unplugin-vue-define-options/macros-global" /* ... */]
    }
}

若是项目中使用了eslint,可以在.eslintrc.js配置文件中,配置globals选项

// .eslintrc.js
module.exports = {
    globals: { defineOptions: 'writable' }
}

使用

<template></template>

<script setup lang="ts">
import { ref } from 'vue'

defineOptions({
  name: 'ComponentName'
})
</script>

<style scoped></style>


动态组件

让多个组件使用同一个挂载点,并动态切换,这就是动态组件。
比如tab切换不同内容

主要通过Vue<component> 元素和特殊的 is属性实现的。

先看下vue2和vue3的区别

vue2

<template>
  <div>
    <component :is="A"></component>
  </div>
</template>
 
<script>
import A from './A';
export default {
  name: 'paysuccess',
  data() {
    return {
      
    }
  },
  components: {
    A
  },
}
</script>
 
<style lang="less" scoped>
 
 
</style>

vue3

<template>
  <div class="tabs-content" @click="switchTab(tab)" v-for="(tab, index) in tabData" :key="index">
    {{ tab.name }}
  </div>
  <component :is="currentTab.tabComp"></component>
</template>
<script setup lang="ts">
import { reactive, markRaw } from 'vue'
import A from './A.vue'
import B from './B.vue'
import C from './C.vue'
 
type tabType = {
  name: string,
  tabComp: any
}
 
type Comp = Pick<tabType, 'tabComp'>
const tabData = reactive<tabType[]>([
  {
    name: 'A组件',
    // proxy会代理reactive中的所有内容
    // 无需对组件进行proxy代理
    // 必须使用markRaw跳过对组件的代理,否则vue会给警告
    tabComp: markRaw(A)
  },
  {
    name: 'B组件',
    tabComp: markRaw(B)
  },
  {
    name: 'C组件',
    tabComp: markRaw(C)
  },
])
 
let currentTab = reactive<Comp>({
  tabComp: tabData[0].tabComp
})
 
const switchTab = (tab: tabType) => {
  currentTab.tabComp = tab.tabComp
}
</script>
<style scoped lang="less">
.tabs-content {
  display: inline-block;
  width: 100px;
  border: 1px solid #ccc;
  background: rgb(175, 96, 96);
  color: white;
}
</style>
  1. Vue2 的时候is 是通过组件名称切换的, 在Vue3 setup 是通过组件实例切换的
  2. vue3如果你把组件实例放到Reactive Vue会给你一个警告,这是因为reactive 会进行proxy 代理 而我们组件代理之后毫无用处 节省性能开销 推荐我们使用shallowRef 或者 markRaw 跳过proxy 代理

异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块 并且减少主包的体积,这时候就可以使用异步组件

<template>
  <Suspense>
          <template #default>
              <Dialog>
                  <template #default>
                      <div>我在哪儿</div>
                  </template>
              </Dialog>
          </template>

          <template #fallback>
              <div>loading...</div>
          </template>
      </Suspense>
</template>

<script setup lang="ts">
import { reactive, ref, markRaw, toRaw, defineAsyncComponent } from 'vue'
 
const Dialog = defineAsyncComponent(() => import('../../components/Dialog/index.vue'))
 
// 下边是完整写法
 
const AsyncComp = defineAsyncComponent({
  // 加载函数
  loader: () => import('../../components/Dialog/index.vue'),
 
  // 加载异步组件时使用的组件
  loadingComponent: LoadingComponent,
  // 展示加载组件前的延迟时间,默认为 200ms
  delay: 200,
 
  // 加载失败后展示的组件
  errorComponent: ErrorComponent,
  // 如果提供了一个 timeout 时间限制,并超时了
  // 也会显示这里配置的报错组件,默认值是:Infinity
  timeout: 3000
})

<suspense> 组件有两个插槽。它们都只接收一个直接子节点。default 插槽里的节点会尽可能展示出来。如果不能,则展示 fallback 插槽里的节点。一般用于加载异步组件,在组件没加载出来之前展示一个骨架屏

异步组件通过import()函数形式引入属于懒加载,只有在用到的时候才会加载,不会打包到主包里面这样也减少了主包的体积也算是性能上的优化

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

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

相关文章

从实时数据库转战时序数据库,他陪伴 TDengine 从 1.0 走到 3.0

关于采访嘉宾 在关胜亮的学生时代&#xff0c;“神童”这个称号如影随形&#xff0c;很多人初听时会觉得这个称谓略显夸张&#xff0c;有些人还会认为这是不是就是一种调侃&#xff0c;但是如果你听说过他的经历&#xff0c;就会理解这一称号的意义所在了。 受到教师母亲的影…

Mobpush厂商通道回执配置指南

为了帮助客户追踪和分析推送效果&#xff0c;Mobpush为APP开发者提供了用户收到推送后行为特征的数据分析&#xff0c;但由于用户使用的设备存在较大差异&#xff0c;不同厂商通道之间配置存在较大差异&#xff0c;不同的厂商通道对送达、展示和点击数据回执的支持程度各不相同…

汽车智能制造中的RFID技术在供应链生产管理中的应用

行业背景 汽车零部件工业是汽车工业中至关重要的一部分&#xff0c;对于汽车工业的长期稳定发展起着基础性的作用&#xff0c;近年来&#xff0c;汽车配件配套市场规模达到了2000亿元&#xff0c;维修市场达到了600亿元&#xff0c;随着汽车国产化的推进&#xff0c;汽车零部件…

机器学习-ROC曲线:技术解析与实战应用

目录 一、引言ROC曲线简介 二、ROC曲线的历史背景二战雷达信号检测在医学和机器学习中的应用横跨多个领域的普及 三、数学基础True Positive Rate&#xff08;TPR&#xff09;与False Positive Rate&#xff08;FPR&#xff09;True Positive Rate&#xff08;TPR&#xff09;F…

DNS域名解析与Web服务

一、DNS 域名解析 1、概念&#xff1a; (1) DNS&#xff1a; DNS&#xff08;Domain Name System&#xff09;是一种用于将可读的域名&#xff08;如www.baidu.com&#xff09;转换为计算机可理解的IP地址&#xff08;如192.168.1.1&#xff09;的分布式命名系统&#xff0c…

uniapp(uncloud) 使用生态开发接口详情5(云公共模块)

1.uniCloud官网 云对象中云公共模块: 网站: https://uniapp.dcloud.net.cn/uniCloud/cf-common.html // 官网介绍 cloudfunctions├─common // 云函数公用模块目录| └─hello-common // 云函数公用模块| ├─package.json| └─index.js // 公用模块代码&#xff0…

BaiChuan2保姆级微调范例

前方干货预警&#xff1a;这可能是你能够找到的&#xff0c;最容易理解&#xff0c;最容易跑通的&#xff0c;适用于各种开源LLM模型的&#xff0c;同时支持多轮和单轮对话数据集的大模型高效微调范例。 我们构造了一个修改大模型自我认知的3轮对话的玩具数据集&#xff0c;使用…

Scrapy设置代理IP方法(超详细)

Scrapy是一个灵活且功能强大的网络爬虫框架&#xff0c;用于快速、高效地提取数据和爬取网页。在某些情况下&#xff0c;我们可能需要使用代理IP来应对网站的反爬机制、突破地理限制或保护爬虫的隐私。下面将介绍在Scrapy中设置代理IP的方法&#xff0c;以帮助您更好地应对这些…

PAM从入门到精通(六)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;五&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 五、主要函数详解 4. pam_get_item 概述&#xff1a; 获取…

YUV图片常见格式

YUV图像 1个亮度量Y2个色度量(UV) 兼容黑白电视 可以通过降低色度的采样率而不会对图像质量影响太大的操作&#xff0c;降低视频传输带宽 有很多格式&#xff0c;所以渲染的时候一定要写对&#xff0c;不然会有很多问题&#xff0c;比如花屏、绿屏 打包格式 一个像素点一…

SRE 的黄昏,平台工程的初晨

船停在港湾是最安全的&#xff0c;但这不是造船的目的 完成使命的 SRE 过去 10 年&#xff0c;SRE 完成了体系化保障系统稳定性的使命。但在这个过程中&#xff0c;SRE 也逐渐变成了庞大的组织。而 SRE 本身的定位是保障系统稳定性&#xff0c;许多时候会因为担心稳定性而减缓…

线性代数-Python-01:向量的基本运算 -手写Vector -学习numpy的基本用法

文章目录 代码目录结构Vector.py_globals.pymain_vector.pymain_numpy_vector.py 一、创建属于自己的向量1.1 在控制台测试__repr__和__str__方法1.2 创建实例测试代码 二、向量的基本运算2.1 加法2.2 数量乘法2.3 向量运算的基本性质2.4 零向量2.5 向量的长度2.6 单位向量2.7 …

Linux上Docker的安装以及作为非运维人员应当掌握哪些Docker命令

目录 前言 1、安装步骤 2、理解镜像和容器究竟是什么意思 2.1、为什么我们要知道什么是镜像&#xff0c;什么是容器&#xff1f; 2.2、什么是镜像&#xff1f; 2.3、什么是容器&#xff1f; 2.4、Docker在做什么&#xff1f; 2.5、什么是镜像仓库&#xff1f; 2、Dock…

ArkTS开发实践

声明式UI基本概念 应用界面是由一个个页面组成&#xff0c;ArkTS是由ArkUI框架提供&#xff0c;用于以声明式开发范式开发界面的语言。 声明式UI构建页面的过程&#xff0c;其实是组合组件的过程&#xff0c;声明式UI的思想&#xff0c;主要体现在两个方面&#xff1a; 描述U…

基于PHP的毕业生招聘管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

吃鸡战队都爱!KOTIN京天华盛定制主机值得拥有

开学季大促正在进行时&#xff0c;少不了来自KOTIN京天的关爱&#xff01;称心满意的初秋&#xff0c;就来京天华盛官方旗舰店挑选一台心仪已久的电脑吧。准备入学的校友们和走过路过的游戏爱好者可千万不能错过了。 作为定制游戏电脑的行业佼佼者&#xff0c;KOTIN京天在各个价…

Android12之DRM架构(一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

视频太大怎么压缩变小?三分钟学会视频压缩

随着科技的不断发展&#xff0c;视频已经成为了我们日常生活中不可或缺的一部分&#xff0c;然而&#xff0c;大尺寸的视频文件常常会给我们带来诸多困扰&#xff0c;例如发送不便、存储空间不足等等&#xff0c;那么&#xff0c;如何将这些过大的视频文件压缩变小呢&#xff1…

公司如何防止源代码外泄,保护开发部门代码安全呢?

在智能制造业中&#xff0c;研发人员的开发环境&#xff0c;大多数采用c#开发语言svn 或c#git进行软件系统的开发&#xff0c;但是c#语言如何来防泄密保护呢&#xff1f;德人合科技针对于制造类企业制定了安全稳定的源代码防泄密方案&#xff0c;不影响员工的正常工作&#xff…

Vivado详细使用教程 | LED闪烁示例

文章目录 整体流程第一步&#xff1a;新建工程第二步&#xff1a;设计输入第三步&#xff1a;功能仿真第四步&#xff1a;分析与综合第五步&#xff1a;约束输入第六步&#xff1a;设计实现第七步&#xff1a;下载比特流 整体流程 打开软甲------>新建工程------->设计输…