Learning Vue 读书笔记 Chapter 4

embedded/2025/2/2 1:39:59/

4.1 Vue中的嵌套组件和数据流

我们将嵌套的组件称为子组件,而包含它们的组件则称为它们的父组件
父组件可以通过 props向子组件传递数据,而子组件则可以通过自定义事件(emits)向父组件发送事件。
在这里插入图片描述

4.1.1 使用Props向子组件传递数据

在 Vue 组件中,props 字段以对象或数组的形式存在,它包含了该组件可从父组件接收的所有可用数据属性。props 对象的每个属性都对应着目标组件的一个 prop(属性)。若要使组件能够接收父组件传递的数据,您需要在组件的选项对象中声明 props 字段。
在一个子组件中定义props

export default { name: 'ChildComponent', props: { name: String } 
}

将动态变量作为属性传递给子组件。每当children[0]的值发生变化时,Vue也会更新ChildComponent中的name属性,如果需要,子组件将重新渲染其内容。

<template><ChildComponent :name="children[0]" />
</template><script lang="ts">
import ChildComponent from './ChildComponent.vue';export default {data() {return {children: ['Red Sweater', 'Blue T-Shirt', 'Green Hat'],};},
};
</script>

如果name属性不是字符串类型,需要使用v-bind属性(或:)来向子组件传递静态数据,例如:对于布尔类型使用 :name=“true”,对于数组类型使用 :name=“[‘hello’, ‘world’]”
使用v-bind(不是:)来传递整个对象,并将其属性绑定到相关子组件的props上:

<template> <ProductComp v-bind="product" /> 
</template>
4.1.2 声明带验证和默认值的Prop类型

将prop定义为带有默认值的字符串

export default {name: 'ChildComponent',props: {name: {type: String,default: 'Child component'}}
}
4.1.3 使用自定义类型检查声明Props

直接将pizza prop 的类型声明为Pizza类

class Pizza {title: string;description: string;image: string;quantity: number;price: number;constructor(title: string,description: string,image: string,quantity: number,price: number) {this.title = title;this.description = description;this.image = image;this.quantity = quantity;this.price = price;}
}export default {name: 'PizzaComponent',props: {pizza: {type: Pizza,required: true}}
}

或者,你可以使用TypeScript的接口或类型来定义你的自定义类型,而不是使用类。然而,在这种情况下,你必须使用vue包中的PropType类型,并按照以下语法,将声明的类型映射到目标prop

type: Object as PropType<Your-Custom-Type>
import type { PropType } from 'vue';interface Pizza {title: string;description: string;image: string;quantity: number;price: number;
}export default {name: 'PizzaComponent',props: {pizza: {type: Object as PropType<Pizza>,required: true,},},
};
4.1.4 使用defineProps()和withDefaults() 定义Props

使用defineProps和

<script setup>
import { defineProps } from 'vue';const props = defineProps({name: {type: String,default: "Hello from the child component.",},
});
</script>

使用defineProps()和TypeScript 类型声明Props (?代表该type中name属性可有可无)

<script setup>
import { defineProps } from 'vue';type ChildProps = {name?: string;
};const props = defineProps<ChildProps>();
</script>

使用defineProps() 和withDefaults()声明Props

import { defineProps, withDefaults } from 'vue';type ChildProps = {name?: string;
};const props = withDefaults(defineProps<ChildProps>(), {name: 'Hello from the child component.',
});

4.2 使用自定义事件进行组件交流

Vue将传递给子组件的props数据视为只读的原始数据。单向数据流确保只有父组件可以更新数据属性。我们通常希望更新特定的数据属性并将其与父组件同步。为此,我们使用组件选项中的emits字段来声明自定义事件。
以ToDoList组件为例。这个ToDoList将使用ToDoItem作为其子组件来渲染任务列表,代码如下:
ToDoList Component

<template><ul style="list-style: none;"><li v-for="task in tasks" :key="task.id"><ToDoItem :task="task"  @task-completed-toggle="onTaskCompleted"/></li></ul>
</template><script lang="ts">
import { defineComponent } from 'vue';
import ToDoItem from './ToDoItem.vue';
import type { Task } from './ToDoItem';export default defineComponent({name: 'ToDoList',components: {ToDoItem,},data() {return {tasks: [{ id: 1, title: 'Learn Vue', completed: false },{ id: 2, title: 'Learn TypeScript', completed: false },{ id: 3, title: 'Learn Vite', completed: false },] as Task[],};},methods: {onTaskCompleted(payload: { id: number; completed: boolean }) {const index = this.tasks.findIndex(t => t.id === payload.id);if (index < 0) {return;}this.tasks[index].completed = payload.completed;}
}});
</script>

ToDoItem Componet

<template><div><input type="checkbox" :checked="task.completed"  @change="onTaskCompleted"/><span>{{ task.title }}</span></div>
</template><script lang="ts">
import { defineComponent, type PropType } from 'vue';export interface Task {id: number;title: string;completed: boolean;
}export default defineComponent({name: 'ToDoItem',props: {task: {type: Object as PropType<Task>,required: true,},},emits: ['task-completed-toggle']methods: {onTaskCompleted(event: Event) {this.$emit("task-completed-toggle", {...this.task,completed: (event.target as HTMLInputElement)?.checked,});}
}});
</script>

4.3 使用defineEmits()定义自定义事件

ToDoTtem使用defineEmits() 定义自定义事件

<script lang="ts" setup>//...const props = defineProps({task: {type: Object as PropType<Task>,required: true,},});const emits = defineEmits(['task-completed-toggle']);const onTaskCompleted = (event: Event) => {emits("task-completed-toggle", {id: props.task.id,completed: (event.target as HTMLInputElement)?.checked,});}
</script>

4.4 使用provide/inject 进行组件沟通

4.4.1 使用provide 传递数据

组件的option 领域 provide 接受两种格式:数据对象函数。 provide 可以是一个包含要注入数据的对象,每个属性代表一个(键,值)数据类型。在以下示例中,ProductList 向其所有后代提供了数据值 selectedIds,其值为 [1]。

<script>
export default {name: 'ProductList',// ...provide: {selectedIds: [1]},
}
</script>

provide 的另一种格式类型是一个返回对象的函数,该对象包含可用于注入后代的数据。这种格式类型的一个好处是,我们可以访问 this 实例,并将动态数据或组件方法映射到返回对象的相应字段。

<script>
export default {// ...provide() {return {selectedIds: [1]};},// ...
}
</script>
4.4.2 使用 inject接收数据

在这段代码中,Vue将获取注入的selectedIds的值并将其赋给一个本地数据字段currentSelectedIds,如果没有注入值,则使用其默认值[]。

<script lang='ts'>
export default {// ...inject: {currentSelectedIds: {from: 'selectedIds',default: [],},},
}
</script>

http://www.ppmy.cn/embedded/158780.html

相关文章

Github 2025-01-30 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2025-01-30统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10Ollama: 本地大型语言模型设置与运行 创建周期:248 天开发语言:Go协议类型:MIT LicenseStar数量:42421 个Fork数量:2724 次关注人…

php接口连接数据库

框架&#xff1a;https://www.thinkphp.cn/doc 创建网站 域名自己写 创建文件夹&#xff0c;“test”拉取框架&#xff0c;地址栏输入 composer create-project topthink/think5.1.* tp5 会自动创建一个tp5文件夹 根目录选择刚刚创建拉框架的文件夹 以test为示例 “D:\test\…

Ubuntu安装VMware17

安装 下载本文的附件&#xff0c;之后执行 sudo chmod x VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle sudo ./VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle安装注意事项&#xff1a; 跳过账户登录的办法&#xff1a;断开网络 可能出现的问题以及解决…

机试题——连续出牌数量

题目描述 有这么一款单人卡牌游戏&#xff0c;牌面由颜色和数字组成&#xff0c;颜色为红、黄、蓝、绿中的一种&#xff0c;数字为0-9中的一个。游戏开始时玩家从手牌中选取一张卡牌打出&#xff0c;接下来如果玩家手中有和他上一次打出的手牌颜色或者数字相同的手牌&#xff…

vue2项目(一)

项目介绍 电商前台项目 技术架构&#xff1a;vuewebpackvuexvue-routeraxiosless.. 封装通用组件登录注册token购物车支付项目性能优化 一、项目初始化 使用vue create projrct_vue2在命令行窗口创建项目 1.1、脚手架目录介绍 ├── node_modules:放置项目的依赖 ├──…

AI-System 学习

《AI系统原理与架构》ZOMI https://github.com/chenzomi12/AISystem 1PB 1024TB&#xff08;太字节&#xff09; 1PB 1024 x 1024GB&#xff08;千兆字节&#xff09; 1PB 1024 x 1024 x 1024MB&#xff08;兆字节&#xff09; 1PB 1024 x 1024 x 1024 x 1024KB&#xff0…

2025数学建模美赛|赛题评析|难度对比|选题建议

2025年美赛题目整体难度对比&#xff1a;A&#xff1e;D&#xff1e;C&#xff1e;E&#xff1e;B&#xff1e;F A题&#xff1a;新颖的机理分析类题目&#xff0c;目前数模比赛中较少出现&#xff0c;主要考虑材料的不同情况的磨损以及随时间的变化过程&#xff0c;但是可以预…

什么是Pytest Fixtures作用域及如何为Pytest Fixtures设置合适的作用域

关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理&#xff0c;构建成功的基石 在自动化测试工作之前&#xff0c;你应该知道的10条建议 在自动化测试中&#xff0c;重要的不是工具 编写重复代码很可能是你最不乐意做的事情之一。至少对我来说是这样。 在一个全力追…