props与defineProps

news2024/11/16 21:23:45

在 Vue3 中,script 脚本存在两种情况。一种是 setup 函数,一种是 <script setup>。而针对这两种不同情况,Vue 也存在 props 和 defineProps 两种接收父组件传递数据的形式。

首先,默认已掌握 Vue2 的父子组件 props 传参,然后进行下面的过程。

setup () {} 函数模式

其实在第一章 拉开序幕的 setup 中,解释了 在 setup 函数中,props 的使用方式。

首先定义父组件,通过reactive 定义响应式数据且返回。然后在父组件中引入子组件 <Child>,将响应式数据 person 对象通过 props 方式传递到子组件中。

<template>
  <Child :person="person" />
</template>

<script>
import Child from "./components/Child.vue";
import { reactive } from "vue";

export default {
  name: "App",
  components: {
    Child,
  },
  setup() {
    let person = reactive({
      name: "al",
      age: 29,
    });

    return {person};
  },
};
</script>

然后定义子组件

<template>
  <div>
    {{ person }}
  </div>
</template>

<script>
export default {
  name: 'ChildComponent',
  setup(props) {
    console.log(props,'props');
  }
}
</script>

在 setup 函数中,接收两个参数,第一个就是 props。但是,此时如果直接打印该 props,发现值是一个空对象,且控制台报错。

这是因为,如果使用的是 setup 函数模式,需要像Vue2一样,先通过 props 属性接收,然后才能在 setup 函数中 接收到 props 

export default {
  name: 'ChildComponent',
  props: ['person'],
  setup(props) {
    console.log(props,'props');
  }
}

setup 函数 + ts

上面说的是最基础的 props 数据传递,在Vue3 中更好的支持了ts,以此来限制类型,提高代码质量。所以我们可以通过 ts 来规定参数类型。

// lang 需要配置,表示支持 ts 语法
<script lang="ts">
import Child from "./components/Child.vue";
import { reactive } from "vue";

// 通过 interface 定义接口类型
interface Person {
  name: string,
  age: number,
}

export default {
  name: "App",
  components: {
    Child,
  },
  setup() {
    // 直接调用 Person 接口,以此来控制类型
    let person:Person = reactive({
      name: "al",
      age: 29,
    });

    return {person};
  },
};
</script>

如果,reactive 定义的数据与 Person 接口存在区别,那么 TS 则会飘红报错,例如:我把对象数据的 name 属性故意写错成 ne属性,vs code 则给了警告

当然,我们可以写的更优雅一点,因为 reactive 本身是可以携带泛型的,所以可以写成

// 通过泛型来规范数据
let person = reactive<Person>({
  name: "al",
  age: 29,
});

然后再子组件中通过 props 接收时通过断言的形式指定属性的类型,通过defult指定默认值

props: {
  person: {
    type: Object as () => { name: string; age: number },
    default: () => ({
      name: "al",
      age: 29,
    }),
  },
},

到了这一步,就算是完成了 setup 函数 + TS 的编写。

 <script setup>

<script setup> 模式中是不存在 setup 函数的,当然也不能配置 props 属性。<script setup>里面的代码会被编译成组件中 setup() 函数的内容。

那么现在问题来了,我需要怎么接收父组件传递的 props,以及怎么使用该 props 数据呢?

父组件:数据不变,TS类型不变,改为  <script setup> 形式

<template>
  <Child :person="person" />
</template>

<script lang="ts" setup>
import Child from "./components/Child.vue";
import { reactive } from "vue";

interface Person {
  name: string;
  age: number;
}

let person = reactive<Person>({
  name: "al",
  age: 29,
});
</script>

子组件:Vue3 提供了 一个新的 API -- defineProps 用来接收父组件传递的props 数据。defineProps 是一个函数,接收一个数组参数,数组内部的元素则是父组件传递过来的数据,每个元素都是字符串形式

<template>
  <div>
    {{ person }}
  </div>
</template>

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

defineProps(['person'])

</script>

展示效果:数据正确展示

父组件传递多个数据

<template>
  <Child :person="person" new="newValue" old="oldValue"/>
</template>

子组件只需要在数组中新增元素即可

defineProps(['person','new','old'])

 展示效果:

Vue3 中的 defineProps() 函数返回一个 Proxy 对象,该对象内部包含的是 defineProps() 函数 中接收的 props 数据,可以针对于 props 中的数据进行某些代码逻辑判断。例如

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

let x = defineProps(['person','new','old'])

if (x.person.age > 1) {
  console.log(x);
}
</script>

展示效果:

到此为止,defineProps() 函数的基本使用就完成了,那如果此时我也想通过 TS 来规范数据类型又需要怎么做呢?

 <script setup> + TS

把上面的数据改一下,现在父组件传递的不是一个对象,而是一个数组。数组内部则是个人信息

<template>
  <Person :list="persons" />
</template>

<script lang="ts" setup name="App">
import Person from "./components/Child.vue";
import { reactive } from "vue";

let persons = reactive([
  { id: "e98219e12", name: "张三", age: 18 },
  { id: "e98219e13", name: "李四", age: 19 },
  { id: "e98219e14", name: "王五", age: 20 },
]);
</script>

现在需要对父组件中的数据进行 TS 类型限制。我们可以在当前文件中直接写,但是更建议是新开一个文件专门用来写 TS 类型。例如,在 src 目录下新建 types 文件夹,然后新建 index.ts 文件。

// 定义一个接口,限制每个Person对象的格式
export interface Person {
  id: string,
  name: string,
  age: number
}

// 定义一个自定义类型
// export type Persons = Array<Person>

// 简写的自定义类型
export type Persons = Person[]

父组件中根据 接口 和 自定义类型 来规范数据格式

<script lang="ts" setup name="App">
import Person from "./components/Person.vue";
import { reactive } from "vue";

// 引入类型时需要使用 type 声明,之前版本的ts是不需要的
import { type Persons } from "@/types";    

// 通过泛型规范 persons 数据类型
let persons = reactive<Persons>([
  { id: "e98219e12", name: "张三", age: 18 },
  { id: "e98219e13", name: "李四", age: 19 },
  { id: "e98219e14", name: "王五", age: 20 },
]);
</script>

 在子组件中 通过 defineProps 接收数据

const props = defineProps(['list'])

在子组件中 通过 defineProps 接收数据 + 限制类型:通过泛型限制数据类型

// 引入类型时需要使用 type 声明,之前版本的ts是不需要的
import { type Persons } from "@/types"; 

const props = defineProps<{list:Persons}>()

在子组件中 通过 defineProps 接收数据 + 限制类型 + 是否必须

// 引入类型时需要使用 type 声明,之前版本的ts是不需要的
import { type Persons } from "@/types"; 


// 通过 ? 表示该值不是必须值
const props = defineProps<{list?:Persons}>()

在子组件中 通过 defineProps 接收数据 + 限制类型 + 是否必须 + 指定默认值。此时需要引入新的 API --  withDefaults。该 API 也是一个函数,接收两个参数,第一个是 接收数据 + 限制类型 + 是否必须 的集合体,第二个就是指定的默认值。且默认值必须通过函数返回(类似于Vue2中的默认值)。

import {defineProps,withDefaults} from 'vue'
import {type Persons} from '@/types'

let props = withDefaults(
    defineProps<{list?:Persons}>(),
    { list:()=>[{id:'asdasg01',name:'小猪佩奇',age:18}]}
)

总结

在Vue3 中接收父组件传递的 props 数据存在两种方式

  1. 通过配置式的props ,且使用数组形式 接收父组件传递的数据,然后在 setup 中通过 props 参数获取接收到的数据进行逻辑处理。不处理也可以直接使用。;例如:props : ['a','b','c']
  2. 通过 <script setup> 形式,使用 defineProps() 来接收父组件传递数据,defineProps() 函数接收一个字符串形式的数组,类似['a','b','c'],数组中每一项就是父组件传递的数据。写在 <script setup> 中的代码最终会被编译到 setup() 函数中。例如:defineProps(['list','a','b'])

通过 TS  限制参数类型 + 指定默认值 + 限制必要性 也存在两种方式

  1. 通过配置式的props,且使用对象形式 来接收父组件传递的数据,然后通过配置项来限制
    props: {
      person: {
        // 使用断言控制参数类型
        type: Object as () => { name: string; age: number },
    
        // 通过函数返回默认值,一般只有对象或数组才会如此,基本类型直接写值即可
        default: () => ({
          name: "al",
          age: 29,
        }),
    
        // 是否必须
        isRequied:false
      },
    },
  2. 通过 <script setup> 形式,使用 defineProps() 来接收父组件传递数据,通过泛型来限制数据类型和是否必须,通过 withDefaults() 设置默认值 

    let props = withDefaults(defineProps<{list?:Persons}>(),{
      list:() =>[{id:'asdasg01',name:'小猪佩奇',age:18}]
    })

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

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

相关文章

五轴数控走心机指的是哪五轴

五轴数控走心机&#xff0c;作为现代机械加工领域中的高精度设备&#xff0c;其核心在于其独特的五轴联动系统。这五个轴分别是X1轴、Y1轴、Z1轴、Z2轴和X2轴&#xff0c;它们各自承担着不同的运动和控制功能&#xff0c;共同实现了对工件的复杂加工。 X1轴&#xff1a;作为向下…

北芯生命持续亏损:产能利用率不理想仍扩产能,销售费用越来越高

《港湾商业观察》黄懿 6月29日&#xff0c;深圳北芯生命科技股份有限公司&#xff08;下称“北芯生命”&#xff09;提交首轮问询回复&#xff0c;更新2023年年报财务数据&#xff0c;保荐机构为中国国际金融股份有限公司。 据悉&#xff0c;北芯生命曾向港交所递交上市申请&…

[C++]AVL树插入和删除操作的实现

AVL树又称为高度平衡的二叉搜索树,是1962年由两位俄罗斯数学家G.M.Adel’son-Vel’skii和E.M.Landis提出的。ALV树提高了二叉搜索树树的搜索效率。为此,就必须每向二叉搜索树插人一个新结点时调整树的结构,使得二叉搜索树保持平衡,从而尽可能降低树的高度,减少树的平均搜索长度…

JS简介 JS特点

JS简介 Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的 客户端脚本语言 &#xff0c;主要目的是为了解决服务器端语言&#xff0c;遗留的速度问题&#xff0c;为客户提供更流畅的浏览效果。 JS特点 JS是一种运行于浏览器…

注册中心 Eureka Nacos

文章目录 目录 文章目录 1. 什么是注册中心? 2.常见的注册中心 3 . Eureka 4 . Nacos 5 . Nacos与Eureka的区别 总结 1. 什么是注册中心? 在最初的架构体系中, 集群的概念还不那么流行, 且机器数量也比较少, 此时直接使用DNSNginx就可以满足几乎所有服务的发现. 相…

ABAP正则表达式 特殊字符处理

REPLACE ALL OCCURRENCES OF REGEX [[:space:]] IN <fs_purhdinfo>-cell_value WITH ."可去掉空格或回车键 REPLACE ALL OCCURRENCES OF &#xff1a; IN <fs_purhdinfo>-cell_value WITH ."可去掉空格或回车键 REPLACE ALL OCCURRENCES OF R…

如何构建高效办公管理系统——Java SpringBoot实战教程,2025年最新设计理念

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

413力扣周赛

3274. 检查棋盘方格颜色是否相同 - 给你两个字符串 coordinate1 和 coordinate2&#xff0c;代表 8 x 8 国际象棋棋盘上的两个方格的坐标。以下是棋盘的参考图。 如果这两个方格颜色相同&#xff0c;返回 true&#xff0c;否则返回 false。分析问题&#xff1a; 由图知&…

在安卓和Windows下使用Vizario H264 RTSP

Unity2021.3.35f1&#xff0c;运行模式为ENGINE_SERVER 1.环境设置 Windows设置 安卓设置 2.代码修改 ConnectionProperties中的server必须与真实IP一样&#xff0c;所以需要新增一个获取IP的函数 public string GetLocalIPAddress(){IPHostEntry host;string localIP &quo…

缓解webclient频繁报‘Connection prematurely closed BEFORE response’的问题

现象&#xff1a; 我在Java代码中使用org.springframework.web.reactive.function.client.WebClient进行网络请求&#xff0c;一开始会有比较多的偶发报错&#xff1a;Connection prematurely closed BEFORE response&#xff0c;网络连接莫名其妙就断了。 处理&#xff1a; …

JDBC以及事务

内容概要&#xff1a; 了解JDBC是什么&#xff0c;以及定义&#xff0c;它有什么好处掌握使用JDBC访问数据库掌握使用JDBC进行增删改查掌握数据库注入问题&#xff0c;以及怎么解决数据库注入问题掌握事务的使用&#xff0c;以及为什么需要事务。理解事务的四大特性&#xff1…

InternLM模型部署教程

一、模型介绍 interlm是一系列多语言基础模型和聊天模型。 InternLM2.5 系列&#xff0c;具有以下特点&#xff1a; 出色的推理能力 &#xff1a;数学推理性能达到世界先进水平&#xff0c;超越 Llama3、Gemma2-9B 等模型。1M 上下文窗口 &#xff1a;在 1M 长上下文中几乎完…

【Qt】Qt 网络 | HTTP

文章目录 HTTP Client核心APIQNetworkAccessManagerQNetworkRequestQNetworkReply 代码示例 本文不涉及 HTTP 的相关前置知识&#xff0c;前置知识可参看 URL概念及组成 HTTP请求 HTTP响应及Cookie原理 HTTP Client 进行 Qt 开发时&#xff0c;和服务器之间的通信很多时候也会…

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界!

随着编程语言的不断演进&#xff0c;Python已经成为开发者们心目中的“瑞士军刀”。它的简洁易用、强大的库支持、广泛的应用领域&#xff0c;让它在人工智能、数据分析、网络爬虫、自动化办公等领域展现了无与伦比的优势。那么&#xff0c;如何深入掌握Python这门语言并用它解…

Stable Diffusion【提示词】【居家设计】:AI绘画给你的客厅带来前所未有的视觉盛宴!

前言 参数设置大模型&#xff1a;RealVisXL V4.0 Lightning采样器&#xff1a;DPM SDE Karras采样迭代步数&#xff1a;5CFG&#xff1a;2图片宽高&#xff1a;1024*1024反向提示词&#xff1a;(octane render, render, drawing, anime, bad photo, bad photography:1.3),(wor…

c++编程(24)——map的模拟实现

欢迎来到博主的专栏&#xff1a;c编程 博主ID&#xff1a;代码小号 文章目录 map的底层红黑树的节点 map的模拟实现map的查找与插入map的迭代器 map的底层 map的底层是一个红黑树&#xff0c;关于红黑树的章节博主写在了数据结构专栏当中&#xff0c;因此不再赘述。 templat…

网络安全服务基础Windows--第8节-DHCP部署与安全

DHCP协议理解 定义&#xff1a;DHCP&#xff1a;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff0c;是⼀个应⽤在局域⽹中的⽹络协议&#xff0c;它使⽤UDP协议⼯作。 67&#xff08;DHCP服务器&#xff09;和68&#xff08;DHCP客户端&#xff0…

C语言:常用技巧及误用

一、字符串存储在数组中 int main() {char* arr[7] {"xiaoming","zhangsan","李四"};printf("%s\n", arr[0]);printf("%s\n", arr[2]);return 0; } 二、scanf()函数用法 2.1 scanf()输入字符串 int main() {char arr[10…

raksmart香港大带宽服务器地址

RAKsmart香港大带宽服务器的地址是由RAKsmart公司提供的香港机房所在地&#xff0c;具体地址未在公开资料中披露&#xff0c;但其主要特点是提供高带宽且不限制流量的服务。 RAKsmart是一家成立于2012年的美国公司&#xff0c;其香港机房以提供大带宽、直连内地的优化线路和丰富…

wincc 远程和PLC通讯方案

有 5个污水厂 的数据需要集中监控到1个组态软件上,软件是WINCC。每个污水厂监控系统都是独立的&#xff0c;已经投入运行了&#xff0c; 分站也是WINCC 和西门子PLC 。采用巨控远程模块的话&#xff0c;有两种方式&#xff1a;一种是从现场的PLC取数据&#xff0c;一种是从分站…