vue3-深入组件-组件注册和props更多细节

组件注册

定义好的组件需要注册才能被使用。 注册方式有两种

  1. 全局注册

  2. 局部注册

全局注册

.component() 方法,让组件在当前 Vue 应用中全局可用。 在 main.ts 中

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import GlobalTitle from '@/components/GlobalTitle.vue'


import App from './App.vue'
import router from './router'

const app = createApp(App)

app.component('GlobalTitle', GlobalTitle)

app.use(createPinia())
app.use(router)

app.mount('#app')

在 vue 中直接使用无需导入

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

<template>
  <div class="container">
    <GlobalTitle></GlobalTitle>
  </div>
</template>

<style lang="scss" scoped>
.container {
}
</style>

效果:

全局注册的组件可以在此应用的任意组件的模板中使用,所有的子组件也可以使用全局注册的组件。

全局组件缺点

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

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

局部注册

局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。

它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。

定义组件

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

<template>
  <div class="container">
    <h2>这是一个局部组件</h2>
  </div>
</template>

<style lang="scss" scoped>
.container {
}
</style>

局部使用组件

<script lang="ts" setup>
import { ref } from 'vue'
import PartTitle from '@/components/PartTitle.vue'
</script>

<template>
  <div class="container">
    <PartTitle />
  </div>
</template>

<style lang="scss" scoped>
.container {
}
</style>

组件名格式

推荐 PascalCase 作为组件名的注册格式。

  1. PascalCase 是合法的 JavaScript 标识符。这使得在 JavaScript 中导入和注册组件都很容易,同时 IDE 也能提供较好的自动补全。

  2. <PascalCase /> 在模板中更明显地表明了这是一个 Vue 组件,而不是原生 HTML 元素。同时也能够将 Vue 组件和自定义元素 (web components) 区分开来。

在单文件组件和内联字符串模板中,我们都推荐这样做。

为了方便,Vue 支持将模板中使用 kebab-case 的标签解析为使用 PascalCase 注册的组件。

这意味着一个以 MyComponent 为名注册的组件,在模板中可以通过 <MyComponent> 或 <my-component> 引用。这让我们能够使用同样的 JavaScript 组件注册代码来配合不同来源的模板。

props

Props 声明

一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute。

setup 写法

组件定义

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

const props = defineProps(['person'])
</script>

<template>
  <div class="container">
    <h1>{{ props.person }}</h1>
  </div>
</template>

<style lang="scss" scoped>
.container {
}
</style>

组件使用

<script lang="ts" setup>
import { ref } from 'vue'
import Com14 from '@/components/Com14.vue'
</script>

<template>
  <div class="container">
    <Com14 person="'王大可'" />
  </div>
</template>

<style lang="scss" scoped>
.container {
}
</style>

声明对象形式的属性 setup JavaScript 形式

defineProps({
  title: String,
  likes: Number
})

setup TypeScript 形式

<script setup lang="ts">
defineProps<{
  title?: string
  likes?: number
}>()
</script>

对象形式的 props 声明不仅可以一定程度上作为组件的文档,而且如果其他开发者在使用你的组件时传递了错误的类型,也会在浏览器控制台中抛出警告。

传递 prop 的细节

Prop 属性命名

如果一个 prop 的名字很长,应使用 camelCase 形式,因为它们是合法的 JavaScript 标识符

defineProps({
  greetingMessage: String
})

<span>{{ greetingMessage }}</span>

//推荐写法
<MyComponent greeting-message="hello" />
//或者
<MyComponent greetingMessage="hello" />

模版上使用属性则通常会将其写为 kebab-case 形式,这样和 HTML attribute 写法就一致了。

静态 vs. 动态 Prop

简单讲 就是传入数值是字符串还是变量

//这是静态
<Com14 person="王大可" />
//这是动态
<Com14 :person="personName" />
使用一个对象绑定多个 prop

v-bind 直接绑定对象,即只使用 v-bind 而非某一个属性

const post = {
id: 1,
title: 'My Journey with Vue'
}

<BlogPost v-bind="post" />
// 实际等价于
<BlogPost :id="post.id" :title="post.title" />
单向数据流
  1. 所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。

  2. 这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。

  3. 每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。若你这么做了,Vue 会在控制台上向你抛出警告:

const props = defineProps(['foo'])

// ❌ 警告!prop 是只读的!
props.foo = 'bar'

「更改 props 的场景:」

prop 被用于传入初始值;而子组件想在之后将其作为一个局部数据属性。

在这种情况下,最好是新定义一个局部数据属性,从 props 上获取初始值即可

const props = defineProps(['initialCounter'])

// 计数器只是将 props.initialCounter 作为初始值
// 像下面这样做就使 prop 和后续更新无关了
const counter = ref(props.initialCounter)

需要对传入的 prop 值做进一步的转换。

在这种情况中,最好是基于该 prop 值定义一个计算属性:

const props = defineProps(['size'])

// 该 prop 变更时计算属性也会自动更新
const normalizedSize = computed(() => props.size.trim().toLowerCase())
Prop 校验
  1. Vue 组件可以更细致地声明对传入的 props 的校验要求。

  2. 比如我们上面已经看到过的类型声明,如果传入的值不满足类型要求,Vue 会在浏览器控制台中抛出警告来提醒使用者。

defineProps({
  // 基础类型检查
  // (给出 `null` 和 `undefined` 值则会跳过任何类型检查)
  propA: Number,
  // 多种可能的类型
  propB: [String, Number],
  // 必传,且为 String 类型
  propC: {
    type: String,
    required: true
  },
  // Number 类型的默认值
  propD: {
    type: Number,
    default: 100
  },
  // 对象类型的默认值
  propE: {
    type: Object,
    // 对象或数组的默认值
    // 必须从一个工厂函数返回。
    // 该函数接收组件所接收到的原始 prop 作为参数。
    default(rawProps) {
      return { message: 'hello' }
    }
  },
  // 自定义类型校验函数
  // 在 3.4+ 中完整的 props 作为第二个参数传入
  propF: {
    validator(value, props) {
      // The value must match one of these strings
      return ['success', 'warning', 'danger'].includes(value)
    }
  },
  // 函数类型的默认值
  propG: {
    type: Function,
    // 不像对象或数组的默认,这不是一个
    // 工厂函数。这会是一个用来作为默认值的函数
    default() {
      return 'Default function'
    }
  }
})

defineProps() 宏中的参数不可以访问 <script setup> 中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。

额外说明:

  • 所有 prop 默认都是可选的,除非声明了 required: true

  • 除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined。

  • Boolean 类型的未传递 prop 将被转换为 false。这可以通过为它设置 default 来更改——例如:设置为 default: undefined 将与非布尔类型的 prop 的行为保持一致。

  • 如果声明了 default 值,那么在 prop 的值被解析为 undefined 时,无论 prop 是未被传递还是显式指明的 undefined,都会改为 default 值。

当 prop 的校验失败后,Vue 会抛出一个控制台警告 (在开发模式下)。

运行时类型检查

校验选项中的 type 可以是下列这些原生构造函数:

  • String

  • Number

  • Boolean

  • Array

  • Object

  • Date

  • Function

  • Symbol

type 也可以是自定义的类或构造函数,Vue 将会通过 instanceof 来检查类型是否匹配。

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }
}

defineProps({
  author: Person
})

Vue 会通过 instanceof Person 来校验 author prop 的值是否是 Person 类的一个实例。

Boolean 类型转换
  1. 组件属性使用 Boolean 类型

defineProps({
  disabled: Boolean
})

<!-- 等同于传入 :disabled="true" -->
<MyComponent disabled />

<!-- 等同于传入 :disabled="false" -->
<MyComponent />
  1. prop 被声明为允许多种类型时

只有当 Boolean 出现在 String 之前时,Boolean 转换规则才适用

// disabled 将被转换为 true
defineProps({
  disabled: [Boolean, Number]
})

// disabled 将被转换为 true
defineProps({
  disabled: [Boolean, String]
})

// disabled 将被转换为 true
defineProps({
  disabled: [Number, Boolean]
})

// disabled 将被解析为空字符串 (disabled="")
defineProps({
  disabled: [String, Boolean]
})

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一带一路暨金砖国家技能发展国际联盟大数据和人工智能专业委员会名单

四川城市职业学院和陈老师在序号&#xff1a;158&#xff0c;300 一带一路暨金砖国家技能发展国际联盟大数据和人工智能专业委员会名单 各相关单位&#xff1a; 一带一路暨金砖国家技能发展国际联盟大数据和人工智能专业委员会于2023年11月12日正式成立。经各单位申请、大数据…

kafka-顺序消息实现

kafka-顺序消息实现 场景 在购物付款的时候&#xff0c;订单会有不同的订单状态&#xff0c;对应不同的状态事件&#xff0c;比如&#xff1a;待支付&#xff0c;支付成功&#xff0c;支付失败等等&#xff0c;我们会将这些消息推送给消息队列 &#xff0c;后续的服务会根据订…

数据的存储结构

1.类别 顺序存储、链式存储、散列存储、索引存储 2.顺序存储与链式存储的区别 顺序存储链式存储优点 可以实现随机存取每个元素占用最少的空间 充分利用所有存储单元&#xff0c;不会出现碎片现象。缺点 只能使用整块的存储单元&#xff0c;会产出较多的碎片。 需要额外的存…

12.for 条件循环语句 (3)

for 循环语句 允许脚本一次性读取多个信息&#xff0c;然后逐一对信息进行操作处理。当要处理的数据有范围时&#xff0c;使用for循环语句。 使用 for 循环语句从列表文件中读取多个用户名&#xff0c;然后为其逐一创建用户账户并设 置密码。首先创建用户名称的列表文件users.…

Linux浅学笔记02

目录 grep-wc-管道符 echo-tail-重定向符 vi编辑器 grep-wc-管道符 grep命令(过滤文件内容) //更准确的来说&#xff0c;是筛选包括“所需字符”的一句内容或多句内容。 语法&#xff1a;grep [-n] 关键字 文件路径 //-n&#xff1a;可选&#xff0c;表示在结果中匹配的行…

如何防止联通光猫后台运营商远程自动改超管密码

环境: 联通光猫 ZXHN F677V9 硬件版本号 V9.0 软件版本号 V9.0.0P1T3 U盘16G 笔记本电脑 问题描述: 如何防止联通光猫后台运营商远程自动改超管密码 家里用的是ZXHN F677V9 光猫,自己改了超级密码之后用了几次,最近就无法登录了,问了装维师傅说是最近统一改了,这还…

模型之大脑和计算机的模型化

大脑和计算机的模型化 “素数分解&#xff1a;悬而未决的问题与计算机科学的挑战” 计算机同样也可以看作由相互作用的各部分集合而成&#xff1b;很大程度上由于这个原因&#xff0c;理论计算机科学中同样有很多悬而未决的重要问题。其中有如下这样一个例子&#xff0c;我们…

2023 工业 AR 关键词:纵深和开拓

2023 年&#xff0c;以虚实融合、工业元宇宙为代表的“新数字化”升级在工业制造领域达成共识。 ▲五部委联合印发元宇宙行动计划 通过发展元宇宙赋能新型工业化 而相对过去几年的行业渗透广、落地场景多样的 AR 业务拓展与合作&#xff0c;#纵深和#开拓&#xff0c;成为 2023…

网工内推 | 国企、合资公司IT专员,13薪,NA以上即可

01 上海新徐汇&#xff08;集团&#xff09;有限公司 招聘岗位&#xff1a;IT运维 职责描述&#xff1a; 1.负责制定网络体系搭建、IP地址分配、网络拓扑图、无线网络等&#xff1b; 2.负责桌面运维技术支持&#xff0c;确保各类系统和终端设备正常工作&#xff1b; 3.负责弱电…

构建中国人自己的私人GPT—与文档对话

先看效果 他可以从上传的文件中提取内容作为答案。上传文件摄取速度 摄取速度取决于您正在摄取的文档数量以及每个文档的大小。为了加快摄取速度&#xff0c;您可以在配置中更改摄取模式。 存在以下摄取模式&#xff1a; simple&#xff1a;历史行为&#xff0c;一次按顺序摄…

Bread:一款功能强大的BIOS逆向工程和高级调试工具

关于Bread Bread是一款功能强大的BIOS逆向工程和高级调试工具&#xff0c;该工具也是一个“可注入”的实模式&#xff08;Real-Mode&#xff09;x86调试器&#xff0c;可以帮助广大研究人员通过串行线缆从另一台电脑调试任意实模式代码。 考虑到目前社区中很多BIOS逆向工程工…

学编曲怎么入门 学会编曲能赚钱吗 编曲软件哪个好用 学编曲要先学什么 编曲和作曲什么区别

一、学编曲有什么用 1、工作时间较为自由 编曲是一个技能专业&#xff0c;换句话说&#xff0c;编曲是一项技能&#xff0c;如果能够熟练掌握编曲这项技能&#xff0c;那么就可以尝试从事一些和编曲相关的职业&#xff0c;例如编曲师等等&#xff0c;这类和编曲有关的职业大多…

零基础学Python(5)— 基本数据类型

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。在内存中存储的数据可以有多种类型。例如&#xff1a;一个人的姓名可以用字符型存储&#xff0c;年龄可以使用数值型存储&#xff0c;婚姻状况可以使用布尔型存储。这里的字符型、数值型、布尔型都是Python语言中提供的基本…

gin介绍及helloworld

1. 介绍 Gin是一个golang的微框架&#xff0c;封装比较优雅&#xff0c;API友好&#xff0c;源码注释比较明确&#xff0c;具有快速灵活&#xff0c;容错方便等特点 对于golang而言&#xff0c;web框架的依赖要远比Python&#xff0c;Java之类的要小。自身的net/http足够简单&…

RK3399平台开发系列讲解(USB篇)BusHound 工具使用介绍

🚀返回专栏总目录 文章目录 一、BusHound简介二、BusHound的下载三、BusHound设备窗口四、BUSHound发送命令窗口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 BusHound软件是由美国perisoft公司研制的一种专用于PC机各种总线数据包监视和控制的开发工具软件,其名…

帝国cms无限级分销的逻辑思路效果展示以及表结构的初步规划

#小李子9479# #帝国cms无限级分销# #帝国cms三级分销系统# 关于分销系统 &#xff0c;我们要解决以下几个重要的逻辑关系&#xff0c; 1&#xff0c;用户上下级关系&#xff0c;即A通过分享期邀请链接&#xff0c;B点击或扫码注册后&#xff0c;成为A的下线。 2。下级级别的…

10.常用统计分析方法——主成分分析和因子分析

基础知识&#xff1a; 主成分分析概念 主成分分析PCA&#xff1a;是一种数据降维的技巧&#xff0c;将大量相关变量转化为一组很少的不相关变量&#xff0c;这些无关变量称为主成分。 在特征选择方法中有一种方法是方差过滤&#xff0c;即如果一个特征的方差很小&#xff0c…

ckman:非常好用的ClickHouse可视化集群运维工具

概述 什么是ckman ckman&#xff0c;全称是ClickHouse Management Console&#xff0c; 即ClickHouse管理平台。它是由擎创科技数据库团队主导研发的一款用来管理和监控ClickHouse集群的可视化运维工具。目前该工具已在github上开源&#xff0c;开源地址为&#xff1a;github…

免费SSL申请和自动更新

当前是在mac下操作 安装certbot # mac下brew安装即可 brew install certbotcentos 安装 centos安装文档 申请泛解析证书 sudo certbot certonly --manual --preferred-challengesdns -d *.yourdomain.com## 输出 Saving debug log to /var/log/letsencrypt/letsencrypt.lo…

民用激光雷达行业简析

01. 激光雷达是“机器之眼” • 激光雷达是一个通过发射激光并接受发射激光同时对其进行信号处理&#xff0c;从而获得周边物体距离等信息的主动测量装置。 • 激光雷达主要由光发射、光扫描、光接收三大模块组成。光发射模块集成了驱动、开关和光源等芯片。光接收模块集成了…