Files
huangjingfen/pro_v3.5.1/view/uniapp/components/home/index.vue
panchengyong 7acbf45ff7 new files
2026-03-07 22:29:07 +08:00

511 lines
11 KiB
Vue

<template>
<!-- 悬浮导航按钮 -->
<view :style="colorStyle" v-if="is_show && showMenu">
<view style="touch-action: none">
<view class="home" style="position: fixed" :style="{ top: top + 'px' }" id="right-nav"
@touchmove.stop.prevent="setTouchMove">
<view class="menus" :class="isOpen ? `menus_isOpen-${menus.length}` : ''" v-if="index == 3 ">
<view id="fab3"></view>
<!-- style="height: 298rpx;" -->
<view class="menu menu_main" @click="changeStatus">
<image :src="isOpen ? main_after_image : main_ago_image" class="image"
style="border-radius: 50%;" />
</view>
<view v-for="(menu, index) in menus" :key="index"
:class="['menu menu_a', `menu_a--${index + 1}`]" @click.stop="jump(menu.url)">
<image :src="menu.img" class="icon-img"></image>
</view>
</view>
<view id="fab1" class="fab1 p-10" v-if="index == 1" @touchmove.stop.prevent="setTouchMove">
<view v-show="isOpen" class="img-list">
<view v-for="(item, index) in menus" :key="index" class="img-box" @click="jump(item.url)">
<image class="img" :src="item.img" mode=""></image>
</view>
</view>
<view class="btn-box" @click="changeStatus">
<view class="img-box">
<image class="img" :src="main_ago_image" mode=""></image>
</view>
</view>
</view>
<view id="fab2" class="fab2 flex-y-center relative p-10" :class="{ hide: isHide }" v-if="index == 2">
<view v-if="isOpen" class="img-list">
<view v-for="(item, index) in menus" :key="index" class="img-box" @click="jump(item.url)">
<image class="img" :src="item.img" mode=""></image>
</view>
</view>
<view v-if="!isOpen" class="btn-box" @click="changeStatus">
<view class="img-box">
<image class="img" :src="main_ago_image" mode=""></image>
</view>
</view>
<view v-if="isOpen" class="icon" @click="changeStatus">
<text class="iconfont icon-ic_rightarrow"></text>
</view>
</view>
<view class="menus fab4" :class="isOpen ? `menus_isOpen menus_isOpen-${menus.length}` : ''"
v-if="index == 4">
<view id="fab4" style="height: 350rpx;width: 1px;"></view>
<view class="menu_bag" :class="isOpen ? ' has-bag' : opend ? 'close-bag' : ''"></view>
<view class="menu menu_main menu_main4" @click="changeStatus">
<text v-if="isOpen" class="iconfont icon-ic_close"></text>
</view>
<view v-for="(menu, index) in menus" :key="index"
:style="{ zIndex: isOpen ? 9999 : '-1' }"
:class="['menu menu_a', `menu_a--${index + 1}`]" @click.stop="jump(menu.url)">
<image :src="menu.img" class="icon-img"></image>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {mapGetters} from 'vuex';
import colors from '@/mixins/color.js';
import {HTTP_REQUEST_URL} from '@/config/app';
import Vue from 'vue';
import {getSuspended} from '@/api/api.js';
export default {
name: 'fabHome',
props: {
// 风格样式
styleType: {
type: Number,
default: 2
},
},
mixins: [colors],
data: function() {
return {
top: '545',
imgHost: HTTP_REQUEST_URL,
isOpen: false, //菜单是否展开
opend: false, //是否打开过
menus: [],
main_image: '',
shifting: 10,
index: 4,
is_show: 1,
main_after_image: '',
main_ago_image: '',
windowHeight: 0,
fabHeight: 0,
isHide: false,
menu:{
color:'rgba(0, 0, 0, 0.10)'
},
showMenu: true
};
},
computed:{
...mapGetters(['isLogin'])
},
mounted() {
uni.$on('scroll', this.scrollFn);
if(this.isLogin && [1,2].includes(this.$store.state.app.identity)){
this.showMenu = false;
}else{
setTimeout(()=>{
this.getSuspended();
},500)
}
uni.getSystemInfo({
success: (res) => {
this.windowHeight = res.windowHeight;
}
});
},
beforeDestroy() {
this.$Cache.set('homeTop',this.top);
},
methods: {
changeStatus() {
this.isOpen = !this.isOpen;
this.opend = true;
this.isHide = false;
},
setTouchMove(e) {
let that = this;
let clientY = e.touches[0].clientY;
if (clientY > (that.fabHeight / 2) && clientY < (that.windowHeight - that.fabHeight / 2)) {
that.top = clientY;
}
},
scrollFn() {
this.isOpen = false;
this.isHide = true;
},
jump(url) {
this.$util.JumpPath(url);
},
// 获取配置信息
getSuspended() {
getSuspended().then(res => {
const data = res.data;
this.menus = data.button;
this.index = data.index;
this.is_show = data.is_show;
this.main_image = data.main_image;
this.main_after_image = data.main_after_image || '';
this.main_ago_image = data.main_ago_image || '';
this.shifting = data.shifting;
if(data.is_show){
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query
.select(`#fab${this.index}`)
.boundingClientRect((data) => {
this.fabHeight = data.height;
if(this.$Cache.get('homeTop')){
this.top = this.$Cache.get('homeTop')
}else{
if (this.shifting == 100) {
this.top = this.windowHeight - data.height / 2
} else if (this.shifting == 0) {
this.top = data.height / 2
} else {
this.top = this.shifting / 100 * this.windowHeight
}
}
})
.exec();
});
}
});
},
}
};
</script>
<style lang="scss" scoped>
.home {
position: fixed;
color: white;
text-align: center;
z-index: 9999;
display: flex;
right: 0;
transform: translateY(-50%);
}
.menus {
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
position: relative;
right: 20rpx;
font-size: 24rpx;
color: #ffffff;
margin: auto;
}
.menus .menu {
display: block;
text-align: center;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition-timing-function: cubic-bezier(0.25, 1.2, 0.45, 1);
transition-duration: 1s;
}
.menu_bag {
width: 70rpx;
height: 70rpx;
// border-radius: 90rpx 0 0 90rpx;
border-radius: 70rpx;
background: rgba(51, 51, 51, 0.1);
box-shadow: 0rpx 0rpx 17rpx 0rpx rgba(0, 0, 0, 0.1);
position: absolute;
}
.close-bag {
animation: close 0.5s ease forwards;
}
.has-bag {
border-radius: 50%;
animation: show 0.4s ease forwards;
}
@keyframes show {
0% {
width: 70rpx;
height: 70rpx;
}
100% {
width: 350rpx;
height: 350rpx;
}
}
@keyframes close {
0% {
width: 350rpx;
height: 350rpx;
}
100% {
width: 70rpx;
height: 70rpx;
}
}
.menus .menu_main {
z-index: 2;
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
font-size: 36px;
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: center;
image {
width: 100%;
height: 100%;
}
}
.menus .menu_a {
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
color: inherit;
// box-shadow: 0 0 6rpx var(--color);
// transform: translate(-50%, -50%) rotate(180deg);
transform: translate(-50%, -50%);
}
/* 点击悬浮球主菜单按钮后样式 */
.menus_isOpen .menu_main {
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
font-size: 28rpx;
color: #607d88;
background-color: #ffffff;
}
.menus_isOpen-3 {
.menu_a--1 {
transform: translate(-100%, calc(-50% - 93rpx));
}
.menu_a--2 {
transform: translate(calc(-50% - 100rpx), calc(-50%));
}
.menu_a--3 {
transform: translate(-100%, calc(-50% + 93rpx));
}
}
.menus_isOpen-4 {
.menu_a--1 {
transform: translate(-50%, calc(-50% - 100rpx));
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
.menu_a--2 {
transform: translate(calc(-50% - 90rpx), calc(-50% - 50rpx));
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
.menu_a--3 {
transform: translate(calc(-50% - 90rpx), calc(-50% + 50rpx));
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
.menu_a--4 {
transform: translate(-50%, calc(-50% + 100rpx));
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
.menu_a--5 {
transform: translate(calc(-50% + 100rpx), calc(-50% + 50rpx));
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
.menu_a--6 {
transform: translate(calc(-50% + 100rpx), calc(-50% - 50rpx));
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
}
.menus_isOpen-5 {
.menu_a--1 {
transform: translate(-50%, calc(-50% - 110rpx));
}
.menu_a--2 {
transform: translate(calc(-50% - 76rpx), calc(-50% - 76rpx));
}
.menu_a--3 {
transform: translate(calc(-50% - 106rpx), -50%);
}
.menu_a--4 {
transform: translate(calc(-50% - 76rpx), calc(-50% + 76rpx));
}
.menu_a--5 {
transform: translate(-50%, calc(-50% + 110rpx));
}
}
.icon-img {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
}
.fab1 {
position: absolute;
right: 20rpx;
bottom: 0;
border-radius: 45rpx;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10rpx);
.img-box {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
background: #FFFFFF;
.img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.img-list {
position: relative;
z-index: 2;
.img-box {
margin: 0 0 16rpx 0;
box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(0, 0, 0, 0.1);
}
}
.btn-box {
position: relative;
z-index: 2;
.img-box {}
}
}
.fab2 {
border-radius: 45rpx 0 0 45rpx;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10rpx);
&.hide {
transform: translateX(42rpx);
opacity: 0.5;
}
.img-box {
position: relative;
z-index: 2;
width: 70rpx;
height: 70rpx;
border-radius: 50%;
background: #FFFFFF;
.img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.img-list {
position: relative;
z-index: 2;
display: flex;
.img-box {
box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(0, 0, 0, 0.1);
+.img-box {
margin: 0 0 0 16rpx;
}
}
}
.icon {
position: relative;
z-index: 2;
display: flex;
justify-content: center;
align-items: center;
width: 28rpx;
height: 28rpx;
margin-left: 16rpx;
}
.iconfont {
font-size: 28rpx;
color: #333333;
}
}
.menu_main4 {
background: #FFFFFF;
.icon-ic_close {
font-size: 34rpx;
color: #333333;
}
}
.fab4 {
.menu_bag {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 70rpx;
height: 70rpx;
border-radius: 50%;
background: rgba(51, 51, 51, 0.1);
backdrop-filter: blur(7.78rpx);
box-shadow: 0rpx 0rpx 13rpx 0rpx rgba(0, 0, 0, 0.1);
}
.close-bag {
background: rgba(51, 51, 51, 0.1);
backdrop-filter: blur(7.78rpx);
}
.has-bag {
background: rgba(255, 255, 255, 0.5);
}
.menu_main {
width: 48rpx;
height: 48rpx;
}
&.menus_isOpen {
.menu_main {
width: 70rpx;
height: 70rpx;
}
}
}
</style>