Vue组件的嵌套关系;父组件传递子组件props;子组件传递给父组件$emit;自定义事件;案例

目录

  • 1_Vue组件的嵌套关系
    • 1.1_认识组件的嵌套
    • 1.2_组件的拆分
    • 1.3_组件的通信
  • 2_父组件传递子组件props
    • 2.1_父子组件之间通信的方式
    • 2.2_父组件传递给子组件
    • 2.3_Props的对象用法
  • 3_子组件传递给父组件$emit
  • 4_自定义事件(了解)
  • 5_小案例
  • 6_补充

1_Vue组件的嵌套关系

1.1_认识组件的嵌套

前面将所有的逻辑放到一个App.vue中:

  • 在之前的案例中,只是创建了一个组件App;

  • 如果一个应用程序将所有的逻辑都放在一个组件中,那么这个组件就会变成非常的臃
    肿和难以维护;

  • 所以组件化的核心思想应该是对组件进行拆分,拆分成一个个小的组件;

  • 再将这些组件组合嵌套在一起,最终形成的应用程序;

假如将所有的代码逻辑都放到一个App.vue组件中,会发现

  • 代码是非常的臃肿和难以维护的。

  • 在真实开发中,会有更多的内容和代码逻辑,对于扩展性和可维护性来说都是非
    常差的。

  • 所以,在真实的开发中,会对组件进行拆分,拆分成一个个功能的小组件。


1.2_组件的拆分

在这里插入图片描述

按照如上的拆分方式后,开发对应的逻辑只需要去对应的组件编写就可


1.3_组件的通信

上图的嵌套逻辑如下,它们存在如下关系:

  • App组件是Header、Main、Footer组件的父组件;
  • Main组件是Banner、ProductList组件的父组件;

在开发过程中,会经常遇到需要组件之间相互进行通信:

  • 比如App可能使用了多个Header,每个地方的Header展示的内容不同,那么就需要使用者传递给Header一些数据,让其进行展示;
  • 又比如在Main中一次性请求了Banner数据和ProductList数据,那么就需要传递给它们来进行展示;
  • 也可能是子组件中发生了事件,需要由父组件来完成某些操作,那就需要子组件向父组件传递事件;

总之,在一个Vue项目中,组件之间的通信是非常重要的环节

demo:

App.vue

<template><div class="app"><app-header></app-header><app-content></app-content><app-footer></app-footer></div>
</template><script>import AppHeader from './components/AppHeader.vue'import AppContent from './components/AppContent.vue'import AppFooter from './components/AppFooter.vue'export default {// 注册局部组件components: {AppHeader,AppContent,AppFooter}}
</script><style scoped>
</style>

文件目录如下

在这里插入图片描述

AppCotent.vue嵌套了AppCotentList.vue

AppContent.vue代码如下

<template><div class="content"><div class="banner">banner</div><!-- 使用局部组件 --> <app-content-list></app-content-list></div>
</template><script>import AppContentList from './AppContentList'// 通过注册局部组件,嵌套 AppContentLisexport default {components: {AppContentList}}
</script><style scoped>.content {background-color: blue;color: white;}
</style>

AppContentList.vue代码如下

<template><ul><li>商品列表1</li><li>商品列表2</li><li>商品列表3</li><li>商品列表4</li></ul>
</template><script>export default {}
</script><style scoped>
</style>

2_父组件传递子组件props

2.1_父子组件之间通信的方式

父子组件之间如何进行通信呢?

  • 父组件传递给子组件:通过props属性;
  • 子组件传递给父组件:通过$emit触发事件;

在这里插入图片描述


2.2_父组件传递给子组件

在开发中很常见的就是父子组件之间通信,比如父组件有一些数据,需要子组件来进行展示, 这时可通过props来完成组件之间的通信;

Props ?

  • Props是你可以在组件上注册一些自定义的attribute;
  • 父组件给这些attribute赋值,子组件通过attribute的名称获取到对应的值;

Props有两种常见的用法:

  • 方式一:字符串数组,数组中的字符串就是attribute的名称;
  • 方式二:对象类型,对象类型可以在指定attribute名称的同时,指定它需要传递的类型、是否是必须的、默认值等等;

Props的数组用法

如下图所示。但是一般不用数组

在这里插入图片描述


2.3_Props的对象用法

.props数组语法的弊端: 不能对类型进行验证 ;没有默认值的。

而对象的写法可以让的props变得更加完善。

当使用对象语法的时候,可以对传入的内容限制更多:

  • 比如指定传入的attribute的类型;
  • 比如指定传入的attribute是否是必传的;
  • 比如指定没有传入时,attribute的默认值;
    props: {//props: ["name","message"]  原来数组的写法name: {type: String,required:true,default: "我是默认name"},age: {type: Number,required: true,default: 0}}  

type的类型有哪些?

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

对象类型的其他写法

在这里插入图片描述


Prop 的大小写命名

HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符;

也就是说,当使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名;


非Prop的Attribute

什么是非Prop的Attribute呢?

  • 当传递给一个组件某个属性,但是该属性并没有定义对应的props或者emits时,就称之为 非Prop的Attribute;
  • 常见的包括class、style、id属性等;

Attribute继承:- 当组件有单个根节点时,非Prop的Attribute将自动添加到根节点的Attribute中:


禁用Attribute继承和多根节点

如果不希望组件的根元素继承attribute,可以在组件中设置 inheritAttrs: false

  • 禁用attribute继承的常见情况是需要将attribute应用于根元素之外的其他元素;
  • 可以通过 $attrs来访问所有的 非props的attribute;

在这里插入图片描述

多个根节点的attribute: 多个根节点的attribute如果没有显示的绑定,那么会报警告,必须手动的指定要绑定到哪一个属性上:

在这里插入图片描述


3_子组件传递给父组件$emit

什么情况下子组件需要传递内容到父组件呢?

  • 当子组件有一些事件发生的时候,比如在组件中发生了点击,父组件需要切换内容;
  • 子组件有一些内容想要传递给父组件的时候;

如何完成子传父呢?

  • 首先,需要在子组件中定义好在某些情况下触发的事件名称;
  • 其次,在父组件中以v-on的方式传入要监听的事件名称,并且绑定到对应的方法中;
  • 最后,在子组件中发生某个事件的时候,根据事件名称触发对应的事件;

demo:

子组件AddCounter.vue

<template><div class="add"><button @click="btnClick(1)">+1</button><button @click="btnClick(5)">+5</button><button @click="btnClick(10)">+10</button></div>
</template><script>export default {// 1.emits数组语法emits: ["add"],// 2.emmits对象语法> // emits: {//   add: function(count) {  //验证参数//     if (count <= 10) {//       return true//     }//     return false//   }// },methods: {btnClick(count) {console.log("btnClick:", count)// 让子组件发出去一个自定义事件// 第一个参数自定义的事件名称// 第二个参数是传递的参数this.$emit("add", 100)}}}
</script><style scoped>
</style>

父组件App.vue

<template><div class="app"><h2>当前计数: {{ counter }}</h2><!-- 1.自定义add-counter, 并且监听内部的add事件 --><add-counter @add="addBtnClick"></add-counter><!-- 2.自定义sub-counter, 并且监听内部的sub事件 --><sub-counter @sub="subBtnClick"></sub-counter></div>
</template><script>import AddCounter from './AddCounter.vue'import SubCounter from './SubCounter.vue'export default {components: {AddCounter,SubCounter},data() {return {counter: 0}},methods: {addBtnClick(count) {this.counter += count},subBtnClick(count) {this.counter -= count}}}
</script><style scoped>
</style>

4_自定义事件(了解)

比如,封装一个CounterOperation.vue的组件, 内部其实是监听两个按钮的点击,点击之后通过 this.$emit的方式发出去事件;

在这里插入图片描述


自定义事件的参数和验证

自定义事件的时候,可以传递一些参数给父组件。

increnmentTen(){this.$emit("addTen",10)
}

在vue3当中,还可以对传递的参数进行验证。

emits:{addOne: null,subOne: null,addTen: function( payload ){if( payload === 10){return true;}return false}
}

5_小案例

在这里插入图片描述

App.vue代码

<template><div class="app"><!-- 1.tab-control --><tab-control :titles="['衣服', '鞋子', '裤子']" @tab-item-click="tabItemClick"/><!-- 2.展示内容 --><h1>{{ pageContents[currentIndex] }}</h1></div>
</template><script>import TabControl from './TabControl.vue'export default {components: {TabControl},data() {return {pageContents: [ "衣服列表", "鞋子列表", "裤子列表" ],currentIndex: 0}},methods: {tabItemClick(index) {console.log("app:", index)this.currentIndex = index}}}
</script><style scoped>
</style>

TabControl.vue

<template><div class="tab-control"><template v-for="(item, index) in titles" :key="item"><div class="tab-control-item":class="{ active: index === currentIndex }"@click="itemClick(index)"><span>{{ item }}</span></div></template></div>
</template><script>export default {// 父组件传子组件。props: {titles: {type: Array,default: () => []}},data() {return {currentIndex: 0}},// 子组件传递给父组件。事件参数传递emits: ["tabItemClick"],methods: {itemClick(index) {this.currentIndex = indexthis.$emit("tabItemClick", index)}}}
</script><style scoped>.tab-control {display: flex;height: 44px;line-height: 44px;text-align: center;}.tab-control-item {flex: 1;}.tab-control-item.active {color: red;font-weight: 700;}.tab-control-item.active span {border-bottom: 3px solid red;padding: 8px;}
</style>

6_补充

css的scoped :当 <style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。

用npm init vue@latest创建项目时,使用vite打包

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

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

相关文章

【C++】set 和 map 简单了解使用

文章目录 关联式容器set 和 multisetmap 和 multimap 关联式容器 set 和 multiset map 和 multimap

WebDAV之π-Disk派盘+Joplin

Joplin是一个优秀的开源笔记,可以组织到笔记本中的大量笔记和文本编辑器中进行复制,标记和修改。支持Evernote的笔记直接导入到Joplin应用程序中。Joplin还支持各种云服务同步,包括Dropbox、OneDrive、WebDAV或文件系统,方便对其进行检查、备份和移动。该应用程序可用于Win…

为什么DNS协议运行在UDP之上?

DNS (Domain Name System) 运行在 UDP (User Datagram Protocol) 上主要是出于以下原因&#xff1a; 简单性和效率&#xff1a;UDP 是无连接的&#xff0c;这意味着与建立和维护 TCP 连接相比&#xff0c;UDP 有更少的开销。当 DNS 查询被发送时&#xff0c;它只需要一个小的请…

关于@JSONField的使用

1.此注解来自jar包com.alibaba.fastjson 今天分享一个有意思的事情。这个注解作用与类的属性上&#xff0c;如下&#xff1a; ApiModelProperty(value"开始时间,格式:yyyy-MM-dd",required true) JSONField(name"start_date",ordinal 1) private String…

18 Java并发机制的底层实现原理_volatile实现原理

Java并发机制的底层实现原理_volatile实现原理 Java并发机制的底层实现原理volatile 关键字volatile的两条实现原则&#xff08;Lock前缀的作用&#xff09; Java并发机制的底层实现原理 Java代码在编译后会变成Java字节码&#xff0c;字节码被类加载器加载到JVM里&#xff0c;…

将本地项目上传至gitee的详细步骤

将本地项目上传至gitee的详细步骤 1.在gitee上创建以自己项目名称命名的空项目2.进入想上传的项目的文件夹&#xff0c;然后右键点击3. 初始化本地环境&#xff0c;把该项目变成可被git管理的仓库4.添加该项目下的所有文件5.使用如下命令将文件添加到仓库中去6.将本地代码库与远…

项目实战 — 消息队列(7){虚拟主机设计(1)}

目录 一、什么是虚拟主机 二、编写虚拟主机代码 &#x1f345; 1、准备工作 &#x1f345; 2、实现exchange相关操作 &#x1f384;实现创建交换机exchangeDeclare &#x1f384; 实现 删除交换机exchangeDelete &#x1f345; 3、实现queue相关操作 &#x1f384;实现…

SSL证书DV和OV的区别?

SSL证书是在互联网通信中保护数据传输安全的一种加密工具。它能够确保客户端和服务器之间的通信得以加密&#xff0c;防止第三方窃听或篡改信息。在选择SSL证书时&#xff0c;常见的有DV证书和OV证书&#xff0c;它们在验证标准和信任级别上有所不同。那么SSL证书DV和OV的有哪些…

Linux vi/vim

Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器&#xff0c;其他的文书编辑器则不一定会存在。 但是目前我们使用比较多的是 vim 编辑器。 vim 具有程序编辑的能力&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。 什么是 vim&…

Mr. Cappuccino的第60杯咖啡——Spring之BeanFactory和ApplicationContext

Spring之BeanFactory和ApplicationContext 类图BeanFactory概述功能项目结构项目代码运行结果总结 ApplicationContext概述功能MessageSource&#xff08;国际化的支持&#xff09;概述项目结构项目代码运行结果 ResourcePatternResolver&#xff08;匹配资源路径&#xff09;概…

面试热题(岛屿数量)

给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以假设该网格的四条边均…

阿里云Nas文件存储的各种场景使用

文章目录 1.ECS服务器挂载NAS文件存储1.1.添加NAS挂载点1.2.为ECS挂载NAS存储image-202202012230314501.3.验证ECS服务器是否挂载了NAS存储1.4.卸载挂载的NAS存储 2.通过命令行的方式在ECS中挂载NAS存储3.KodCloud云盘系统采用NAS存储用户上传的文件3.1.配置云盘系统接入NAS存储…

爬虫013_函数的定义_调用_参数_返回值_局部变量_全局变量---python工作笔记032

然后再来看函数,可以避免重复代码 可以看到定义函数以及调用函数

【MFC】05.MFC第一大机制:程序启动机制-笔记

MFC程序开发所谓是非常简单&#xff0c;但是对于我们逆向人员来说&#xff0c;如果想要逆向MFC程序&#xff0c;那么我们就必须了解它背后的机制&#xff0c;这样我们才能够清晰地逆向出MFC程序&#xff0c;今天这篇文章就来带领大家了解MFC的第一大机制&#xff1a;程序启动机…

Vulhub之Apache HTTPD 换行解析漏洞(CVE-2017-15715)

Apache HTTPD是一款HTTP服务器&#xff0c;它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞&#xff0c;在解析PHP时&#xff0c;1.php\x0A将被按照PHP后缀进行解析&#xff0c;导致绕过一些服务器的安全策略。 1、docker-compose build、docker-compo…

Technical debt (技术负债 / 技术债)

Technical debt (技术负债 / 技术债) In software development, or any other IT field (e.g., Infrastructure, Networking, etc.) technical debt (also known as design debt or code debt) is the implied cost of future reworking required when choosing an easy but li…

支持对接鸿蒙系统的无线模块及其常见应用介绍

近距离的无线通信得益于万物互联网的快速发展&#xff0c;基于集成部近距离无线连接&#xff0c;为固定和移动设备建立通信的蓝牙技术也已经广泛应用于汽车领域、工业生产及医疗领域。为协助物联网企业终端产品能快速接入鸿蒙生态系统&#xff0c;SKYLAB联手国产芯片厂家研发推…

新能源汽车充电桩控制主板有哪些特点

你是否好奇&#xff0c;新能源汽车充电桩控制主板是什么样子的?它有哪些特点?接下来&#xff0c;我们将为您揭秘。 控制主板是充电桩的大脑&#xff0c;它决定了充电桩的性能和稳定性。睿讯微充电桩主板拥有良好的整机抗干扰能力&#xff0c;能够有效地防止外部信号和电磁波的…

模仿火星科技 基于cesium+水平面积测量+可编辑

​ 当您进入Cesium的编辑水平积测量世界&#xff0c;下面是一个详细的操作过程&#xff0c;帮助您顺利使用这些功能&#xff1a; 1. 创建提示窗&#xff1a; 启动Cesium应用&#xff0c;地图场景将打开&#xff0c;欢迎您进入编辑模式。 在屏幕的一角&#xff0c;一个友好的提…

C++中如何让程序休眠自定义的时长

在C中&#xff0c;可以使用以下几种方法让程序休眠指定的时间&#xff1a; 1 使用操作系统相关的方法&#xff0c;如 Windows 中的 Sleep 函数&#xff0c;需要包含 <windows.h> 头文件 #include <windows.h> // 休眠1000毫秒&#xff08;1秒&#xff09; Sleep(…