Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot
如果您已经对 Vue.js 组件的基础用法了如指掌,可以跳过本小节,不过当做复习稍读一下也无妨。
组件的构成
一个再复杂的组件,都是由三部分组成的:prop、event、slot,它们构成了 Vue.js 组件的 API。如果你开发的是一个通用组件,那一定要事先设计好这三部分,因为组件一旦发布,后面再修改 API 就很困难了,使用者都是希望不断新增功能,修复 bug,而不是经常变更接口。如果你阅读别人写的组件,也可以从这三个部分展开,它们可以帮助你快速了解一个组件的所有功能。
属性 prop
prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。写通用组件时,props 最好用对象的写法,这样可以针对每个属性设置类型、默认值或自定义校验属性的值,这点在组件开发中很重要,然而很多人却忽视,直接使用 props 的数组用法,这样的组件往往是不严谨的。比如我们封装一个按钮组件 <i-button>
:
<template><button :class="'i-button-size' + size" :disabled="disabled"></button>
</template>
<script>// 判断参数是否是其中之一function oneOf (value, validList) {for (let i = 0; i < validList.length; i++) {if (value === validList[i]) {return true;}}return false;}export default {props: {size: {validator (value) {return oneOf(value, ['small', 'large', 'default']);},default: 'default'},disabled: {type: Boolean,default: false}}}
</script>
使用组件:
<i-button size="large"></i-button>
<i-button disabled></i-button>
组件中定义了两个属性:尺寸 size 和 是否禁用 disabled。其中 size 使用 validator 进行了值的自定义验证,也就是说,从父级传入的 size,它的值必须是指定的 small、large、default 中的一个,默认值是 default,如果传入这三个以外的值,都会抛出一条警告。
要注意的是,组件里定义的 props,都是单向数据流,也就是只能通过父级修改,组件自己不能修改 props 的值,只能修改定义在 data 里的数据,非要修改,也是通过后面介绍的自定义事件通知父级,由父级来修改。
在使用组件时,也可以传入一些标准的 html 特性,比如 id、class:
<i-button id="btn1" class="btn-submit"></i-button>
这样的 html 特性,在组件内的 <button>
元素上会继承,并不需要在 props 里再定义一遍。这个特性是默认支持的,如果不期望开启,在组件选项里配置 inheritAttrs: false 就可以禁用了。
插槽 slot
如果要给上面的按钮组件 <i-button>
添加一些文字内容,就要用到组件的第二个 API:插槽 slot,它可以分发组件的内容,比如在上面的按钮组件中定义一个插槽:
<template><button :class="'i-button-size' + size" :disabled="disabled"><slot></slot></button>
</template>
这里的 <slot>
节点就是指定的一个插槽的位置,这样在组件内部就可以扩展内容了:
<i-button>按钮 1</i-button>
<i-button><strong>按钮 2</strong>
</i-button>
当需要多个插槽时,会用到具名 slot,比如上面的组件我们再增加一个 slot,用于设置另一个图标组件:
<template><button :class="'i-button-size' + size" :disabled="disabled"><slot name="icon"></slot><slot></slot></button>
</template>
<i-button><i-icon slot="icon" type="checkmark"></i-icon>按钮 1
</i-button>
这样,父级内定义的内容,就会出现在组件对应的 slot 里,没有写名字的,就是默认的 slot。
在组件的 <slot>
里也可以写一些默认的内容,这样在父级没有写任何 slot 时,它们就会出现,比如:
<slot>提交</slot>
自定义事件 event
现在我们给组件 <i-button>
加一个点击事件,目前有两种写法,我们先看自定义事件 event(部分代码省略):
<template><button @click="handleClick"><slot></slot></button>
</template>
<script>export default {methods: {handleClick (event) {this.$emit('on-click', event);}}}
</script>
通过 $emit,就可以触发自定义的事件 on-click ,在父级通过 @on-click 来监听:
<i-button @on-click="handleClick"></i-button>
上面的 click 事件,是在组件内部的 <button>
元素上声明的,这里还有另一种方法,直接在父级声明,但为了区分原生事件和自定义事件,要用到事件修饰符 .native,所以上面的示例也可以这样写:
<i-button @click.native="handleClick"></i-button>
如果不写 .native 修饰符,那上面的 @click 就是自定义事件 click,而非原生事件 click,但我们在组件内只触发了 on-click 事件,而不是 click,所以直接写 @click 会监听不到。
组件的通信
一般来说,组件可以有以下几种关系:
A 和 B、B 和 C、B 和 D 都是父子关系,C 和 D 是兄弟关系,A 和 C 是隔代关系(可能隔多代)。组件间经常会通信,Vue.js 内置的通信手段一般有两种:
- ref:给元素或组件注册引用信息;
- $parent / $children:访问父 / 子实例。
这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据,比如下面的示例中,用 ref 来访问组件(部分代码省略):
// component-a
export default {data () {return {title: 'Vue.js'}},methods: {sayHello () {window.alert('Hello');}}
}
<template><component-a ref="comA"></component-a>
</template>
<script>export default {mounted () {const comA = this.$refs.comA;console.log(comA.title); // Vue.jscomA.sayHello(); // 弹窗}}
</script>
$parent 和 $children 类似,也是基于当前上下文访问父组件或全部子组件的。
这两种方法的弊端是,无法在跨级或兄弟间通信,比如下面的结构:
// parent.vue
<component-a></component-a>
<component-b></component-b>
<component-b></component-b>
我们想在 component-a 中,访问到引用它的页面中(这里就是 parent.vue)的两个 component-b 组件,那这种情况下,就得配置额外的插件或工具了,比如 Vuex 和 Bus 的解决方案,本小册不再做它们的介绍,读者可以自行阅读相关内容。不过,它们都是依赖第三方插件的存在,这在开发独立组件时是不可取的,而在小册的后续章节,会陆续介绍一些黑科技,它们完全不依赖任何三方插件,就可以轻松得到任意的组件实例,或在任意组件间进行通信,且适用于任意场景。
结语
本小节带您复习了 Vue.js 组件的核心知识点,虽然这并没有完全覆盖 Vue.js 的 API,但对于组件开发来说已经足够了,后续章节也会陆续扩展更多的用法。
基于 Vue.js 开发独立组件,并不是新奇的挑战,坦率地讲,它本质上还是 JavaScript。掌握了 Vue.js 组件的这三个 API 后,剩下的便是程序的设计。在组件开发中,最难的环节应当是解耦组件的交互逻辑,尽量把复杂的逻辑分发到不同的子组件中,然后彼此建立联系,在这其中,计算属性(computed)和混合(mixins)是两个重要的技术点,合理利用,就能发挥出 Vue.js 语言的最大特点:把状态(数据)的维护交给 Vue.js 处理,我们只专注在交互上。
当您最终读完本小册时,应该会总结出和笔者一样的感悟:Vue.js 组件开发,玩到最后还是在拼 JavaScript 功底。对于每一位使用 Vue.js 的开发者来说,阅读完本小册都可以尝试开发和维护一套属于自己的组件库,并乐在其中,而且你会越发觉得,一个组件或一套组件库,就是融合了前端精髓的产出。
扩展阅读
- Vue 组件通信之 Bus
- Vuex通俗版教程
相关文章:

Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot
如果您已经对 Vue.js 组件的基础用法了如指掌,可以跳过本小节,不过当做复习稍读一下也无妨。 组件的构成 一个再复杂的组件,都是由三部分组成的:prop、event、slot,它们构成了 Vue.js 组件的 API。如果你开发的是一个…...

npm install 报 ERESOLVE unable to resolve dependency tree 异常解决方法
问题 在安装项目依赖时,很大可能会遇到安装不成功的问题,其中有一个很大的原因,可能就是因为你的npm版本导致的。 1.npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree 2.ERESOLVE unable to resolve dependenc…...

RPC还是HTTP
RPC是一个远程调用的通讯协议 RPC要比HTTP快一些 1. HTTP体积大 原因是HTTP协议会带着一堆无用信息 HTTP由三部分组成 请求头 请求行 请求体 这三部分只有请求体是需要的 2. HTTP支持的序列化协议比较少 RPC支持更多轻量级的通讯协议 3. RPC协议支持定制...
Conda 常用命令总结
创建虚拟环境 conda create -n name python[your_version] 激活环境 conda activate name 退出环境 conda deactivate 查看虚拟环境 conda info --envs 删除虚拟环境 conda remove -n name --all 删除所有的安装包及cache(索引缓存、锁定文件、未使用过的包和tar包) …...
Spring MVC 文件上传和下载
文章目录 Spring MVC 中文件上传利用 commons-fileupload 文件上传使用 Servlet 3.1 内置的文件上传功能 Spring MVC 中文件下载 Spring MVC 中文件上传 为了能上传文件,必须将 from 表单的 method 设置为 POST,并将 enctype 设置为 multipart/form-data…...

WSL访问adb usb device
1.Windows上用PowerShell运行: winget install --interactive --exact dorssel.usbipd-win 2.在WSLUbuntu上终端运行: sudo apt install linux-tools-generic hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-too…...
CDF与PDF(描述随机变量的分布情况)
一、概念解释 CDF(Cumulative Distribution Function)和PDF(Probability Density Function)是概率论和统计学中常用的两个评价指标,用于描述随机变量的分布情况。 1. CDF(累积分布函数): - CDF是描述随机变量在某个取值及其之前所有可能取值的概率的函数。它表示了累…...
react项目中需要条形码功能,安装react-barcode使用时报错
react项目中需要条形码功能,用yarn add安装react-barcode后,在项目中使用import Barcode from ‘react-barcode’,页面中一直白屏,加载中 查看控制台报以下错误 load component failed Error: Module "./react-barcode"…...

ES6基础(JavaScript基础)
本文用于检验学习效果,忘记知识就去文末的链接复习 1. ECMAScript介绍 ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言…...
[蓝桥杯] 纸张尺寸(C语言)
题目链接 蓝桥杯2022年第十三届省赛真题-纸张尺寸 - C语言网 题目理解 输入一行包含一个字符串表示纸张的名称,该名称一定是 A0、A1、A2、A3、A4、A5、A6、A7、A8、A9 之一,输出两行,每行包含一个整数,依次表示长边和短边的长度…...
AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2024.04.05-2024.04.10
文章目录~ 1.BRAVE: Broadening the visual encoding of vision-language models2.ORacle: Large Vision-Language Models for Knowledge-Guided Holistic OR Domain Modeling3.MedRG: Medical Report Grounding with Multi-modal Large Language Model4.InternLM-XComposer2-4…...

【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos
项目背景 在自研的系统,需要实现类似草料二维码的功能 将我们自己的小程序,通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、生成Qrcode并提交到对象存储 通过源生A…...
kubeadm k8s 1.24之后版本安装,带cri-dockerd
最后编辑时间:2024/3/26 适用于1.24之后的版本 单节点配置 检查是否已经安装kubectl, kubelet, kubeadm直接输入命令确定,如果提示没有该指令则正确 kubectl kubelet kubeadm如果之前安装,首先reset,然后使用apt remove和snap r…...

13-pyspark的共享变量用法总结
目录 前言广播变量广播变量的作用 广播变量的使用方式 累加器累加器的作用累加器的优缺点累加器的使用方式 PySpark实战笔记系列第四篇 10-用PySpark建立第一个Spark RDD(PySpark实战笔记系列第一篇)11-pyspark的RDD的变换与动作算子总结(PySpark实战笔记系列第二篇))12-pysp…...

BI数据分析软件:行业趋势与功能特点剖析
随着数据量的爆炸性增长,企业对于数据的需求也日益迫切。BI数据分析软件作为帮助企业实现数据驱动决策的关键工具,在当前的商业环境中扮演着不可或缺的角色。本文将从行业趋势、功能特点以及适用场景等方面,深入剖析BI数据分析软件࿰…...

centos7上docker搭建vulhub靶场
1 vulhub靶场概述 VulHub是一个在线靶场平台,提供了丰富的漏洞环境供安全爱好者学习和实践。 该平台主要面向网络安全初学者和进阶者,通过模拟真实的漏洞环境,帮助用户深入了解漏洞的成因、利用方式以及防范措施。 此外,VulHub还…...
Flutter入门指南
文章目录 一、环境搭建二、基本概念三、创建一个简单的Flutter应用四、常用组件及代码示例五、总结推荐阅读 笔者项目中使用Flutter的模块并不多。虽然笔者还没有机会在项目中正式使用Flutter,但是也在学习Flutter的一些基本用法。本文就是一篇Flutter的入门介绍&am…...

keepalived脑裂问题
脑裂问题产生的原因 就是vip同时存在 master和backup 就叫做脑裂 比如说 backup 机器的防火墙没关,并且没有允许vrrp通过,backup 没有收到master的心跳数据,就会抢夺资源,发生脑裂问题测试 我们打开test3的防火墙,此…...
【Linux笔记】编mysql库
说明当前编译条件:使用cmake 进行编译<当前编译为Ubuntu PC 版本 在虚拟机上面使用> 一、 cmake 库 【 cmake version 3.16.3 】 二、 openssl 库 【 libopenssl-1.1.1K 】 三、mysql 库 【mysql-5.7.36 】 四、boost 库 【boost_1_59_0 】 一、安装cmake 1.1…...

vscode远程免密登录ssh
vscode远程免密登录ssh 1. 安装vscode2. 安装ssh3. 本地vscode配置免密登录远端开发机1. 本地配置秘钥2. 远程开发机配置秘钥 4. vscode常用小工具1. vscode怎么设置ctrl加滚轮放大字体 1. 安装vscode 2. 安装ssh 设置符号打开config配置文件,点击符号ssh连接新的远…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...