You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

706 lines
19 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="tm-button " :class="[block ? 'd-block' : 'd-inline-block ']" hover-class="opacity-6">
<view
class="flex-center tm-button-btn fulled-height"
:class="[block ? '' : customDense_puted ? '' : 'ma-10', block ? 'd-block' : 'd-inline-block', black_tmeme ? 'bk' : '', customStyleTm]"
>
<!-- @getuserinfo="getuserinfo" -->
<button
@contact="contact"
@error="error"
@getphonenumber="getphonenumber"
@launchapp="launchapp"
@opensetting="opensetting"
@click="onclick"
@longpress="$emit('longpress', $event)"
@touchcancel="$emit('touchcancel', $event)"
@touchend="$emit('touchend', $event)"
@touchstart="$emit('touchstart', $event)"
:disabled="disabled"
:loading="loading"
:open-type="openType"
:hover-start-time="hoverStartTime"
:hover-stay-time="hoverStaySime"
:hover-stop-propagation="hoverStopPropagation"
:send-message-img="sendMessageImg"
:send-message-path="sendMessagePath"
:send-message-title="sendMessageTitle"
:show-message-card="showMessageCard"
:class="[
showValue ? 'showValue' : '',
titl ? 'text-' + color_tmeme : '',
vertical ? 'flex-col flex-center' : 'flex-center',
black_tmeme ? 'bk' : '',
disabled ? color_tmeme + ' grey-lighten-2' : color_tmeme,
block ? '' : sizes,
text || titl ? '' : bgcolor ? 'shadow-' + shadow : 'shadow-' + shadowthemeName + '-' + shadow,
flat ? 'flat' : '',
text ? 'text ' : '',
plan ? 'plan outlined' : '',
titl ? 'titl' : '',
fab?'rounded':'round-' + round,
customClassTm_puted
]"
:style="{
background: bgcolor ? bgcolor + ' !important' : 'default',
width: widths != 0 && widths != 'inherit' ? widths : 'inherit',
height: heights,
lineHeight: 'inherit'
}"
>
<slot name="icon" :data="{ icon: icon, size: icon_size.upx, fab: fab }">
<block v-if="vtype == true">
<text
v-if="!fab && icon"
:class="[`${prefx_computed} ${icon}`, fontColor ? `text-${colors.color}` : '', black_tmeme ? 'opacity-6' : '', 'px-12','flex-shrink']"
:style="{
fontSize: `${icon_size.px}px`,
lineHeight:'normal'
}"
></text>
<text
v-if="fab && icon && !loading && !titl"
:class="[`${prefx_computed} ${icon}`, fontColor ? `text-${colors.color}` : '', black_tmeme ? 'opacity-6' : '','flex-shrink']"
:style="{
fontSize: `${icon_size.px}px`,
lineHeight:'normal'
}"
></text>
<text
v-if="fab && icon && !loading && titl"
:class="[`${prefx_computed} ${icon}`, fontColor ? `text-${color_tmeme}` : '', black_tmeme ? 'opacity-6' : '','flex-shrink']"
:style="{
fontSize: `${icon_size.px}px`,
lineHeight:'normal'
}"
></text>
</block>
<block v-if="vtype == false"><tm-icons :size="icon_size.upx" :name="icon"></tm-icons></block>
</slot>
<view v-if="!fab || showValue" class="d-inline-block tm-button-label flex-shrink" :style="{ fontSize: font_size }" :class="[fontColor ? `text-${colors.color}` : '',vertical ? 'full ' : '',]">
<slot name="default" :data="label">{{ label }}</slot>
</view>
</button>
</view>
</view>
</template>
<script>
/**
* 按钮
* @description 注意,按钮功能同原生按钮功能,所有属性都有。
* @property {Function} contact
* @property {Function} error
* @property {Function} getphonenumber
* @property {Function} getuserinfo
* @property {Function} opensetting
* @property {Function} click
* @property {Boolean} disabled = [true|false] 是否禁用
* @property {Boolean} loading = [true|false] 是否加载中
* @property {String} open-type = [contact|getPhoneNumber|getUserInfo|launchapp|share|openSetting] 同原生btn相同,//当等于getUserProfile时自动获取微信授权。
* @property {Boolean} block = [true|false] 是否独占一行
* @property {Boolean} show-value = [true|false] fab模式是隐藏文字的。如果这个设置为true,不管在什么情况下都会显示文字。
* @property {String} url = [] 默认"",如果提供将会跳转连接。
* @property {String} size = [xs|s|m|n|l|g] 默认"n",按钮尺寸大小。
* @property {Number|String} font-size = [] 默认 0,自定义文字大小默认使用主题size的大小。
* @property {Number|String} icon-size = [] upx单位默认 0,自定义图标大小默认使用主题size的大小。
* @property {String} icon = [] 单位默认 "",自定义按钮图标。
* @property {String} item-class = [] 默认 "",按钮自定样式类。
* @property {String|Number} shadow = [] 默认 5,按钮投影
* @property {String} font-color = [] 默认主题颜色,自定文字颜色
* @property {String} bgcolor = [] 默认主题颜色,自定义-背景颜色
* @property {String} theme = [] 默认 primary,主题颜色
* @property {Boolean|String} black = [true|false] 默认 false, 暗黑模式
* @property {Boolean|String} flat = [true|false] 默认 false, 去除所有投影圆角效果,扁平模式。
* @property {Boolean|String} text = [true|false] 默认 false, 文本模式。背景减淡。文字使用主题色。
* @property {Boolean|String} plan = [true|false] 默认 false, 镂空。
* @property {Boolean|String} fab = [true|false] 默认 false, 圆模式。
* @property {Boolean|String} dense = [true|false] 默认 false, 是否去除外间隙。
* @property {Boolean|String} titl = [true|false] 默认 false, 无背景,无边框,只保留按钮区域和文字颜色或者图标颜色。
* @property {String} label = [] 默认 "", 按钮文字也可以使用插槽模式直接写在组件内部。
* @property {String|Number} width = [] 默认 "", 按钮宽, 单位px ,可以是百分比 如果不设置block为true时此项设置无效。
* @property {String|Number} height = [] 默认 "", 按钮高, 单位px ,可以是百分比如果不设置block为true时此项设置无效。
* @property {String|Number} round = [] 默认 2, 圆角
* @property {String|Number} navtie-type = [form] 默认 :'', 可选值form提供此属性为form时事件会被表单接替会触发表单提交事件。
* @property {String} userProfileError = ['auto'] 默认:'auto' 仅open-type='getUserProfile'时有效当微信授权失败提示的信息默认为auto,如果非auto将显示自定义错误提示。如果为'',将不显示错误提示。
* @example <tm-button>确定</tm-button>
*/
import tmIcons from '@/tm-vuetify/components/tm-icons/tm-icons.vue';
export default {
components: { tmIcons },
name: 'tm-button',
props: {
hoverStartTime:20,
hoverStaySime:70,
appParameter:String,
hoverStopPropagation:{
type:Boolean,
default:false
},
sessionFrom:String,
sendMessageTitle:String,
sendMessagePath:String,
sendMessageImg:String,
showMessageCard:String,
navtieType: {
type: String,
default: '' //form
},
// 内联还是独占一行的块状100%,默认内联样式。
block: {
type: String | Boolean,
default: false
},
// fab模式是隐藏文字的。如果这个设置为true,不管在什么情况下都会显示文字。
showValue: {
type: String | Boolean,
default: false
},
disabled: {
type: String | Boolean,
default: false
},
loading: {
type: String | Boolean,
default: false
},
url: {
type: String,
default: ''
},
// xs,s,n,l,g
size: {
type: String,
default: 'n'
},
// 文字大小。
fontSize: {
type: Number | String,
default: 0
},
// 图标大小。
iconSize: {
type: Number | String,
default: 0
},
// icon-cog-fill
icon: {
type: String,
default: ''
},
// 按钮自定样式类。
itemClass: {
type: String,
default: ''
},
// 同原生btn相同。contact|getPhoneNumber|getUserInfo|launchapp|share|openSetting
//当等于getUserProfile时自动获取微信授权。
openType: {
type: String,
default: ''
},
shadow: {
type: Number | String,
default: 4
},
vertical: {
type: Boolean | String,
default: false
},
// 自定义-文字颜色。
fontColor: {
type: String,
default: ''
},
// 自定义-背景颜色
bgcolor: {
type: String | Array,
default: ''
},
// 主题颜色
theme: {
type: String,
default: 'primary'
},
//优先级最高: 优先级1
black: {
type: Boolean | String,
default: null
},
// 优先级高优先级2
flat: {
type: Boolean | String,
default: null
},
// 优先级高:文本模式。背景减淡。文字使用主题色。
text: {
type: Boolean | String,
default: false
},
// 优先级高:镂空。
plan: {
type: Boolean | String,
default: false
},
// 圆模式。
fab: {
type: Boolean | String,
default: false
},
// 无背景,无边框,只保留按钮区域和文字颜色或者图标颜色。
titl: {
type: Boolean | String,
default: false
},
label: {
type: String,
default: ''
},
// 如果不设置block为true时此项设置无效。
width: {
type: String | Number,
default: NaN
},
// 如果不设置block为true时此项设置无效。
height: {
type: String | Number,
default: NaN
},
// 圆角
round: {
type: String | Number,
default: 3
},
dense: {
type: Boolean | String,
default: false
},
// 跟随主题色的改变而改变。
fllowTheme: {
type: Boolean | String,
default: true
},
//当微信授权失败提示的信息默认为auto,如果非auto将显示自定义错误提示。如果为'',将不显示错误提示。
userProfileError:{
type:String,
default:'auto'
}
},
created() {
this.customClassTm_puted = this.itemClass;
this.customDense_puted = this.dense;
this.color_tmeme = this.theme;
},
watch: {
theme: function() {
this.color_tmeme = this.theme;
}
},
computed: {
prefx_computed() {
let prefix = this.icon.split('-')[0];
if (prefix == 'icon') return 'iconfont';
if (prefix == 'mdi') return 'mdi';
return prefix;
},
customDense_puted: {
get: function() {
return this.customDense;
},
set: function(val) {
this.customDense = val;
}
},
customClassTm_puted: {
get: function() {
return this.customClassTm;
},
set: function(val) {
this.customClassTm = val;
}
},
vtype: function() {
if (this.icon[0] == '.' || this.icon[0] == '/' || this.icon.substring(0, 4) == 'http' || this.icon.substring(0, 5) == 'https' || this.icon.substring(0, 3) == 'ftp') {
return false;
}
return true;
},
black_tmeme: function() {
if (this.black !== null) return this.black;
return this.$tm.vx.state().tmVuetify.black;
},
color_tmeme: {
get: function() {
if (this.$tm.vx.state().tmVuetify.color !== null && this.$tm.vx.state().tmVuetify.color && this.fllowTheme) {
return this.$tm.vx.state().tmVuetify.color;
}
return this.color_tmeme_computed;
},
set: function(val) {
this.color_tmeme_computed = val;
}
},
// 投影的颜色名字。
shadowthemeName: function() {
if (!this.theme) return 'none';
return this.color_tmeme;
},
widths: {
get: function() {
let w;
if (typeof this.width === 'undefined') {
return 'auto';
}
let item = this.$TestUnit(this.width);
if (item) {
if (item.type == 'string') {
w = item.value;
}
if (item.type == 'number') {
w = item.value + 'px';
}
}
return w;
}
},
heights: {
get: function() {
let item = this.$TestUnit(this.height);
if (item) {
if (item.type == 'string') {
return item.value;
}
if (item.type == 'number') {
return item.value + 'px';
}
}
return 'auto';
}
},
sizes: function() {
if (!isNaN(this.width) || !isNaN(this.height)) return;
if (this.size == 'xs') {
return this.fab ? 'fabxs text-size-xs rounded' : 'wxs round-1 text-size-xs';
} else if (this.size == 's') {
return this.fab ? 'fabs text-size-xs rounded' : 'ws round-1 text-size-s';
} else if (this.size == 'm') {
return this.fab ? 'fabm text-size-xs rounded' : 'wm round-1 text-size-n';
} else if (this.size == 'n') {
return this.fab ? 'fabn text-size-xs rounded' : 'wn round-1 text-size-n';
} else if (this.size == 'l') {
return this.fab ? 'fabl text-size-xs rounded' : 'wl round-2 text-size-g';
} else if (this.size == 'g') {
return this.fab ? 'fabg text-size-xs rounded' : 'wg round-3 text-size-g';
}
},
font_size: function() {
if (this.fontSize > 0) {
return this.fontSize + 'rpx';
}
if (this.size == 'xs') {
return uni.upx2px(20) + 'px';
} else if (this.size == 's') {
return uni.upx2px(22) + 'px';
} else if (this.size == 'm') {
return uni.upx2px(24) + 'px';
} else if (this.size == 'n') {
return uni.upx2px(28) + 'px';
} else if (this.size == 'l') {
return uni.upx2px(32) + 'px';
} else if (this.size == 'g') {
return uni.upx2px(36) + 'px';
}
},
icon_size: function() {
if (this.iconSize) {
return { px: uni.upx2px(this.iconSize), upx: this.iconSize };
}
if (this.size == 'xs') {
return { px: uni.upx2px(20), upx: 20 };
} else if (this.size == 's') {
return { px: uni.upx2px(22), upx: 22 };
} else if (this.size == 'm') {
return { px: uni.upx2px(24), upx: 24 };
} else if (this.size == 'n') {
return { px: uni.upx2px(28), upx: 28 };
} else if (this.size == 'l') {
return { px: uni.upx2px(32), upx: 32 };
} else if (this.size == 'g') {
return { px: uni.upx2px(36), upx: 36 };
}
},
defaultfontsize: function() {
if (this.iconSize) {
return this.iconSize;
}
if (this.size == 'xs') {
return uni.upx2px(20);
} else if (this.size == 's') {
return uni.upx2px(22);
} else if (this.size == 'm') {
return uni.upx2px(24);
} else if (this.size == 'n') {
return uni.upx2px(28);
} else if (this.size == 'l') {
return uni.upx2px(32);
} else if (this.size == 'g') {
return uni.upx2px(36);
}
},
colors: function() {
let color = this.$TestColor(this.fontColor);
return color;
}
},
data() {
return {
customClassTm: '',
customDense: false,
customStyleTm: '',
color_tmeme_computed: ''
};
},
methods: {
setConfigStyle(val) {
this.customStyleTm = val;
},
onclick() {
let t = this;
this.$emit('click', ...arguments);
if(this.openType=='getUserInfo' || this.openType == 'getUserProfile'){
// #ifdef MP-WEIXIN
uni.getUserProfile({
desc: '需要获取用户信息',
lang: 'zh',
complete: function (userProfile) {
if(userProfile.errMsg !='getUserProfile:ok'){
if(t.userProfileError==''||t.userProfileError=='true') return;
if(t.userProfileError!='auto'){
uni.showToast({
title:t.userProfileError,icon:'error',mask:true
})
return;
}
uni.showToast({
title:userProfile.errMsg,icon:'error',mask:true
})
return;
}
t.$emit('getUserInfo', userProfile);
t.$emit('getUserProfile', userProfile);
},
fail: (error) => {
if(t.userProfileError==''||t.userProfileError=='true') return;
if(t.userProfileError!='auto'){
uni.showToast({
title:t.userProfileError,icon:'error',mask:true
})
return;
}
uni.showToast({
title:error
})
}
});
// #endif
}
if (this.url !== '' && typeof this.url === 'string') {
let url = this.url;
if (url[0] !== '/') url = '/' + url;
uni.navigateTo({
url: url
});
}
},
contact() {
this.$emit('contact', ...arguments);
},
error() {
this.$emit('error', ...arguments);
},
getphonenumber() {
this.$emit('getphonenumber', ...arguments);
},
getuserinfo() {
this.$emit('getuserinfo', ...arguments);
},
launchapp() {
this.$emit('launchapp', ...arguments);
},
opensetting() {
this.$emit('opensetting', ...arguments);
}
}
};
</script>
<style lang="scss" scoped>
.tm-button {
vertical-align: middle;
.tm-button-btn button {
background: none;
border: none;
width: 100%;
height: auto;
line-height: 88upx;
height: 88upx;
vertical-align: middle;
// #ifdef H5
transition: all 0.3s;
// #endif
.tm-button-label {
vertical-align: middle;
}
&::after {
border: none;
}
&.fabxs {
width: 48upx;
height: 48upx !important;
line-height: 48upx;
text-align: center;
padding: 0 !important;
}
&.fabs {
width: 64upx;
height: 64upx !important;
line-height: 64upx;
text-align: center;
padding: 0 !important;
}
&.fabm {
width: 90upx;
height: 90upx !important;
line-height: 90upx;
text-align: center;
padding: 0 !important;
}
&.fabn {
width: 110upx;
height: 110upx !important;
line-height: 110upx;
text-align: center;
padding: 0 !important;
}
&.fabl {
width: 140upx;
height: 140upx !important;
line-height: 140upx;
text-align: center;
padding: 0 !important;
}
&.fabg {
width: 180upx;
height: 180upx !important;
line-height: 180upx;
text-align: center;
padding: 0 !important;
}
&.wxs {
min-width: 64upx;
height: 36upx !important;
// line-height: 24upx;
text-align: center;
// padding: 0 !important;
padding: 0 12upx;
}
&.ws {
min-width: 90upx;
height: 48upx !important;
// line-height: 24upx;
text-align: center;
padding: 0 16upx;
}
&.wm {
min-width: 140upx;
height: 64upx !important;
// line-height: 88upx;
text-align: center;
padding: 0 24upx;
}
&.wn {
min-width: 240upx;
height: 72upx !important;
// line-height: 88upx;
text-align: center;
// padding: 0 !important;
padding: 0 32upx;
}
&.wl {
min-width: 280upx;
height: 72upx !important;
// line-height: 88upx;
text-align: center;
padding: 0 32upx;
}
&.wg {
min-width: 400upx;
height: 76upx !important;
// line-height: 88upx;
text-align: center;
padding: 0 32upx;
}
&.plan {
box-shadow: none !important;
// background: transparent !important;
border-width: 1px !important;
border-style: solid;
}
&.titl {
box-shadow: none !important;
background: transparent !important;
border: none;
}
&:active,
&:focus {
opacity: 0.64;
}
&.showValue {
line-height: inherit !important;
padding: 0 !important;
}
&.noGutter {
min-width: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: unset !important;
}
}
&.d-block {
button {
// padding: 30upx 0;
font-size: 32upx;
&.plan {
box-shadow: none !important;
background: transparent !important;
border-width: 1px !important;
border-style: solid;
}
}
&.showValue {
line-height: inherit !important;
}
}
&.d-inline-block {
vertical-align: middle;
}
}
</style>