123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- <template>
- <view class="icon-list" :class="mode" :style="{ '--columns': getColumnCount() }">
- <view v-for="(item, index) in displayIcons" :key="index" class="icon-item" @click="_handleClick(item.urlMap?.internal_url)">
- <view class="icon-wrapper">
- <image :src="item.image || `http://iph.href.lu/48x48?text=${index}`" :style="{ borderRadius: `${radius}px` }" mode="aspectFill" />
- </view>
- <view class="icon-text">{{ item.text }}</view>
- </view>
- </view>
- </template>
- <script setup>
- import { computed } from 'vue';
- const props = defineProps({
- icons: {
- type: Array,
- default: () => [1, 2, 3, 4],
- },
- mode: {
- type: String,
- default: 'row4',
- validator: (value) => ['row4', 'row8', 'row5', 'row10'].includes(value),
- },
- radius: {
- type: Number,
- default: 0,
- },
- });
- const getColumnCount = () => {
- switch (props.mode) {
- case 'row4':
- case 'row8':
- return 4;
- case 'row5':
- case 'row10':
- return 5;
- default:
- return 4;
- }
- };
- const getMaxItems = () => {
- switch (props.mode) {
- case 'row4':
- return 4;
- case 'row8':
- return 8;
- case 'row5':
- return 5;
- case 'row10':
- return 10;
- default:
- return 4;
- }
- };
- const _handleClick = (url) => {
- if (url) {
- uni.navigateTo({
- url,
- fail: (err) => {
- uni.switchTab({
- url,
- });
- },
- });
- }
- };
- const displayIcons = computed(() => {
- return props.icons.slice(0, getMaxItems());
- });
- </script>
- <style lang="less" scoped>
- .navigator {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .icon-list {
- display: grid;
- grid-template-columns: repeat(var(--columns), 1fr);
- gap: 16rpx;
- width: 100%;
- padding: 16px;
- box-sizing: border-box;
- background-color: #fff;
- border-radius: 8px;
- .icon-item {
- display: flex;
- flex-direction: column;
- gap: 4px;
- align-items: center;
- .icon-wrapper {
- width: 44px;
- height: 44px;
- overflow: hidden;
- image {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
- }
- .icon-text {
- width: 100%;
- overflow: hidden;
- color: #333;
- font-size: 12px;
- white-space: nowrap;
- text-align: center;
- text-overflow: ellipsis;
- }
- }
- }
- .row4 {
- grid-template-rows: 1fr;
- }
- .row8 {
- grid-template-rows: repeat(2, 1fr);
- }
- .row5 {
- grid-template-rows: 1fr;
- }
- .row10 {
- grid-template-rows: repeat(2, 1fr);
- }
- </style>
|