elementPlus-button组件二次封装

elementPlus-button组件二次封装

目录

  • 传递参数说明

    • 1.time

    • 2.type

    • 3.icon

  • 二次封装了什么

    • 属性透传

    • 预设类型

    • 预设映射

    • 节流约束

    • loading联动

  • 源代码

传递参数说明

  <el-button
    ref="buttonRef"
    v-bind="$attrs"
    :type="computedProps.type"
    :icon="computedProps.icon"
    :disabled="isDisabled"
    @click="handleClick"
  >
    <slot />
  </el-button>

只有两个值是外部传入,其余绑定的值由内部控制

1.time
  • 类型:Number
  • 默认值:1000(毫秒)
  • 用途:控制按钮点击的节流时间间隔
  • 使用示例:
    <t-button :time="2000" @click="handleClick" />  <!-- 2秒内只能点击一次 -->
    
2.type
  • 类型:ButtonType(字符串联合类型)
  • 可选值:
  • 预设业务类型:'add' | 'import'| 'export'| 'delete'
  • 基础类型:'default' |'primary' |'success' | 'warning' |'danger' | 'info'
  • 默认值:'default'
  • 用途:设置按钮的类型和样式
  • 使用示例:
      
      
      
    
3.icon
  • 类型:String
  • 默认值:‘’
  • 作用:设置按钮的图标
  • 说明:支持Element Plus 的所有图标名称
  • 示例:icon=“Edit”
    <t-button icon="search" /> 
    

二次封装了什么

属性透传

该绑定保留了elementPlus原生按钮的所有功能传参,自动透传未被声明的 props。

<el-button v-bind="$attrs" ...>
预设类型

这样我们在给组件传参的时候可以看到vscode展示的预设类型提示

在基础的类型上添加了业务类型

type ButtonType =
  | 'add'
  | 'import'
  | 'export'
  | 'delete'
  | 'default'
  | 'primary'
  | 'success'
  | 'warning'
  | 'danger'
  | 'info'
  
预设映射

将原有的if-else结构优化成map映射结构,减少代码冗余,提高开发效率

这样通过传入的业务类型就可以绑定type和icon,并且保留组件原有的icon传入设置

// 类型与图标映射
const TYPE_ICON_MAP = {
  add: { type: 'primary', icon: 'CirclePlus' },
  import: { type: 'default', icon: 'Upload' },
  export: { type: 'default', icon: 'Download' },
  delete: { type: 'danger', icon: 'Delete' }
} as const

// 根据 props.type 与 props.icon 计算出最终类型与图标
const computedProps = computed(() => {
  const fallback = { type: props.type, icon: props.icon || '' }
  const entry = TYPE_ICON_MAP[props.type] || fallback
  const icon = innerLoading.value ? 'Loading' : (TYPE_ICON_MAP[props.type] ? entry.icon : props.icon || '')
  return {
    type: entry.type,
    icon
  }
})

节流约束

通过接收的time来进行节流限制,并且在节流触发时会激活内置的loading状态,围绕这个loading状态来展开节流,之后将点击事件暴露给父组件并移除焦点

const handleClick = (event: MouseEvent) => {
  if (innerLoading.value) return
  if (props.time) {
    innerLoading.value = true
    setTimeout(() => {
      innerLoading.value = false
    }, props.time)
  }
  emits('click', event)
  buttonRef.value?.ref?.blur()
}

节流过程中会持续loading和disabled

const attrs = useAttrs()
const isDisabled = computed(() => {
  return innerLoading.value || attrs.disabled
})
loading联动

这里的loading是一种状态,采用内部定义,与disabled、节流函数和loading图标联动

在节流过程中自动触发loading状态,loading状态会将button设置成disabled状态并添加loading的icon图标。

const innerLoading = ref(false)

const computedProps = computed(() => {
  //省略
  const icon = innerLoading.value ? 'Loading' : (TYPE_ICON_MAP[props.type] ? entry.icon : props.icon || '')
  //省略
})

const buttonRef = ref<any>(null)

const handleClick = (event: MouseEvent) => {
  if (innerLoading.value) return
  if (props.time) {
    innerLoading.value = true //loading
    setTimeout(() => {
      innerLoading.value = false //loading
    }, props.time)
  }
  emits('click', event)
  buttonRef.value?.ref?.blur()
}

const attrs = useAttrs()
const isDisabled = computed(() => innerLoading.value || attrs.disabled)

源代码






你可能感兴趣的:(前端开发,前端,前端框架,javascript,vue.js)