|
|
<template>
|
|
|
<div class="icon-btn" @click="onClick" :style="btnStyle">
|
|
|
<i class="iconfont" :class="iconClass" :style="iconStyle"></i>
|
|
|
<span v-if="text" class="icon-btn-text" :style="textStyle">{{text}}</span>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { pxToRem } from '../../../utils/helpers.js';
|
|
|
|
|
|
const classMap = {
|
|
|
fav: {
|
|
|
default: 'icon-zan',
|
|
|
selected: 'icon-zan-fill'
|
|
|
},
|
|
|
star: {
|
|
|
default: 'icon-star',
|
|
|
selected: 'icon-star-fill'
|
|
|
},
|
|
|
share: {
|
|
|
default: 'icon-share'
|
|
|
},
|
|
|
msg: {
|
|
|
default: 'icon-msg'
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const defaultOption = {
|
|
|
canSelect: true, // 是否支持选中
|
|
|
selected: false, // 初始选中状态(不受是否支持选中控制)
|
|
|
color: '#444', // btn字体颜色
|
|
|
selectedColor: '#444', // btn选中状态字体颜色(不设置默认与非选中一致)
|
|
|
iconFontSize: 48, // icon字号(单位px)
|
|
|
textFontSize: 20, // text字号(单位px)
|
|
|
textAlign: 'top', // text位置, 默认normal(支持normal, top, bottom)
|
|
|
textZoom: 0.9, // text缩放
|
|
|
textAutoChange: false, // text自动增减,只支持number类型(受是否支持选中控制)
|
|
|
emitName: '' // 点击触发事件名称
|
|
|
};
|
|
|
|
|
|
export default {
|
|
|
name: 'WidgetIconBtn',
|
|
|
props: {
|
|
|
type: {
|
|
|
type: String,
|
|
|
default: 'fav'
|
|
|
},
|
|
|
text: String,
|
|
|
option: {
|
|
|
type: Object,
|
|
|
default() {
|
|
|
return defaultOption;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
btnSelected: false,
|
|
|
actionClass: ''
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
btnStyle() {
|
|
|
let color = this.option.color || defaultOption.color;
|
|
|
|
|
|
return `color: ${this.btnSelected ? (this.option.selectedColor || color) : color};`;
|
|
|
},
|
|
|
iconClass() {
|
|
|
if (this.actionClass) {
|
|
|
return this.actionClass;
|
|
|
}
|
|
|
|
|
|
if (!this.iconObj) {
|
|
|
this._icon = classMap[this.type] || classMap.fav;
|
|
|
}
|
|
|
|
|
|
if (this.option.selected) {
|
|
|
this.btnSelected = true;
|
|
|
|
|
|
return this._icon.selected || this._icon.default;
|
|
|
}
|
|
|
|
|
|
return this._icon.default;
|
|
|
},
|
|
|
iconStyle() {
|
|
|
return `font-size: ${pxToRem(this.option.iconFontSize || defaultOption.iconFontSize)};`;
|
|
|
},
|
|
|
textStyle() {
|
|
|
let style = `font-size: ${pxToRem(this.option.textFontSize || defaultOption.textFontSize)};`;
|
|
|
|
|
|
if (['top', 'bottom'].indexOf(this.option.textAlign) >= 0) {
|
|
|
style += ` vertical-align: ${this.option.textAlign};`;
|
|
|
}
|
|
|
|
|
|
if (Number(this.option.textZoom) !== NaN) {
|
|
|
style += `transform: scale(${this.option.textZoom}, ${this.option.textZoom});`
|
|
|
}
|
|
|
|
|
|
return style;
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
onClick(evt) {
|
|
|
if (this.option.canSelect) {
|
|
|
this.btnSelected = !this.btnSelected;
|
|
|
|
|
|
if (Number(this.text) !== NaN) {
|
|
|
this.text = Number(this.text) + (this.btnSelected ? 1 : -1);
|
|
|
}
|
|
|
|
|
|
if (this._icon.selected) {
|
|
|
this.actionClass = this.btnSelected ? this._icon.selected : this._icon.default;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this.option.emitName && this.$emit(this.option.emitName, evt);
|
|
|
}
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style type="css">
|
|
|
.icon-btn {
|
|
|
display: inline-block;
|
|
|
line-height: 1;
|
|
|
vertical-align: middle;
|
|
|
|
|
|
> * {
|
|
|
display: inline-block;
|
|
|
vertical-align: middle;
|
|
|
}
|
|
|
|
|
|
.icon-btn-text {
|
|
|
line-height: 1.3;
|
|
|
}
|
|
|
}
|
|
|
</style> |
...
|
...
|
|