166 lines
4.0 KiB
Vue
166 lines
4.0 KiB
Vue
<!--
|
||
Jeepay导航卡片, 支持4种风格
|
||
@author terrfly
|
||
@site https://www.jeequan.com
|
||
@date 2022/11/16 11:45
|
||
-->
|
||
<template>
|
||
<!-- 宫格类型 -->
|
||
<template v-if="props.type == 'grid'">
|
||
<view class="grid-card-wrapper" :style="{ margin: calcPadding(), '--space-w': space + 'rpx' }">
|
||
<block v-for="(v, i) in navListComputed" :key="i">
|
||
<view
|
||
class="card-main"
|
||
:style="{ margin: calcMargin(), '--radius-size': radiusSize + 'rpx' }"
|
||
hover-class="touch-hover"
|
||
hover-stay-time="150"
|
||
:class="{ 'card-big-main': navListComputed.length == 4 || navListComputed.length <= 2 }"
|
||
@tap="clickFunc(v)"
|
||
>
|
||
<image :src="v.icon" mode="scaleToFill" />
|
||
<view class="card-title">{{ v.title }}</view>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 列表类型 -->
|
||
<template v-if="props.type == 'list'">
|
||
<view class="list-nav-wrapper" :style="{ '--radius-size': radiusSize + 'rpx' }">
|
||
<block v-for="(v, i) in navListComputed" :key="i">
|
||
<view class="nav-main" hover-class="touch-hover" hover-stay-time="150" @tap="clickFunc(v)">
|
||
<image :src="v.icon" mode="scaleToFill" />
|
||
<view class="nav-text">{{ v.title }}</view>
|
||
<image class="nav-right" src="/static/iconImg/icon-arrow-right.svg" mode="scaleToFill" />
|
||
</view>
|
||
</block>
|
||
</view>
|
||
</template>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref, computed } from "vue"
|
||
import go from "@/commons/utils/go.js"
|
||
import ent from '@/commons/utils/ent.js'
|
||
import {
|
||
hasPermission
|
||
} from '@/commons/utils/hasPermission.js';
|
||
// 定义组件参数
|
||
const props = defineProps({
|
||
//显示类型: 支持 grid-宫格 list-列表
|
||
type: { type: String, default: "list" },
|
||
|
||
// 圆角矩形大小 为0 则 无圆角
|
||
radiusSize: { type: Number, default: 32 },
|
||
|
||
//间隙类型: 仅grid-宫格时生效, 支持 0 和 25
|
||
space: { type: Number, default: 25 },
|
||
|
||
// 导航列表, 格式:{ icon, title, pageUrl, clickFunc, entId }
|
||
navList: { type: Array, default: () => [] },
|
||
})
|
||
|
||
// 点击事件
|
||
async function clickFunc(nav) {
|
||
if(nav.pageUrl=="PAGES_SALES_SUMMARY"){
|
||
let res =await hasPermission('允许查看经营数据')
|
||
if(!res) return
|
||
}
|
||
// 包含回调事件
|
||
if (nav.clickFunc) {
|
||
return nav.clickFunc(nav)
|
||
}
|
||
|
||
// 包含URL
|
||
if (nav.pageUrl) {
|
||
return go.to(nav.pageUrl)
|
||
}
|
||
}
|
||
const calcPadding = () => `${50 - props.space}rpx 35rpx 50rpx ${35 - props.space}rpx`
|
||
const calcMargin = () => `${props.space}rpx 0 0 ${props.space}rpx`
|
||
|
||
|
||
// 计算属性
|
||
let navListComputed = computed(() => {
|
||
return props.navList.filter(r => hasEnt(r.entId))
|
||
})
|
||
|
||
function hasEnt(entId){
|
||
|
||
// 不包含: 说明无需隐藏
|
||
if(!entId){
|
||
return true
|
||
}
|
||
return ent.has(entId)
|
||
}
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.grid-card-wrapper {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
background-color: $v-color-bgrey;
|
||
padding-top: 25rpx;
|
||
.card-main {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin: 25rpx 0 0 25rpx;
|
||
width: calc(33.3% - var(--space-w));
|
||
height: 210rpx;
|
||
border-radius: var(--radius-size);
|
||
background-color: $J-bg-ff;
|
||
image {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
}
|
||
.card-title {
|
||
margin-top: 22rpx;
|
||
color: $J-color-t80;
|
||
font-size: $J-f-size30;
|
||
}
|
||
}
|
||
.card-big-main {
|
||
width: calc(50% - var(--space-w));
|
||
}
|
||
}
|
||
|
||
.list-nav-wrapper {
|
||
margin: 0 auto;
|
||
width: 680rpx;
|
||
border-radius: var(--radius-size);
|
||
overflow: hidden;
|
||
|
||
.nav-main {
|
||
display: flex;
|
||
align-items: center;
|
||
padding-left: 30rpx;
|
||
height: 120rpx;
|
||
background-color: $J-bg-ff;
|
||
image {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
vertical-align: text-bottom;
|
||
margin: 0 20rpx 0 10rpx;
|
||
}
|
||
.nav-text {
|
||
flex: 1;
|
||
font-size: 32rpx;
|
||
}
|
||
.nav-right {
|
||
margin: 0;
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
}
|
||
}
|
||
.nav-setup {
|
||
margin: 30rpx auto;
|
||
width: 680rpx;
|
||
border-radius: $J-b-r32;
|
||
box-sizing: border-box;
|
||
}
|
||
}
|
||
</style>
|