【ElementPlus源码】Button 按钮

文章目录

    • 准备工作
    • 属性
    • 方法
    • 模板
    • 使用到的hooks
      • use-prop
      • useDeprecated

看源码时候做的笔记。

准备工作

本地开发 | Element Plus (element-plus.org)

文档与源码对应:docs/examples/button

在这里插入图片描述
组件源码位置: packages/components/button/src

属性

定义在 packages/components/button/src/button.ts(下面路径packages/components/button省略。)

以下面三个属性为例。buttonProps 定义了button有哪些属性,和属性的类型。如size的类型是useSizeProp,即是字符串类型的,values值是枚举值,非必填的属性。

export const buttonProps = buildProps({
  /**
   * @description button size
   */
  size: useSizeProp,
  /**
   * @description disable the button
   */
  disabled: Boolean,
  /**
   * @description button type
   */
  type: {
    type: String,
    values: buttonTypes,
    default: '',
  })

useSizeProp

export const useSizeProp = buildProp({
  type: String,
  values: componentSizes,
  required: false,
} as const)

componentSizes

export const componentSizes = ['', 'default', 'small', 'large'] as const

在这里插入图片描述

buildProps是一个构建属性的方法,没看懂。

buttonProps -> prop:从buttonProps到button.vue 的props

// buttonProps -> ButtonProps 
// src / button.ts
export type ButtonProps = ExtractPropTypes<typeof buttonProps>

// ButtonProps -> useButton 
// src / use-button.ts
export const useButton = (
  props: ButtonProps,
  emit: SetupContext<ButtonEmits>['emit']
) => {...}

// buttonProps-> props 
// src / button.vue
const props = defineProps(buttonProps)

// src / button.vue
// 用props创建button实例,并解构出一堆属性
const { _ref, _size, _type, _disabled, _props, shouldAddSpace, handleClick } =
  useButton(props, emit)

调用useButton创建button实例,解构出一堆属性。

这些属性一部分绑定到class上,如:_size, _type, _disabled其他props的属性 。用于控制按钮的样式

// useNamespace,用于生成 BEM(Block Element Modifier)命名规则的类名和 CSS 变量名
const ns = useNamespace('button')

//  生成符合 BEM 命名规则的类名,绑定到元素的class上
const buttonKls = computed(() => [
  ns.b(),
  ns.m(_type.value),
  ns.m(_size.value),
  ns.is('disabled', _disabled.value),
  ns.is('loading', props.loading),
  ns.is('plain', props.plain),
  ... // 其他props的属性
])

// 绑定在class上
 <component
    :is="tag"
    ref="_ref"
    v-bind="_props"
    :class="buttonKls" // 这里
    :style="buttonStyle"
    @click="handleClick"
  >

一部分绑定到属性上:v-bind="_props"

解构出的点击事件handleClick绑定到@click上。

解构出的shouldAddSpace通过defineExpose暴露出去:

// button.vue
defineExpose({
  /** @description button html element */
  ref: _ref,
  /** @description button size */
  size: _size,
  /** @description button type */
  type: _type,
  /** @description button disabled */
  disabled: _disabled,
  /** @description whether adding space */
  shouldAddSpace,
})

对应button方法:

在这里插入图片描述
可以通过this.refs.refName调用看到:

// template
<el-button ref="buttonRef">Button</el-button>
// script
console.log(this.$refs.buttonRef);

在这里插入图片描述

方法

buttonEmits -> button实例。

// src / button.ts
export const buttonEmits = {
  click: (evt: MouseEvent) => evt instanceof MouseEvent,
}

// src / button.vue
const emit = defineEmits(buttonEmits)
const { _ref, _size, _type, _disabled, _props, shouldAddSpace, handleClick } =
  useButton(props, emit)

解构出的handleClick 是方法,绑定在@click上:@click="handleClick"

模板

  • tag默认为button(在button.ts中定义的buttonProps中)
  • _ref为ref<HTMLButtonElement>(),在use-button.ts中定义的useButton中
  • _props为useButton创建的实例解构出的属性,动态绑定到模板上
  • buttonKls为生成的符合 BEM 命名规则的类名,绑定到class上
  • buttonStyle为根据props生成的样式,绑定在style上
  • handleClick为解构出来的点击事件

template、el-icon、span 对应插槽。

<template>
  <component
    :is="tag"
    ref="_ref"
    v-bind="_props"
    :class="buttonKls"
    :style="buttonStyle"
    @click="handleClick"
  >
    <!-- 插槽-loading -->
    <template v-if="loading">
      <slot v-if="$slots.loading" name="loading" />
      <el-icon v-else :class="ns.is('loading')">
        <component :is="loadingIcon" />
      </el-icon>
    </template>
    <!-- 插槽-icon -->
    <el-icon v-else-if="icon || $slots.icon">
      <component :is="icon" v-if="icon" />
      <slot v-else name="icon" />
    </el-icon>
    <!-- 插槽-default -->
    <span
      v-if="$slots.default"
      :class="{ [ns.em('text', 'expand')]: shouldAddSpace }"
    >
      <slot />
    </span>
  </component>
</template>

使用到的hooks

路径:packages/hooks/

use-prop

路径:/use-prop

作用:传入一个name,返回实例的name属性。

获取当前Vue实例,返回一个计算属性,其值是:实例的某个属性。
vm.proxy 是当前 Vue 实例的代理对象,$props 是代理对象的属性集合,[name] 是指定的属性。

import { computed, getCurrentInstance } from 'vue'
import type { ComputedRef } from 'vue'

export const useProp = <T>(name: string): ComputedRef<T | undefined> => {
  // 获取当前Vue实例
  const vm = getCurrentInstance()
  // 返回当前实例的某个属性
  return computed(() => (vm?.proxy?.$props as any)?.[name])
}

useDeprecated

路径:use-deprecated

作用:显示已弃用的警告

// 显示已弃用的警告
export const useDeprecated = (
  { from, replacement, scope, version, ref, type = 'API' }: DeprecationParam,
  condition: MaybeRef<boolean>
) => {
  watch(
    () => unref(condition), // 如果condition是ref,就返回这个ref的内部值;否则返回它本身
    (val) => {
      if (val) {
        debugWarn(
          scope,
          `[${type}] ${from} is about to be deprecated in version ${version}, please use ${replacement} instead.
For more detail, please visit: ${ref}
`
        )
      }
    },
    {
      immediate: true,
      // 无论 condition 的初始值是什么,回调函数都会在创建侦听器时立即执行一次
    }
  )
}

如:在button中,当传入的type为text时,props.type === 'text'返回true,就会触发useDeprecated 中的watch(),告诉用户text要被弃用,建议用link替代。

useDeprecated(
  {
    from: 'type.text',
    replacement: 'link',
    version: '3.0.0',
    scope: 'props',
    ref: 'https://element-plus.org/en-US/component/button.html#button-attributes',
  },
  computed(() => props.type === 'text')
)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++面试宝典30题丨第一题:开灯

专栏导读 见得题目越多&#xff0c;考试时抽中的概率也越大。每一题都有详细的解答思路和独有的视频讲解。 本文收录于&#xff1a;C面试宝典&#xff08;送视频讲解&#xff09; ☆☆☆购买专栏后&#xff0c;请加微信会私发讲解视频&#xff01; 题目描述 一条名叫Mango的街…

图书管理系统(持久化存储数据以及增添新功能)

目录 一、数据库表设计 二、引入MyBatis 和MySQL 驱动依赖 三、配置数据库 & 日志 四、Model创建 五、枚举类 常量类用户登录 六、用户登录 七、添加图书 八、图书列表 九、修改图书 十、删除图书 十一、批量删除 十二、强制登录 十三、前端代码 &#xff0…

使用 HBuilder X 进行 uniapp 小程序开发遇到的问题合集

文章目录 背景介绍问题集锦1. 在 HBuilderX 点击浏览器运行时&#xff0c;报 uni-app vue3编译器下载失败 安装错误2.在 HBuilderX 点击微信小程序运行时&#xff0c;报 微信开发者工具打开项目失败&#xff0c;请参阅启动日志错误 背景介绍 HBuilder X 版本&#xff1a;HBui…

餐饮界的新传奇:沃可趣员工社区,让品牌关怀在指尖流淌

咖啡师与顾客发生肢体冲突、员工用咖啡粉泼顾客……某精品咖啡一天爆出两个大瓜&#xff01; 很快有网友指出咖啡店员工长期遭受重压&#xff0c;与品牌之间存在根本矛盾。 同样做餐饮的老牌快餐&#xff0c;门店密度与之不相上下&#xff0c;却很少发生这样的暴雷。 不仅因…

六.核心动画 - 特殊图层①

引言 本专栏到目前为止已经介绍了CALayer&#xff0c;了解了它的绘画和动画功能。但是Core Animation图层不仅仅能够用于图片和颜色&#xff0c;本篇博客就来介绍一下一些CALayer的子类特殊图层&#xff0c;来进一步扩展Core Animation的绘图能力。 特殊图层 Core Animation…

Vue实现金钱输入框组件自动带千位逗号

新建PriceInput.vue <template><div id"bord"><el-inputv-model"inputValue"v-bind"$attrs":maxlength"maxlength"input"handleInput"focus"handleFocus"blur"handleBlur"change"h…

自闭症儿童:探索症状背后的多彩内心世界

在星启帆自闭症康复中心&#xff0c;我们每天与一群独特而珍贵的孩子相遇——他们&#xff0c;是自闭症谱系障碍的患儿。自闭症&#xff0c;这一复杂的神经发育障碍&#xff0c;以其多样化的症状表现&#xff0c;为每个孩子的生活轨迹绘上了不同的色彩。 自闭症孩子的症状各异…

Websocket通信实战项目(js)(图片互传应用)(下)客户端H5+css+js实现

Rqtz : 个人主页 ​ 共享IT之美&#xff0c;共创机器未来 Sharing the Beauty of IT and Creating the Future of Machines Together 目录 起始 客户端GUI Javascripts连接websocket 使用localStorage保存用户输入的IP Websocket连接成功 Websocket接收数据 解析…

【Linux】正确的关机方法

1. Linux正确的关机方式 如何关机呢&#xff1f;我想&#xff0c;很多朋友在DOS年代已经有在玩计算机了。在当时我们关闭DOS的系统时&#xff0c;常常是直接关闭电源开关&#xff0c;而Windows 在你不爽的时候&#xff0c;按着电源开关四秒也可以关机&#xff0c;但是在Linux则…

旧衣回收小程序:减少资源浪费,提高回收效率

当下&#xff0c;旧衣服回收成为了大众热衷的事&#xff0c;不少居民都会把闲置的衣物进行回收&#xff0c;旧衣回收行业逐渐火爆。不过&#xff0c;传统的旧衣回收模式已经不符合当下时代发展&#xff0c;具有较大的不便利性。 因此&#xff0c;为解决这一问题&#xff0c;线…

PG实践|内置函数之GENERATE_SERIES之深入理解(二)

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注…

使用Vue CLI方式创建Vue3.0应用程序

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。新版本的 Vue CLI 的包名由原来的 vue-cli 改成了 vue/cli。 在开发大型项目时&#xff0c;需要考虑项目的组织结构、项目构建和部署等问题。如果手动完成这些配置工作&#xff0c;工作效率会非常低。为此&#xff0c;Vue.…

Rocky Linux 9 快速安装docker 教程

前述 CentOS 7系统将于2024年06月30日停止维护服务。CentOS官方不再提供CentOS 及后续版本&#xff0c;不再支持新的软件和补丁更新。CentOS用户现有业务随时面临宕机和安全风险&#xff0c;并无法确保及时恢复。由于 CentOS Stream 相对不稳定&#xff0c;刚好在寻找平替系统…

Python学生信息管理系统(完整代码)

引言&#xff1a;&#xff08;假装不是一个大学生课设&#xff09;在现代教育管理中&#xff0c;学生管理系统显得尤为重要。这种系统能够帮助教育机构有效地管理学生资料、成绩、出勤以及其他教育相关活动&#xff0c;从而提高管理效率并减少人为错误。通过使用Python&#xf…

IDEA版本推荐

推荐版本&#xff1a; IDEA 2024.1.4 下载链接&#xff1a;IDEA下载 &#xff08;下载时可以往下拖&#xff0c;选到自己想要的版本哦&#xff09; 本人由于项目开发需要&#xff0c;陆续用过几个版本的IDEA&#xff0c;包括&#xff1a; IDEA 2020.2.4 。这是在看韩顺平老师…

昇思25天学习打卡营第9天|CycleGAN图像风格迁移互换

文章目录 昇思MindSpore应用实践基于MindSpore的CycleGAN图像风格迁移互换1、CycleGAN 概述2、生成器部分3、判别器部分4、优化器和损失函数5、模型训练6、模型推理 Reference 昇思MindSpore应用实践 本系列文章主要用于记录昇思25天学习打卡营的学习心得。 基于MindSpore的C…

打造商贸物流“产-供-销”、“仓-运-配”全流程供应链

在当今全球化的商业环境中&#xff0c;商贸物流平台的搭建成为企业提升效率、降低成本并增强市场竞争力的关键因素。在现代商业环境中&#xff0c;商贸与物流之间的紧密协作是业务成功的关键因素。然而&#xff0c;许多组织面临着信息不对称、资源配套不足、以及系统间隔离等痛…

Windows的管理工具

任务计划程序&#xff1a;这是一个用来安排任务自动运行的工具。你可以在这里创建新的任务&#xff0c;设定触发条件&#xff0c;并指定任务的操作。 事件查看器&#xff1a;这是一套日志记录和分析工具&#xff0c;&#xff0c;你可以了解到系统的工作状况&#xff0c;帮助诊…

Spark大数据处理:技术、应用与性能优化(全)PDF书籍推荐分享

本书从一个系统化的视角&#xff0c;秉承大道至简的主导思想&#xff0c;介绍Spark中最值得关注的内 容&#xff0c;讲解Spark部署、开发实战&#xff0c;并结合Spark的运行机制及拓展&#xff0c;帮读者开启Spark技术之旅。 Spark大数据处理&#xff1a;技术、应用与性能优化…

阿里云邮件推送邮件发送失败的问题排查解决

阿里云邮件推送为何失败&#xff1f;解决邮件推送失败的步骤指南&#xff01; 即便是功能强大的阿里云邮件推送服务&#xff0c;也可能在实际使用中遇到邮件发送失败的问题。AokSend将详细介绍如何排查和解决阿里云邮件推送邮件发送失败的问题。 阿里云邮件推送&#xff1a;验…