Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot

news2024/11/25 2:07:24

如果您已经对 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.js
      comA.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通俗版教程

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

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

相关文章

TechTool Pro for Mac v19.0.3中文激活版 硬件监测和系统维护工具

TechTool Pro for Mac是一款专为Mac用户设计的强大系统维护和故障排除工具。它凭借全面的功能、高效的性能以及友好的操作界面&#xff0c;赢得了广大用户的信赖和好评。 软件下载&#xff1a;TechTool Pro for Mac v19.0.3中文激活版 作为一款专业的磁盘和系统维护工具&#x…

大数据入门之如何利用Phoenix访问Hbase

在大数据的世界里&#xff0c;HBase和Phoenix可谓是一对黄金搭档。HBase以其高效的列式存储和强大的数据扩展能力&#xff0c;成为大数据存储领域的佼佼者&#xff1b;而Phoenix则以其SQL化的操作方式&#xff0c;简化了对HBase的访问过程。今天&#xff0c;就让我们一起看看如…

哲学家带你实现单链表

最近本哲♂学家学习了链表这一新的数据结构&#xff0c;接下来由我带领大家实现链表&#xff1a; 一 、头文件 注&#xff1a;本写法是无头的单链表&#xff0c;所以传参为二级指针。 我们事先写好所要完成的函数&#xff0c;在 .c文件中进一步去完成。 typedef int SLTData…

19(20)-1(3)-CSS3 平面 2D 变换+CSS3 过渡

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍一、CSS3 平面 2D 变换&#x1f48e;1 坐标轴&#x1f48e;2 transform 语法…

云原生数据库海山(He3DB)PostgreSQL版核心设计理念

本期深入解析云原生数据库海山PostgreSQL版&#xff08;以下简称“He3DB”&#xff09;的设计理念&#xff0c;探讨在设计云原生数据库过程中遇到的工程挑战&#xff0c;并展示He3DB如何有效地解决这些问题。 He3DB是移动云受到 Amazon Aurora 论文启发而独立自主设计的云原生数…

【学习】Spring IoCDI

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 Spring 是什么&#xff1f; 什么是 IoC容器&#xff1f; 传统开发模式 loC开发模式 IoC的优势 IoC 的使用 Bean的…

策略为王股票软件源代码-----如何修改为自己软件04

上面是如何打开-------类---------函数 1. 数据结构 1) 股票数据结构的定义在头文件Src\StkLib\Include\Stock.h中,主要的几个结构定义为: KDATA K线数据结构 DRDATA 除权数据结构 REPORT 交易所在交易时间内不断发送的报价信息 MINUTE 分钟成交…

最大连续1的个数 III

题目链接 最大连续1的个数 III 题目描述 注意点 nums[i] 不是 0 就是 10 < k < nums.length 解答思路 创建一个滑动窗口&#xff0c;保证窗口内翻转0的个数始终不大于k&#xff0c;不断移动窗口的右边界&#xff0c;有以下三种情况&#xff1a; 当右边界的值为1&…

Java基础第十课——类与对象(1)

前面二白的九讲属于Java基础方面的内容&#xff0c;总体来说偏基础和简单&#xff0c;能完成的操作也有限&#xff0c;有兴趣的同学可以写一写相关的管理系统&#xff0c;后面二白也会上传一些自己敲的小系统&#xff0c;下面就要开始Java面对对象的知识内容了&#xff0c;从这…

【年度典型案例】扫码就能领补贴?通知社保在线速办?当心是钓鱼骗局!

随着我们生活的数字化程度越来越高&#xff0c;完成各种业务和服务变得前所未有的便捷。只需轻轻一点手机屏幕&#xff0c;我们办事儿变得飞快又方便。然而&#xff0c;正当我们享受这种数字化带来的便捷时&#xff0c;一些不法分子也在暗中伺机而动&#xff0c;利用各种手段制…

c# refc# substring c# 反射c# split c# websocket c# datatable使用

在C#编程中&#xff0c;ref关键字、Substring方法、反射&#xff08;Reflection&#xff09;、Split方法、WebSocket通信以及DataTable的使用都是常见的技术和方法。下面我将逐一为您详解这些内容。 1. C# ref关键字 ref关键字在C#中用于按引用传递参数。这意味着当您将变量作…

PC-lint 学习之配置方法

1. 下载PC-lint 9.0后&#xff0c;点击pclint9setup.exe进行安装&#xff08;我只安装了C/C语言&#xff0c;其他语言可安装时选择&#xff09; 2.安装完成后&#xff0c;打开keil5&#xff0c;选择配置 3. 配置选项 &#xff08;1&#xff09;Lint Executable&#xff1a;在第…

基于SpringBoot+Vue+Mysql的图书管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

html+javascript,用date完成,距离某一天还有多少天

图片展示: html代码 如下: <style>* {margin: 0;padding: 0;}.time-item {width: 500px;height: 45px;margin: 0 auto;}.time-item strong {background: orange;color: #fff;line-height: 100px;font-size: 40px;font-family: Arial;padding: 0 10px;margin-right: 10px…

LeetCode---392周赛

题目列表 3105. 最长的严格递增或递减子数组 3106. 满足距离约束且字典序最小的字符串 3107. 使数组中位数等于 K 的最少操作数 3108. 带权图里旅途的最小代价 一、最长的严格递增或递减子数组 按照题目要求进行模拟即可&#xff0c;这里提供两者思路&#xff1a; 1、两次…

Harmony鸿蒙南向外设驱动开发-Codec

功能简介 OpenHarmony Codec HDI&#xff08;Hardware Device Interface&#xff09;驱动框架基于OpenMax实现了视频硬件编解码驱动&#xff0c;提供Codec基础能力接口给上层媒体服务调用&#xff0c;包括获取组件编解码能力、创建组件、参数设置、数据的轮转和控制、以及销毁…

数据分析python代码——数据填充

在Python中&#xff0c;我们通常使用pandas库来处理和分析数据。数据填充是数据预处理的一个重要步骤&#xff0c;用于处理数据中的缺失值。以下是使用pandas库进行数据填充的示例代码&#xff1a; 在数据分析中&#xff0c;处理缺失值&#xff08;空值&#xff09;是一个重要…

Failed to load dll

Unity运行时提示 dll 加载失败 Plugins: Failed to load ‘Assets/Plugins/xxx.dll’ because one or more of its dependencies could not be loaded. 使用 Dependency Walker 查看这个 dll 引用&#xff0c;一推引用丢失 最后确认是 C 组件缺失 打开 Visual Studio Install…

kafka的概念以及Zookeeper集群 + Kafka集群 +elk集群

准备 3 台服务器做 Zookeeper 集群 192.168.68.5 192.168.68.6 192.168.68.7 安装前准备 //关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0 node1服务器&#xff1a; vim zoo.cfg tickTime2000 #通信心跳时间&#xff0c;Zookeeper服务…