增加other分包页面
我的页面里增加跳转other分包跳转(仅在ios不是浏览器审核时展示)
This commit is contained in:
523
tuniao-ui/components/tn-fab/tn-fab.vue
Normal file
523
tuniao-ui/components/tn-fab/tn-fab.vue
Normal file
@@ -0,0 +1,523 @@
|
||||
<template>
|
||||
<view class="tn-fab-class tn-fab" @touchmove.stop.prevent>
|
||||
<view
|
||||
class="tn-fab__box"
|
||||
:class="{'tn-fab--right': left === 'auto'}"
|
||||
:style="{
|
||||
left: $t.string.getLengthUnitValue(fabLeft || left),
|
||||
right: $t.string.getLengthUnitValue(fabRight || right),
|
||||
bottom: $t.string.getLengthUnitValue(fabBottom || bottom),
|
||||
zIndex: elZIndex
|
||||
}"
|
||||
>
|
||||
<view
|
||||
v-if="visibleSync"
|
||||
class="tn-fab__btns"
|
||||
:class="[`tn-fab__btns__animation--${animationType}`,
|
||||
showFab ? `tn-fab__btns--visible--${animationType}` : ''
|
||||
]"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in btnList"
|
||||
:key="index"
|
||||
class="tn-fab__item"
|
||||
:class="[
|
||||
`tn-fab__item__animation--${animationType}`,
|
||||
{'tn-fab__item--left': right === 'auto'}
|
||||
]"
|
||||
:style="[fabItemStyle(index)]"
|
||||
@tap.stop="handleClick(index)"
|
||||
>
|
||||
<!-- 带图标或者图片时显示的文字信息 -->
|
||||
<view
|
||||
v-if="animationType !== 'around' && (item.imgUrl || item.icon)"
|
||||
:class="[left === 'auto' ? 'tn-fab__item__text--right' : 'tn-fab__item__text--left']"
|
||||
:style="{
|
||||
color: item.textColor || '#FFF',
|
||||
fontSize: $t.string.getLengthUnitValue(item.textSize || 28)
|
||||
}"
|
||||
>{{ item.text || '' }}</view>
|
||||
|
||||
<!-- 带图片或者图标时的图片、图标信息 -->
|
||||
<view
|
||||
class="tn-fab__item__btn"
|
||||
:class="[!item.bgColor ? backgroundColorClass : '']"
|
||||
:style="{
|
||||
width: $t.string.getLengthUnitValue(width),
|
||||
height: $t.string.getLengthUnitValue(height),
|
||||
lineHeight: $t.string.getLengthUnitValue(height),
|
||||
backgroundColor: item.bgColor || backgroundColorStyle || '#01BEFF',
|
||||
borderRadius: $t.string.getLengthUnitValue(radius)
|
||||
}"
|
||||
>
|
||||
<!-- 无图片和无图标时只显示文字 -->
|
||||
<view
|
||||
v-if="!item.imgUrl && !item.icon"
|
||||
class="tn-fab__item__btn__title"
|
||||
:style="{
|
||||
color: item.textColor || '#fff',
|
||||
fontSize: $t.string.getLengthUnitValue(item.textSize || 28)
|
||||
}"
|
||||
>{{ item.text || '' }}</view>
|
||||
<!-- 图标 -->
|
||||
<view
|
||||
v-if="item.icon"
|
||||
class="tn-fab__item__btn__icon"
|
||||
:class="[`tn-icon-${item.icon}`]"
|
||||
:style="{
|
||||
color: item.iconColor || '#fff',
|
||||
fontSize: $t.string.getLengthUnitValue(item.iconSize || iconSize || 64)
|
||||
}"
|
||||
></view>
|
||||
<!-- 图片 -->
|
||||
<image
|
||||
v-else-if="!item.icon && item.imgUrl"
|
||||
class="tn-fab__item__btn__image"
|
||||
:style="{
|
||||
width: $t.string.getLengthUnitValue(item.imgWidth || 64),
|
||||
height: $t.string.getLengthUnitValue(item.imgHeight || 64),
|
||||
}"
|
||||
:src="item.imgUrl"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="tn-fab__item__btn tn-fab__item__btn--fab"
|
||||
:class="[backgroundColorClass, fontColorClass, {'tn-fab__item__btn--active': showFab}]"
|
||||
:style="{
|
||||
width: $t.string.getLengthUnitValue(width),
|
||||
height: $t.string.getLengthUnitValue(height),
|
||||
backgroundColor: backgroundColorStyle || !backgroundColorClass ? '#01BEFF' : '',
|
||||
color: fontColorStyle || '#fff',
|
||||
borderRadius: $t.string.getLengthUnitValue(radius),
|
||||
zIndex: elZIndex - 1
|
||||
}"
|
||||
@tap.stop="fabClick"
|
||||
>
|
||||
<slot>
|
||||
<view class="tn-fab__item__btn__icon" :class="[`tn-icon-${icon}`]" :style="{fontSize: $t.string.getLengthUnitValue(iconSize || 64)}"></view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="visibleSync && showMask" class="tn-fab__mask" :class="{'tn-fab__mask--visible': showFab}" :style="{zIndex: elZIndex - 3}" @tap="clickMask()"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentsColorMixin from '../../libs/mixin/components_color.js'
|
||||
export default {
|
||||
name: 'tn-fab',
|
||||
mixins: [componentsColorMixin],
|
||||
props: {
|
||||
// 按钮列表
|
||||
// {
|
||||
// // 背景颜色
|
||||
// bgColor: '#fff',
|
||||
// // 图片地址
|
||||
// imgUrl: '',
|
||||
// // 图片宽度
|
||||
// imgWidth: 60,
|
||||
// // 图片高度
|
||||
// imgHeight: 60,
|
||||
// // 图标名称
|
||||
// icon: '',
|
||||
// // 图标尺寸
|
||||
// iconSize: 60,
|
||||
// // 图标颜色
|
||||
// iconColor: '#fff',
|
||||
// // 提示文字
|
||||
// text: '',
|
||||
// // 文字大小
|
||||
// textSize: 30,
|
||||
// // 字体颜色
|
||||
// textColor: '#fff'
|
||||
// }
|
||||
btnList: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
// 自定义悬浮按钮内容
|
||||
customBtn: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 悬浮按钮的宽度
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: 88
|
||||
},
|
||||
// 悬浮按钮的高度
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: 88
|
||||
},
|
||||
// 图标大小
|
||||
iconSize: {
|
||||
type: [String, Number],
|
||||
default: 64
|
||||
},
|
||||
// 图标名称
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'open'
|
||||
},
|
||||
// 按钮圆角
|
||||
radius: {
|
||||
type: [String, Number],
|
||||
default: '50%'
|
||||
},
|
||||
// 按钮距离左边的位置
|
||||
left: {
|
||||
type: [String, Number],
|
||||
default: 'auto'
|
||||
},
|
||||
// 按钮距离右边的位置
|
||||
right: {
|
||||
type: [String, Number],
|
||||
default: 'auto'
|
||||
},
|
||||
// 按钮距离底部的位置
|
||||
bottom: {
|
||||
type: [String, Number],
|
||||
default: 100
|
||||
},
|
||||
// 展示动画类型 up 往上展示 around 环绕
|
||||
animationType: {
|
||||
type: String,
|
||||
default: 'up'
|
||||
},
|
||||
// 当动画为圆环时,每个弹出按钮之间的距离, 单位px
|
||||
aroundBtnDistance: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 显示遮罩
|
||||
showMask: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 点击遮罩是否可以关闭
|
||||
maskCloseable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showFab: false,
|
||||
visibleSync: false,
|
||||
timer: null,
|
||||
fabLeft: 0,
|
||||
fabRight: 0,
|
||||
fabBottom: 0,
|
||||
fabBtnInfo: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0
|
||||
},
|
||||
systemInfo: {
|
||||
width: 0,
|
||||
height: 0
|
||||
},
|
||||
updateProps: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
elZIndex() {
|
||||
return this.zIndex || this.$t.zIndex.fab
|
||||
},
|
||||
propsData() {
|
||||
return [this.width, this.height, this.left, this.right, this.bottom]
|
||||
},
|
||||
fabItemStyle() {
|
||||
return (index) => {
|
||||
let style = {
|
||||
zIndex: this.elZIndex - 2
|
||||
}
|
||||
if (this.animationType === 'up' || !this.showFab) {
|
||||
return style
|
||||
}
|
||||
let base = 1
|
||||
if (this.left === 'auto') {
|
||||
base = 1
|
||||
} else if (this.right === 'auto') {
|
||||
base = -1
|
||||
}
|
||||
style.transform = `rotate(${base * index * 60}deg) translateX(${(this.aroundBtnDistance + this.fabBtnInfo.width) * (-(base))}px)`
|
||||
return style
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
propsData() {
|
||||
// 更新按钮信息
|
||||
this.updateProps = true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.getFabBtnRectInfo()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 按钮点击事件
|
||||
handleClick(index) {
|
||||
this.close()
|
||||
this.$emit('click', {index: index})
|
||||
},
|
||||
// 点击悬浮按钮
|
||||
fabClick() {
|
||||
if (this.showFab) {
|
||||
this.close()
|
||||
} else {
|
||||
// console.log(this.visibleSync);
|
||||
if (this.visibleSync) {
|
||||
this.visibleSync = false
|
||||
return
|
||||
}
|
||||
this.open()
|
||||
}
|
||||
},
|
||||
// 点击遮罩
|
||||
clickMask() {
|
||||
if (!this.showMask || !this.maskCloseable) return
|
||||
this.close()
|
||||
},
|
||||
|
||||
open() {
|
||||
this.change('visibleSync', 'showFab', true)
|
||||
this.translateFabPosition()
|
||||
},
|
||||
close() {
|
||||
this.change('showFab', 'visibleSync', false)
|
||||
this.fabLeft = 0
|
||||
this.fabRight = 0
|
||||
this.fabBottom = 0
|
||||
},
|
||||
// 关闭时先通过动画隐藏弹窗和遮罩,再移除整个组件
|
||||
// 打开时,先渲染组件,延时一定时间再让遮罩和弹窗的动画起作用
|
||||
change(param1, param2, status) {
|
||||
this[param1] = status
|
||||
if (status) {
|
||||
// #ifdef H5 || MP
|
||||
this.timer = setTimeout(() => {
|
||||
this[param2] = status
|
||||
this.$emit(status ? 'open' : 'close')
|
||||
clearTimeout(this.timer)
|
||||
}, 10)
|
||||
// #endif
|
||||
// #ifndef H5 || MP
|
||||
this.$nextTick(() => {
|
||||
this[param2] = status
|
||||
this.$emit(status ? 'open' : 'close')
|
||||
})
|
||||
// #endif
|
||||
} else {
|
||||
this.timer = setTimeout(() => {
|
||||
this[param2] = status
|
||||
this.$emit(status ? 'open' : 'close')
|
||||
clearTimeout(this.timer)
|
||||
}, 250)
|
||||
}
|
||||
},
|
||||
|
||||
/******************** 旋转动画相关函数 ********************/
|
||||
// 获取按钮的信息
|
||||
async getFabBtnRectInfo() {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
const btnRectInfo = await this._tGetRect('.tn-fab__item__btn--fab')
|
||||
if (!btnRectInfo) {
|
||||
setTimeout(() => {
|
||||
this.getFabBtnRectInfo()
|
||||
}, 10)
|
||||
return
|
||||
}
|
||||
console.log(btnRectInfo);
|
||||
this.systemInfo = {
|
||||
width: systemInfo.windowWidth,
|
||||
height: systemInfo.windowHeight
|
||||
}
|
||||
this.fabBtnInfo.width = btnRectInfo.width
|
||||
this.fabBtnInfo.height = btnRectInfo.height
|
||||
this.fabBtnInfo.left = btnRectInfo.left
|
||||
this.fabBtnInfo.right = btnRectInfo.right
|
||||
this.fabBtnInfo.bottom = btnRectInfo.bottom
|
||||
},
|
||||
// 更新悬浮按钮的位置
|
||||
translateFabPosition() {
|
||||
if (this.updateProps) {
|
||||
this.getFabBtnRectInfo()
|
||||
this.updateProps = false
|
||||
}
|
||||
if (this.animationType === 'up') return
|
||||
// 按钮组的宽度
|
||||
const btnGroupWidth = this.fabBtnInfo.width + this.aroundBtnDistance + 10
|
||||
// 判断当前按钮是在左边还是右边
|
||||
if (this.left === 'auto' && btnGroupWidth > this.systemInfo.width - this.fabBtnInfo.right) {
|
||||
// 距离不够需要移动
|
||||
this.fabRight = btnGroupWidth + 'px'
|
||||
} else if (this.right === 'auto' && btnGroupWidth > this.fabBtnInfo.left) {
|
||||
this.fabLeft = btnGroupWidth + 'px'
|
||||
}
|
||||
|
||||
if (btnGroupWidth > this.systemInfo.height - this.fabBtnInfo.bottom) {
|
||||
this.fabBottom = btnGroupWidth + 'px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.tn-fab {
|
||||
&__box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
transition: all 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
&--right {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
&__btns {
|
||||
transition: all 0.25s cubic-bezier(0,.13,0,1.43);
|
||||
transform-origin: 80% bottom;
|
||||
|
||||
&__animation--up {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
&__animation--around {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&--visible--up {
|
||||
// visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
&--visible--around {
|
||||
// visibility: visible;
|
||||
// opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
&__animation--around {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: transform 0.25s ease-in-out;
|
||||
transform-origin: 50% 50%;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
&--left {
|
||||
flex-flow: row-reverse;
|
||||
}
|
||||
|
||||
&__text {
|
||||
&--left {
|
||||
padding-left: 14rpx;
|
||||
}
|
||||
&--right {
|
||||
padding-right: 14rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 0 5rpx 2rpx rgba(0, 0, 0, 0.07);
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&--active {
|
||||
animation-name: fab-button-animation;
|
||||
animation-duration: 0.2s;
|
||||
animation-timing-function: cubic-bezier(0,.13,0,1.43);
|
||||
}
|
||||
|
||||
&__title {
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
text-align: center;
|
||||
font-size: 64rpx;
|
||||
}
|
||||
|
||||
&__image {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: $tn-mask-bg-color;
|
||||
transition: all 0.2s ease-in-out;
|
||||
opacity: 0;
|
||||
|
||||
&--visible {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fab-button-animation {
|
||||
0% {
|
||||
transform: scale(0.6);
|
||||
}
|
||||
// 20% {
|
||||
// transform: scale(1.8);
|
||||
// }
|
||||
// 40% {
|
||||
// transform: scale(0.4);
|
||||
// }
|
||||
// 50% {
|
||||
// transform: scale(1.4);
|
||||
// }
|
||||
// 80% {
|
||||
// transform: scale(0.8);
|
||||
// }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user