290 lines
8.1 KiB
Vue
290 lines
8.1 KiB
Vue
<template>
|
|
<view
|
|
@click="OnClick"
|
|
class="tmSheet"
|
|
@touchstart="touchStart"
|
|
@touchcancel="touchEnd"
|
|
@touchend="touchEnd"
|
|
@mousedown="touchStart"
|
|
@mouseup="touchEnd"
|
|
@mouseleave="touchEnd"
|
|
:style="[
|
|
{
|
|
width: _width,
|
|
height: _height,
|
|
},
|
|
buttonStyle,
|
|
]"
|
|
>
|
|
<!-- @slot 默认插槽 -->
|
|
<slot></slot>
|
|
<view
|
|
v-if="_attrs.loading"
|
|
class="tmSheetLoading"
|
|
:style="{ borderRadius: buttonStyle.borderRadius }"
|
|
>
|
|
<tm-icon name="loader-line" size="50" spin color="primary"></tm-icon>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed, ref } from "vue";
|
|
import { arrayNumberValid, arrayNumberValidByStyleMP, arrayNumberValidByStyleBorderColor, arrayNumberValidByStyleBorderStyle, covetUniNumber, linearValid } from "../../libs/tool";
|
|
import { useTmConfig } from "../../libs/config";
|
|
import { getDefaultColor, getDefaultColorObj, getOutlineColorObj, getTextColorObj, getThinColorObj } from "../../libs/colors";
|
|
|
|
/**
|
|
* @displayName 容器
|
|
* @exportName tm-sheet
|
|
* @category 常用组件
|
|
* @description 像一张纸张一样,用于包裹内容区域,可塑性高,可以快速用来布局.
|
|
* @constant 平台兼容
|
|
* | H5 | uniAPP | 小程序 | version |
|
|
| --- | --- | --- | --- |
|
|
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
|
|
*/
|
|
defineOptions({ name: 'TmSheet' });
|
|
|
|
const { config } = useTmConfig()
|
|
const emits = defineEmits([
|
|
/**
|
|
* 点击事件
|
|
* @property {MouseEvent} evt 事件参数
|
|
* */
|
|
'click',
|
|
])
|
|
type PropsKeyType = keyof typeof attrs;
|
|
const attrs = defineProps({
|
|
/**
|
|
* 遵循规则:
|
|
* string或者[x]:全部边线
|
|
* [x,x]左右边线,上下边线
|
|
* [x,x,x] 左,上,右
|
|
* [x,x,x,x] 左,上,右,下
|
|
*/
|
|
borderColor: {
|
|
type: [String, Array<string>],
|
|
default: ""
|
|
},
|
|
darkBorderColor: {
|
|
type: [String, Array<string>],
|
|
default: "transparent"
|
|
},
|
|
/** 规则同borderColor */
|
|
borderWidth: {
|
|
type: [String, Number, Array<string | number>],
|
|
default: 0
|
|
},
|
|
/** 规则同borderColor */
|
|
borderStyle: {
|
|
type: [String, Array<string>],
|
|
default: "solid"
|
|
},
|
|
/** 规则同borderColor
|
|
* 左上,右上,右下,左下
|
|
*/
|
|
round: {
|
|
type: [String, Number, Array<string | number>],
|
|
default: ''
|
|
},
|
|
/**
|
|
* 遵循规则:填写0关闭,填写空值取全局
|
|
* string,number,或者[x]:全部
|
|
* [x,x]左右,上下
|
|
* [x,x,x] 左,上,右
|
|
* [x,x,x,x] 左,上,右,下
|
|
*/
|
|
margin: {
|
|
type: [String, Number, Array<string | number>],
|
|
default: ''
|
|
},
|
|
/**
|
|
* 遵循规则:填写0关闭,填写空值取全局
|
|
* string,number,或者[x]:全部
|
|
* [x,x]左右,上下
|
|
* [x,x,x] 左,上,右
|
|
* [x,x,x,x] 左,上,右,下
|
|
*/
|
|
padding: {
|
|
type: [String, Number, Array<string | number>],
|
|
default: ''
|
|
},
|
|
width: {
|
|
type: [String, Number],
|
|
default: ""
|
|
},
|
|
height: {
|
|
type: [String, Number],
|
|
default: ""
|
|
},
|
|
|
|
loading: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 是否跟随主题背景色
|
|
* 下方的color失效
|
|
*/
|
|
flowTheme: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/**
|
|
* 背景主题
|
|
*/
|
|
color: {
|
|
type: String,
|
|
default: "white"
|
|
},
|
|
/**
|
|
* 自定义暗黑背景
|
|
* 空值时取全局配置
|
|
*/
|
|
darkBgColor: {
|
|
type: String,
|
|
default: ""
|
|
},
|
|
/** 渐变,前面的color,bgColor,darkBgColor失效 */
|
|
linear: {
|
|
type: [Array<string>],
|
|
default: () => [],
|
|
validator: (val: string[]) => {
|
|
if (val.length == 0) return true;
|
|
let pass = val.length == 3;
|
|
if (!pass) {
|
|
console.error("tmui提醒:linear 参数格式错误,请检查,必须长度为3");
|
|
}
|
|
return pass
|
|
}
|
|
},
|
|
/**
|
|
* 数字或者字符串时自动计算投影,它会投影大小
|
|
* 数组时(必须为4),第一个x,第二为y,第三个为大小 ,第四个为投影颜色
|
|
* 空字符串时,取全局配置,如果不想投影设置为none即可.
|
|
*/
|
|
shadow: {
|
|
type: [String, Number, Array<string>],
|
|
default: '',
|
|
validator: (val: string | number | string[]) => {
|
|
if (Array.isArray(val)) {
|
|
if (val.length != 4) {
|
|
console.error("tmui提醒:shadow 第一个x,第二为y,第三个为大小 ,第四个为投影颜色");
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
})
|
|
const _attrs = computed(() => attrs);
|
|
const OnClick = (evt: MouseEvent) => {
|
|
if (_attrs.value.loading) return;
|
|
emits('click', evt)
|
|
}
|
|
const _width = computed(() => {
|
|
return covetUniNumber(attrs.width || 'auto')
|
|
})
|
|
const _height = computed(() => covetUniNumber(attrs.height || 'auto'))
|
|
|
|
const isHover = ref(false);
|
|
const touchStart = () => {
|
|
isHover.value = true;
|
|
}
|
|
const touchEnd = () => {
|
|
isHover.value = false;
|
|
}
|
|
|
|
const buttonStyle = computed(() => {
|
|
let style = {
|
|
borderColor: ``,
|
|
borderWidth: ``,
|
|
borderStyle: ``,
|
|
background: ``,
|
|
color: ``,
|
|
borderRadius: ``,
|
|
boxShadow: `none`,
|
|
margin: '0px',
|
|
padding: '0px'
|
|
}
|
|
let isDark = config.mode == 'dark';
|
|
|
|
let background = attrs.color
|
|
let borderColor = arrayNumberValidByStyleBorderColor(attrs.borderColor)
|
|
let borderWidth = arrayNumberValidByStyleMP(attrs.borderWidth)
|
|
let borderStyle = arrayNumberValidByStyleBorderStyle(attrs.borderStyle)
|
|
let borderRadius = arrayNumberValidByStyleMP(attrs.round || config.sheetRadius)
|
|
let margin = arrayNumberValidByStyleMP(attrs.margin === '' ? config.sheetMargin : attrs.margin)
|
|
let padding = arrayNumberValidByStyleMP(attrs.padding === '' ? config.sheetPadding : attrs.padding)
|
|
let linear = linearValid(attrs.linear)
|
|
|
|
if (attrs.flowTheme) {
|
|
background = config.color
|
|
}
|
|
if (isDark) {
|
|
background = attrs.darkBgColor || config.sheetDarkColor
|
|
}
|
|
|
|
let shadow = 'none'
|
|
if (Array.isArray(attrs.shadow)) {
|
|
shadow = attrs.shadow.join(' ')
|
|
} else if (attrs.shadow !== '' && attrs.shadow != 'none') {
|
|
let obj = getDefaultColorObj(attrs.color, attrs.color)
|
|
shadow = `0px 0px ${covetUniNumber(attrs.shadow)} ${obj.default.shadow}`
|
|
} else if (attrs.shadow === '') {
|
|
if (Array.isArray(config.sheetShadow)) {
|
|
shadow = config.sheetShadow.join(' ')
|
|
} else if (config.sheetShadow && config.sheetShadow != 'none') {
|
|
let obj = getDefaultColorObj(attrs.color, attrs.color)
|
|
shadow = `0 4px ${covetUniNumber(config.sheetShadow)} ${obj.default.shadow}`
|
|
}
|
|
}
|
|
|
|
|
|
style.background = linear || getDefaultColor(background)
|
|
style.borderColor = borderColor.join(' ')
|
|
style.borderWidth = borderWidth.join(' ')
|
|
style.borderStyle = borderStyle.join(' ')
|
|
style.borderRadius = borderRadius.join(' ')
|
|
style.margin = margin.join(' ')
|
|
style.padding = padding.join(' ')
|
|
style.boxShadow = shadow
|
|
return style;
|
|
});
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
export default {
|
|
options: {
|
|
styleIsolation: "apply-shared",
|
|
virtualHost: true,
|
|
addGlobalClass: true,
|
|
multipleSlots: true,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.tmSheet {
|
|
position: relative;
|
|
|
|
.tmSheetLoading {
|
|
display: flex;
|
|
border: 0px solid transparent;
|
|
width: 100%;
|
|
height: 100%;
|
|
position: absolute;
|
|
top: 0px;
|
|
left: 0px;
|
|
padding: 0px;
|
|
margin: 0px;
|
|
backdrop-filter: blur(3px);
|
|
background-color: rgba(125, 125, 125, 0.2);
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: row;
|
|
}
|
|
}
|
|
</style>
|