基于el-button的RibbonControl

2021-11-24 13:10:45 浏览数 (1)

1、前言

  最近需要对一个包含各种操作的系统进行样式重构。鉴于操作按钮较多,且几年前在上家公司时候有做财务类型软件,当时是参照office使用了ribbon风格,只不过是C/S的,效果相当不错。这次面对同样类型的任务,自然想到也使用ribbon风格来重构系统的各个功能布局。但查了下,目前市面上基本没开源的前端ribbon组件,所以决定自己基于element-ui的el-button魔改制作ribboncontrol,这里把探索的过程做下简单记录。

2、准备

  安装node、Vue CLI。

3、实践

(1)vue create ribbon-example 创建实验项目

(2)打开项目,npm install elemetn-ui安装element-ui前端框架

(3)入口文件main.js中引入element-ui

代码语言:javascript复制
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

(4)GitHub上找到element-ui中el-button的组件源码,复制到项目中/src/components/RibbonButton.vue文件中,并做相应改动:

其中红色部分是针对el-button原始组件做的改动。

代码语言:javascript复制
<template>
  <button
    class="el-button"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[
      type ? 'el-button--'   type : '',
      buttonSize ? 'el-button--'   buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"
    @click="handleClick"
  >
    <span>
      <i v-if="loading" class="el-icon-loading" />
      <i v-if="icon && !loading" :class="icon" />
      <span v-if="$slots.default" class="icon-name"><slot /></span>
    </span>
  </button>
</template>
<script>
export default {
  name: 'RibbonButton',

  inject: {
    elForm: {
      default: ''
    },
    elFormItem: {
      default: ''
    }
  },

  props: {
    type: {
      type: String,
      default: 'default'
    },
    // eslint-disable-next-line vue/require-default-prop
    size: String,
    icon: {
      type: String,
      default: ''
    },
    nativeType: {
      type: String,
      default: 'button'
    },
    loading: Boolean,
    disabled: Boolean,
    plain: Boolean,
    autofocus: Boolean,
    round: Boolean,
    circle: Boolean
  },

  computed: {
    _elFormItemSize() {
      return (this.elFormItem || {}).elFormItemSize
    },
    buttonSize() {
      return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size
    },
    buttonDisabled() {
      return this.disabled || (this.elForm || {}).disabled
    }
  },

  methods: {
    handleClick(evt) {
      this.$emit('click', evt)
    }
  }
}
</script>
<style scoped>
.el-button {
  vertical-align: middle;
  min-width: 70px;
  padding: 5px 5px;
}

.el-button span {
    display: inline-block;
}

.el-button i {
    display: block;
    font-size: 32px;
    margin-bottom: 10px;
    transition: color .15s linear;
}

.el-button .icon-name{
    display: inline-block;
    font-size: 16px;
}
</style>

(5)打开HelloWorld.vue,以该文件作为场景测试,如下:

代码语言:javascript复制
<template>
  <div class="button-group">
    <ribbon-button type="primary" icon="el-icon-search">button1</ribbon-button>
    <ribbon-button type="primary" icon="el-icon-search">button2</ribbon-button>
    <div class="vertical-group">
      <el-button type="primary" icon="el-icon-search">button3</el-button>
      <el-button type="primary" icon="el-icon-search">button4</el-button>
    </div>
    <ribbon-button type="primary" icon="el-icon-search">button5</ribbon-button>
    <ribbon-button type="primary" icon="el-icon-search">button6</ribbon-button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.button-group {
  display: inline-block;
  height: 100%;
  white-space: nowrap;
  font-size: 0;
}

.button-group .vertical-group {
  display: inline-flex;
  height: 70px;
  flex-direction: column;
  vertical-align: middle;
  justify-content: space-between;
}

.button-group .vertical-group button {
  padding: 8px 5px;
  height: 34.5px;
}

.button-group button {
  margin: 0 1px 0 0;
}
</style> 

其中用到了flex布局,因为flex布局要方便的多。

(6)npm run serve运行测试样例,最终实现的ribbon效果:

0 人点赞