基于el-button的RibbonControl
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
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原始组件做的改动。
<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,以该文件作为场景测试,如下:
<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效果: