Vue3实战笔记(33)—组件传值props终章

文章目录

  • 前言
  • 一、运行时声明、基于类型的声明
  • 二、一个小小的好奇心
  • 三、非 script setup场景下
  • 总结


前言

在 Vue 3 中,组件的声明方式主要有两种:运行时声明和基于类型的声明。这两种方式在 Vue 3 的 Composition API 中体现得尤为明显。


一、运行时声明、基于类型的声明

这两天一直有一个疑问,为什么这种方式声明属性不能支持Type和interface?


  //这种方式会报错,同理,Type声明的类型也不能
    defineProps({
      navigationItem :NavigationItem,//“NavigationItem”仅表示类型,但在此处却作为值使用。ts(2693)
      author: Person,
      book:shtype//“shtype”仅表示类型,但在此处却作为值使用。ts(2693
    })

先来了解一下两个概念:运行时声明、基于类型的声明

当使用


<script setup lang="ts">
const props = defineProps({
  foo: { type: String, required: true },
  bar: Number
})

props.foo // string
props.bar // number | undefined
</script>

这被称之为“运行时声明”,因为传递给 defineProps() 的参数会作为运行时的 props 选项使用。

然而,通过泛型参数来定义 props 的类型通常更直接:


<script setup lang="ts">
const props = defineProps<{
  foo: string
  bar?: number
}>()
</script>

这被称之为“基于类型的声明”。编译器会尽可能地尝试根据类型参数推导出等价的运行时选项。在这种场景下,我们第二个例子中编译出的运行时选项和第一个是完全一致的。

基于类型的声明或者运行时声明可以择一使用,但是不能同时使用。

我们也可以将 props 的类型移入一个单独的接口中:


<script setup lang="ts">
interface Props {
  foo: string
  bar?: number
}

const props = defineProps<Props>()
</script>

还可以从外部导入接口声明:


<script setup lang="ts">
import type { Props } from './foo'

const props = defineProps<Props>()
</script>

在 3.2 及以下版本中,defineProps() 的泛型类型参数仅限于类型文字或对本地接口的引用。

这个限制在 3.3 中得到了解决。最新版本的 Vue 支持在类型参数位置引用导入和有限的复杂类型。但是,由于类型到运行时转换仍然基于 AST,一些需要实际类型分析的复杂类型,例如条件类型,还未支持。您可以使用条件类型来指定单个 prop 的类型,但不能用于整个 props 对象的类型。
上一篇文章中注意到Prop校验的话,有一个默认值选项,官方文档说,

当使用基于类型的声明时,我们失去了为 props 声明默认值的能力。这可以通过 withDefaults 编译器宏解决:


export interface Props {
  msg?: string
  labels?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
  labels: () => ['one', 'two']
})

这将被编译为等效的运行时 props default 选项。此外,withDefaults 帮助程序为默认值提供类型检查,并确保返回的 props 类型删除了已声明默认值的属性的可选标志。

二、一个小小的好奇心

能不能在接口中声明默认值?搜了一下:
在这里插入图片描述
特别好奇,尝试了一下:

interface NavigationItem{
      children: Array<NavigationItem>,
        id:string,
        name:string = 'sh',
        propDef: {
          type: String,
          required: false,
          default:""
        },
        path:string,
        child:{
          id:string,
          name:string,
          path:string,
          child:{}
        }
    }

在这里插入图片描述
接口中也不应该这样的写法,但是编译器没有报错:


        propDef: {
          type: String,
          required: false,
          default:""
        }

实例化时候:

在这里插入图片描述
这是类型啊!!!所以不要把接口和对象的各种约束等方式混淆了。老老实实按照官方文档来吧,好奇害死猫,浪费了不少时间去验证一些奇奇怪怪的想法。还有就是搜到的不一定是你需要的。

三、非 script setup场景下

如果没有使用 script setup,那么为了开启 props 的类型推导,必须使用 defineComponent()。传入 setup() 的 props 对象类型是从 props 选项中推导而来:


import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    message: String
  },
  setup(props) {
    props.message // <-- 类型:string
  }
})

重点来了,基于类型的声明能干的事儿,运行时声明也能干
通过基于类型的声明,一个 prop 可以像使用其他任何类型一样使用一个复杂类型:


<script setup lang="ts">
interface Book {
  title: string
  author: string
  year: number
}

const props = defineProps<{
  book: Book
}>()
</script>

对于运行时声明,我们可以使用 PropType 工具类型:


import type { PropType } from 'vue'

const props = defineProps({
  book: Object as PropType<Book>
})

其工作方式与直接指定 props 选项基本相同:


import { defineComponent } from 'vue'
import type { PropType } from 'vue'

export default defineComponent({
  props: {
    book: Object as PropType<Book>
  }
})

总结

运行时声明: 这是一种传统的 Vue 组件声明方式,它主要依赖于 Vue 的运行时特性。在 Vue 2.x 中,这种方式主要通过 options API 实现,例如 data、methods、computed、watch 等。在 Vue 3 中,虽然 Composition API 被引入,但运行时声明仍然是一种可选的方式。例如,可以直接在 setup 函数中定义响应式变量、方法等,无需额外的类型注解,Vue 3 的响应式系统会在运行时自动处理这些声明。
基于类型的声明: 这种方式是 Vue 3 新引入的,特别是与 TypeScript 一起使用时,可以提供更严格的类型检查和更好的开发体验。基于类型的声明通常涉及到使用 TypeScript 的类型注解来定义组件的 props、emits、slots 以及其他响应式状态。Vue 3 的 Composition API,如 ref、reactive、computed、watch 等函数,都可以与 TypeScript 的类型系统很好地配合工作。

人间的事往往如此,当时提起痛不欲生,几年之后,也不过是一场回忆而已。

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

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

相关文章

如何使用Docker快速运行Firefox并实现远程访问本地火狐浏览器

文章目录 1. 部署Firefox2. 本地访问Firefox3. Linux安装Cpolar4. 配置Firefox公网地址5. 远程访问Firefox6. 固定Firefox公网地址7. 固定地址访问Firefox Firefox是一款免费开源的网页浏览器&#xff0c;由Mozilla基金会开发和维护。它是第一个成功挑战微软Internet Explorer浏…

基于manifest文件批量将coding的仓库导入gitlab中

文章目录 写在前面的话背景编写manifest文件最终效果 写在前面的话 前面有讲过通过manifest清单导入项目到gitlab中&#xff0c;但是实际的操作是不同gitlab实例之间的操作&#xff0c;然而对于在不同gitlab实例的repo迁移而言&#xff0c;显然direct transfer会更合适。 背景…

Spring6笔记(五):国际化、数据校验、提前编译

九、国际化&#xff1a;i18n 9.1 i18n概述 9.2 Java国际化 9.3 Spring6国际化 十、数据校验&#xff1a;Validation 10.1 Spring Validation 概述 10.2 实验一&#xff1a;通过 validator 接口实现 10.3 实验三&#xff1a;Bean Validation 注解 10.4 实验四&#xff1a;实现…

深入了解 RabbitMQ:构建可靠消息传递系统的关键

前言 在现代分布式应用程序开发中&#xff0c;构建可靠的消息传递系统至关重要。RabbitMQ 作为一款强大的消息代理软件&#xff0c;为开发人员提供了丰富的工具和解决方案。本文将深入探讨 RabbitMQ 的核心概念、工作原理以及其在实际应用中的应用场景。 一、什么是 RabbitMQ…

[力扣]——231.2的幂

题目描述&#xff1a; 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2x &#xff0c;则认为 n 是 2 的幂次方。 bool isPowerOfTwo(int n){ if(n0)retur…

Diffusion Policy:基于扩散模型的机器人动作生成策略

项目地址&#xff1a; Diffusion Policy (columbia.edu) 一、摘要 本文介绍了 "扩散策略"&#xff0c;这是一种生成机器人行为的新方法&#xff0c;它将机器人的视觉运动策略&#xff08;visuomotor policy&#xff09;表示为条件去噪扩散过程&#xff08;conditi…

15:00面试,15:08出来,面试问的有点变态。。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天…

Manjaro /opt/google/chrome error

mingcai Manjaro in /opt/google/chrome [22:34:02] $ ./google-chrome [62841:62841:0516/223407.119870:ERROR:process_singleton_posix.cc(353)] 其他计算机 (mingcai-systemproductname) 的另一个 Google Chrome 进程 (2931) 好像正在使用此个人资料。Chrome 已锁定此个人…

PySide6 QStateMachine状态机的实现

PySide6的状态机模块提供了一种方便的方式来实现状态机模式&#xff0c;用于管理程序的状态和状态转换。通过使用PySide6的状态机模块&#xff0c;开发者可以更加清晰地组织程序逻辑&#xff0c;使程序更易于维护和扩展。 在PySide6中&#xff0c;状态机相关的类主要包括&…

探索k8s集群中kubectl的陈述式资源管理

一、k8s集群资源管理方式分类 1.1陈述式资源管理方式&#xff1a;增删查比较方便&#xff0c;但是改非常不方便 使用一条kubectl命令和参数选项来实现资源对象管理操作 即通过命令的方式来实 1.2声明式资源管理方式&#xff1a;yaml文件管理 使用yaml配置文件或者json配置文…

Monkey自动化测试(Android)吐血整理(超详细)

一、前言 随机的命令对APP进行自动化测试&#xff0c;可以快速发现APP的问题&#xff0c;若执行时设置的-S 100出现了一个错误&#xff0c;后面再执行时&#xff0c;只需设置相同的-S&#xff0c;就会按照第一次执行命令的顺序再次执行 自动化就是比较有针对性的对某一个功能…

Jenkins部署成功后自动发通知到钉钉群

钉钉上如何配置 选择钉钉群&#xff0c;找到群设置-机器人-添加机器人 选择自定义 选择【添加】 选择【加签】&#xff0c;复制值&#xff0c;后续在jenkins里配置时会用到 复制Webhook地址&#xff0c;后面在jenkins里配置的时候要用到 Jenkins上如何配置 系统管理-插件管…

数学建模~~多目标规划

1.认识多目标规划 &#xff08;1&#xff09;前面我们介绍的是单目标规划&#xff0c;现在我们要认识一下多目标规划&#xff1a; &#xff08;2&#xff09;使用上面的这个题目作为例子&#xff0c;简单的翻译一下题干&#xff0c;这个题目说的就是 有1&#xff0c;2这两种产…

LeetCode题练习与总结:二叉树的最大深度--104

一、题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root […

Nginx/阿里云/二级域名的配置和使用

阿里云域名解析配置如下&#xff1a; nginx配置如下&#xff1a; 访问地址&#xff1a; zhadmin.iotzzh.com image.png

SD-WAN EVPN基本原理

SD-WAN EVPN是一种用于Overlay业务网络和底层传输网络分离以及业务网络路由和传输网络路由分离的VPN技术。SD-WAN EVPN技术采用类似于BGP/MPLS IP VPN的机制&#xff0c;通过扩展BGP协议&#xff0c;使用扩展后的可达性信息&#xff0c;使不同站点的底层传输网络互通&#xff0…

【NumPy】关于numpy.loadtxt()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

微服务如何做好监控

大家好&#xff0c;我是苍何。 在脉脉上看到这条帖子&#xff0c;说阿里 P8 因为上面 P9 斗争失败走人&#xff0c;以超龄 35 被裁&#xff0c;Boss 上找工作半年&#xff0c;到现在还处于失业中。 看了下沟通记录&#xff0c; 沟通了 1000 多次&#xff0c;但没有一个邀请投递…

MySQL-笔记-02.关系模型基本理论

目录 2.1 关系模型 2.1.1 基本概念 2.1.2 关系的完整性 1 实体完整性 2 参照完整性 3 用户定义完整性 2.2 关系代数 2.2.1 传统的集合运算 1 并运算 2 交运算 3 差运算 4 ​​笛卡尔积​编辑 2.2.2 专门的关系运算 1 选择 2 投影 3 连接 &#xff08;1&#xff09;等…

活动预告|来 GIAC 大会听大数据降本利器:AutoMQ 基于云原生重新设计的 Kafka

GIAC大会 2024年5月24日至25日&#xff0c;2024 全球互联网架构大会&#xff08;简称&#xff1a;GIAC大会&#xff09;将于深圳华侨城洲际酒店举行。大会将聚焦互联网架构热门的 AIGC、效能提升、 云原生架构、数据智能、新硬件等领域&#xff0c;甄选前沿的有典型代表性的技…