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效果: