[ Element plus源码笔记三(button组件2) | 青训营笔记]

252 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 六 天

一、模板内容简介

首先是源码展示

<template>
  <button
    ref="_ref"
    :class="[
      ns.b(),
      ns.m(_type),
      ns.m(_size),
      ns.is('disabled', _disabled),
      ns.is('loading', loading),
      ns.is('plain', plain),
      ns.is('round', round),
      ns.is('circle', circle),
      ns.is('text', text),
      ns.is('link', link),
      ns.is('has-bg', bg),
    ]"
    :aria-disabled="_disabled || loading"
    :disabled="_disabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :style="buttonStyle"
    @click="handleClick"
  >
    <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>
    <el-icon v-else-if="icon || $slots.icon">
      <component :is="icon" v-if="icon" />
      <slot v-else name="icon" />
    </el-icon>
    <span
      v-if="$slots.default"
      :class="{ [ns.em('text', 'expand')]: shouldAddSpace }"
    >
      <slot />
    </span>
  </button>
</template>

1.此部分是决定loading的样式是否要展示,这边还有一个插槽,也用v-if做了一个处理。同时,使用了来充当loading样式的icon,icon种类(element-plus.gitee.io/zh-CN/compo… 。下面<component :is="loadingIcon" />的is主要是用来决定是成为什么组件

<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>

2.像是诸如:style=后面的这些属性,都是在button.ts(packages\components\button\src\button.ts)里面有做定义,这边就要提到一个ts非常好用的一个api。可以使用例如“@description disable the button” /**

  • @description disable the button */ disabled: Boolean,可以这样去使用。效果就是在调用这个disabled的时候,当鼠标悬停在对应组件内disabled属性上面时就会对应显示出你设定好的介绍,极大程度提高了代码的可读性

二、逻辑内容简介

1.源码展示 在代码逻辑区主要是命名空间,见我上一篇文章。再来是defineOptions这个部分,他主要是定义这个组件的名字等信息,官方文档(vue-macros.sxzz.moe/macros/defi… 但文档内容不是很多,主要是可以在setup下使用defineOptions声明Option API。可以用来设置props,emit,name等等。下面的defineExpose()可以暴露组件的属性,方法等等,可以用于组件传值,父组件可以非常直接的获取子组件的属性和方法

<script lang="ts" setup>
import { ElIcon } from '@element-plus/components/icon'
import { useNamespace } from '@element-plus/hooks'
import { useButton } from './use-button'
import { buttonEmits, buttonProps } from './button'
import { useButtonCustomStyle } from './button-custom'

defineOptions({
  name: 'ElButton',
})

const props = defineProps(buttonProps)
const emit = defineEmits(buttonEmits)

const buttonStyle = useButtonCustomStyle(props)
const ns = useNamespace('button')
const { _ref, _size, _type, _disabled, shouldAddSpace, handleClick } =
  useButton(props, emit)

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,
})
</script>