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?: stringlikes?: 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 stringsreturn ['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 = firstNamethis.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]
})

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

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

相关文章

Nodejs前端学习Day1

妈的&#xff0c;学vue3需要15.0以上的nodejs 文章目录 前言一、学习目标二、学习目录三、为什么JavaScript可以在浏览器中被执行四、为什么JavaScript可以操作DOM和BOM五、浏览器中的JavaScript运行环境总结 前言 妈的&#xff0c;学vue3需要15.0以上的nodejs 一、学习目标 二…

递归和尾递归(用C语言解斐波那契和阶乘问题)

很多人都对递归有了解&#xff0c;但是为尾递归很少&#xff0c;所以这次来专门讲一讲关于尾递归的一些问题。 什么是尾递归 如果一个函数中所有递归形式的调用都出现在函数的末尾&#xff0c;我们称这个递归函数是尾递归的。因为在一些题目的做法中&#xff0c;我们可以发现…

解决 Git:ssh: connect to host github.com port 22: Connection timed out 问题的三种方案

1、问题描述&#xff1a; 其一、整体提示为&#xff1a; ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 中文为&#xff1a; ssh&#xff1a;连接到主机 github.com 端口 22&#xff1a;连接超时 fatal&a…

linux服务器ssh连接慢问题处理

一、 可能导致慢的几个原因 1、网络问题&#xff1a;网络延迟、带宽限制和包丢失等网络问题都有可能导致SSH连接变慢。 2、客户端设置&#xff1a;错误的客户端设置&#xff0c;如使用过高的加密算法或不适当的密钥设置&#xff0c;可能导致SSH连接变慢。 3、服务器负载过高…

使用docker容器 将node应用程序打包成镜像

可以使得node服务应用程序可以通过流水线部署 安装docker 1、注意 我的服务器的系统是 centos7&#xff0c;所以这里写的是在centos7上按照的docker 注意&#xff1a;Docker 要求 CentOS 系统的内容版本高于3.10 uname -r打印&#xff1a;3.10.0-1160.105.1.el7.x86_64 //确定…

leetcode刷题(剑指offer) 240.搜索二维矩阵Ⅱ

240.搜索二维矩阵Ⅱ 编写一个高效的算法来搜索 *m* x *n* 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,…

27.移除元素(力扣LeetCode)

文章目录 27.移除元素&#xff08;力扣LeetCode&#xff09;题目描述方法一&#xff1a;vector成员函数&#xff1a;erase方法二&#xff1a;暴力解法方法三&#xff1a;双指针法 27.移除元素&#xff08;力扣LeetCode&#xff09; 题目描述 给你一个数组 nums 和一个值 val&…

[每日一题] 01.24 - 求三角形

求三角形 n int(input()) count1 (1 n) * n // 2 count2 n * n lis1 [str(i).zfill(2) for i in range(1,count1 1)] lis2 [str(i).zfill(2) for i in range(1,count2 1)]for i in range(0,len(lis2),n):print(.join(lis2[i:i n]))print()for i in range(1,n 1):tem…

代码中遇到的问题

编译器错误消息&#xff1a; CS1061&#xff1a; default_aspx 不包含 GridView1_SelectedIndexChanged 的定义&#xff0c;并且找不到接受类型为default_aspx的第一个参数的可访问扩展方法GridView1_SelectedIndexChanged&#xff08;是否缺少 using 指令或程序集引用&#xf…

[笔记]Spring AOP

Spring AOP&#xff08;Aspect Oriented Programming&#xff09; AOP将应用程序分为核心业务和非核心的公共功能&#xff0c;AOP的关注点是系统中的非核心的公共功能&#xff1b; AOP可以通过预编译或者运行期动态代理的方式&#xff0c;为横跨多个对象&#xff08;没有继承关…

UCAS-AOD遥感旋转目标检测数据集——基于YOLOv8obb,map50已达96.7%

1.UCAS-AOD简介 1.1数据说明 遥感图像&#xff0c;又名高分辨率遥感图像。遥感图像的分类依据是根据成像的介质不同来进行分类的。UCAS-AOD (Zhu et al.&#xff0c;2015)用于飞机和汽车的检测&#xff0c;包含飞机与汽车2类样本以及一定数量的反例样本&#xff08;背景&…

【立创EDA-PCB设计基础】6.布线铺铜实战及细节详解

前言&#xff1a;本文进行布线铺铜实战及详解布线铺铜的细节 在本专栏中【立创EDA-PCB设计基础】前面完成了布线铺铜前的设计规则的设置&#xff0c;接下来进行布线 布局原则是模块化布局&#xff08;优先布局好确定位置的器件&#xff0c;例如排针、接口、主控芯片&#xff…

k8s-基础知识(Pod,Deployment,ReplicaSet)

k8s职责 自动化容器部署和复制随时扩展或收缩容器容器分组group&#xff0c;并且提供容器间的负载均衡实时监控&#xff0c;即时故障发现&#xff0c;自动替换 k8s概念及架构 pod pod是容器的容器&#xff0c;可以包含多个container pod是k8s最小可部署单元&#xff0c;容器…

基于python和定向爬虫的商品比价系统实现

目录 前言 一、系统设计 1. 系统需求分析 2. 系统设计思路 二、系统实现 1. 爬虫部分 2. 比价部分 3. 完整系统代码 三、系统优化 1. 多线程爬取 2. 引入数据库 四、总结 前言 商品比价系统是一种可以帮助用户快速找到最优价格商品的系统。本文将介绍如何使用pyth…

查询文件hash值

查询文件hash值 1 Windows 查询文件hash值1.1 certutil -hashfile 文件名 2 Linux 环境查询文件hash值2.1 sha256sum 文件名2.2 md5sum 文件名 1 Windows 查询文件hash值 在某些环境要对比两个文件是否完全一致 1.1 certutil -hashfile 文件名 certutil -hashfile C:\Users\…

【C++ 自写String】

CString.hpp #include <iostream> #include <string.h>#pragma warning(disable:4996) using namespace std;class CString { private:int len;char* data;public:CString():data(nullptr),len(0) {cout << "0空构造\n";}CString(const char* _da…

计算机服务器中了mallox勒索病毒解密方案计划,勒索病毒解密措施

计算机技术的不断应用与发展&#xff0c;为企业的生产运营提供了有利条件&#xff0c;但网络安全威胁无处不在。近期&#xff0c;广西某生物制药企业的计算机服务器遭到了mallox勒索病毒攻击&#xff0c;导致企业的计算机所有重要数据被加密&#xff0c;严重影响企业的生产运营…

【jetson笔记】torchaudio报错

原因是因为pip安装的包与jetson不兼容导致 自己安装或者cmake编译也会报错 需要拉取官方配置好的docker镜像 拉取docker镜像 具体容器可以看官网&#xff0c;按照自己需求拉取即可 https://catalog.ngc.nvidia.com/orgs/nvidia/containers/l4t-ml 如果其他包不需要只需要torc…

2024区块链应用最趋势,RWA实物资产化

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 实物资产通证化&#xff0…

Conda python运行的包和环境管理 入门

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装 Conda 是一个功能强大的命令行工具&#xff0c;用于在 Windows、macOS 和 Linux 上运行的包和环境管理。 本 conda 入门指南介绍了启动和使用 conda 创建环境和安装包的基础知识。 1. 准备…