vue2 element-ui组件二封-表单组件-按钮封装

这里是一段我们公司过往项目的代码(增删改查项目中的查询/重置按钮)

<el-button @click="query()" type="primary" size="mini">
  <i class="el-icon-search">查询</i>
</el-button>
<el-button @click="resetQueryForm" type="default" size="mini">
  <i class="el-icon-refresh-left">重置</i>
</el-button>

看一下这么写的几个弊端(当然代码时没问题的)

  1. type=primary/type=default 按钮的样式全局调整时非常不便
  2. size=mini每次都要写, 如果不是复制粘贴的话容易忘
  3. 查询重置按钮文字, 如查询的平替"检索/搜索", 每个项目要求不同, 全局调整也不方便
  4. 图标, el-button上有icon属性, 两者写法稍有差异(icon prop中间会有个默认空格, 例如上方没有手动空格的话, 图标和文字是在一起的)
  5. 图标更换不易, 全局替换可行性也不高(项目大了图标满处都在用)
  6. type=primary, size=mini这种字符串格式参数, 出了拼写错误很难静态排查

基于上述问题, 有以下几个组件(其实基本上都一样)

效果

用法

文字/图标/样式统一

特殊功能:

  1. 批量删除click事件触发前会自动二次确认
  2. import的click事件会带文件(示例代码全局仅支持Excel导入)
  3. 驳回会自动带审批意见(没封)
<ly-btn-search @click="todo"/>
<ly-btn-reset @click="todo"/>
<ly-btn-create @click="todo"/>
<ly-btn-remove @click="todo"/>
<ly-btn-export @click="todo"/>
<ly-btn-import @click="todo"/>

代码

mixin

所有按钮支持禁用和loading状态(虽然大部分按钮用不到)

export const FormButtonMixin = {
  props: {
    /**
     * 禁用状态
     */
    disabled: {
      type: [Boolean, Object, String, Number]
    },
    /**
     * 加载状态
     */
    loading: Boolean
  }
}

LyBtnSearch 检索

<template>
  <el-button
    :disabled="disabled"
    :loading="loading"
    icon="el-icon-search"
    size="small"
    type="primary"
    @click="$emit('click')"
  >
    <slot>检索</slot>
  </el-button>
</template>

<script>
import { FormButtonMixin } from './mixins/form-button-mixin'

export default {
  name: 'LyBtnSearch',
  mixins: [FormButtonMixin]
}
</script>

LyBtnReset 重置

<template>
  <el-button
    icon="el-icon-refresh-left"
    size="small"
    type="default"
    @click="$emit('click')"
  >
    <slot>重置</slot>
  </el-button>
</template>

<script>
import { FormButtonMixin } from './mixins/form-button-mixin'

export default {
  name: 'LyBtnReset',
  mixins: [FormButtonMixin]
}
</script>

LyBtnCreate 新增

<template>
  <el-button
    class="ly-form-button"
    :loading="loading"
    :disabled="disabled"
    icon="el-icon-plus"
    type="primary"
    size="small"
    @click="$emit('click')"
  >
    <slot>添加</slot>
  </el-button>
</template>

<script>

import { FormButtonMixin } from './mixins/form-button-mixin'

export default {
  name: 'LyBtnCreate',
  mixins: [FormButtonMixin]
}
</script>

LyBtnRemove (批量)删除

<template>
  <el-button
    class="ly-form-button"
    :loading="loading"
    :disabled="disabled"
    icon="el-icon-delete"
    type="danger"
    size="small"
    @click="handleClick"
  >
    <slot>批量删除</slot>
  </el-button>
</template>

<script>

import { FormButtonMixin } from './mixins/form-button-mixin'

export default {
  name: 'LyBtnRemove',
  mixins: [FormButtonMixin],
  props: {
    /**
     * 为true时, 删除操作不需要二次确认
     */
    unimportant: Boolean,
    /**
     * 提示内容示例:
     * ())=>`确认要删除${xxx}吗`
     */
    tip: {
      type: [String, Function],
      default: '确认删除选中内容吗?'
    }
  },
  methods: {
    handleClick() {
      if (this.unimportant) {
        return this.$emit('click')
      }
      let tip = this.tip
      if (typeof tip === 'function') {
        tip = tip()
      }
      this.$confirm(tip, '提示', { type: 'warning' }).then(_ => this.$emit('click'))
    }
  }
}
</script>

LyBtnImport 导入

<template>
  <el-button
    :disabled="disabled"
    :loading="loading"
    icon="el-icon-upload2"
    size="small"
    type="primary"
    @click="handleClick"
  >
    <input
      ref="fileRef"
      style="display: none"
      type="file"
      accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      @change="handleFileChange"
    >
    <slot>导入</slot>
  </el-button>
</template>

<script>
import { FormButtonMixin } from './mixins/form-button-mixin'

export default {
  name: 'LyBtnImport',
  mixins: [FormButtonMixin],
  methods: {
    /**
     * 文件变更
     * @param {Event} e
     */
    handleFileChange(e) {
      /**
       * @type {HTMLInputElement}
       */
      const target = e.target
      const file = target.files[target.files.length - 1]
      this.$emit('change', file)
    },
    handleClick() {
      this.$refs.fileRef.dispatchEvent(new MouseEvent('click'))
    }
  }
}
</script>

LyBtnExport 导出

<template>
  <el-button
    :disabled="disabled"
    :loading="loading"
    icon="el-icon-download"
    size="small"
    type="primary"
    @click="$emit('click')"
  >
    <slot>导出</slot>
  </el-button>
</template>

<script>
import { FormButtonMixin } from './mixins/form-button-mixin'

export default {
  name: 'LyBtnExport',
  mixins: [FormButtonMixin]
}
</script>

posted on 2023-01-09 11:14  凉云  阅读(220)  评论(0编辑  收藏  举报

导航