mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-11-13 04:18:53 +08:00
feat: 分类页支持后台配置的四种导航模板
This commit is contained in:
93
components/category/category-scroller.vue
Normal file
93
components/category/category-scroller.vue
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<scroll-view scroll-x scroll-with-animation class="cate-scroller" :scroll-into-view="intoView">
|
||||||
|
<view
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
:id="'cs-' + item.id"
|
||||||
|
class="cs-item"
|
||||||
|
:class="{ active: item.id === currentId, 'cs-item--text': mode === 'text' }"
|
||||||
|
@click="$emit('change', item)"
|
||||||
|
>
|
||||||
|
<template v-if="mode === 'icon'">
|
||||||
|
<view class="cs-icon">
|
||||||
|
<u-image width="88rpx" height="88rpx" shape="circle" :src="item.image">
|
||||||
|
<template #loading><u-loading-icon></u-loading-icon></template>
|
||||||
|
</u-image>
|
||||||
|
</view>
|
||||||
|
<text class="cs-name">{{ item.name }}</text>
|
||||||
|
</template>
|
||||||
|
<text v-else class="cs-text-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
list?: any[]
|
||||||
|
currentId?: string | number | null
|
||||||
|
mode?: 'icon' | 'text'
|
||||||
|
}>(), {
|
||||||
|
list: () => [],
|
||||||
|
currentId: null,
|
||||||
|
mode: 'icon'
|
||||||
|
})
|
||||||
|
|
||||||
|
defineEmits(['change'])
|
||||||
|
|
||||||
|
const intoView = computed(() =>
|
||||||
|
props.currentId != null ? `cs-${props.currentId}` : ''
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.cate-scroller {
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.cs-item {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 120rpx;
|
||||||
|
padding: 16rpx 0 10rpx;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.cs-icon {
|
||||||
|
width: 88rpx;
|
||||||
|
height: 88rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 2rpx solid transparent;
|
||||||
|
}
|
||||||
|
.cs-item.active .cs-icon {
|
||||||
|
border-color: $light-color;
|
||||||
|
}
|
||||||
|
.cs-name {
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #333;
|
||||||
|
max-width: 110rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.cs-item.active .cs-name {
|
||||||
|
color: $light-color;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.cs-item--text {
|
||||||
|
width: auto;
|
||||||
|
padding: 18rpx 24rpx;
|
||||||
|
}
|
||||||
|
.cs-text-name {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.cs-item--text.active .cs-text-name {
|
||||||
|
color: $light-color;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
51
components/category/category-side-list.vue
Normal file
51
components/category/category-side-list.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<scroll-view scroll-y scroll-with-animation class="side-list">
|
||||||
|
<view
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
class="side-item"
|
||||||
|
:class="{ active: item.id === currentId }"
|
||||||
|
@click="$emit('change', item)"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
withDefaults(defineProps<{
|
||||||
|
list?: any[]
|
||||||
|
currentId?: string | number | null
|
||||||
|
}>(), {
|
||||||
|
list: () => [],
|
||||||
|
currentId: null
|
||||||
|
})
|
||||||
|
|
||||||
|
defineEmits(['change'])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.side-list {
|
||||||
|
width: 160rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
}
|
||||||
|
.side-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 90rpx;
|
||||||
|
padding: 10rpx 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
&.active {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $light-color;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
83
components/category/sort-bar.vue
Normal file
83
components/category/sort-bar.vue
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<view class="sort-bar">
|
||||||
|
<view
|
||||||
|
class="sort-item"
|
||||||
|
:class="{ active: sort === 'releaseTime' }"
|
||||||
|
@click="onClick('releaseTime')"
|
||||||
|
>
|
||||||
|
综合
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="sort-item"
|
||||||
|
:class="{ active: sort === 'buyCount' }"
|
||||||
|
@click="onClick('buyCount')"
|
||||||
|
>
|
||||||
|
销量
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="sort-item"
|
||||||
|
:class="{ active: sort === 'price' }"
|
||||||
|
@click="onClick('price')"
|
||||||
|
>
|
||||||
|
<text>价格</text>
|
||||||
|
<view class="arrows">
|
||||||
|
<u-icon
|
||||||
|
name="arrow-up"
|
||||||
|
size="10"
|
||||||
|
:color="sort === 'price' && order === 'asc' ? '#ff6700' : '#c5c5c5'"
|
||||||
|
></u-icon>
|
||||||
|
<u-icon
|
||||||
|
name="arrow-down"
|
||||||
|
size="10"
|
||||||
|
:color="sort === 'price' && order === 'desc' ? '#ff6700' : '#c5c5c5'"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
sort?: string
|
||||||
|
order?: string
|
||||||
|
}>(), {
|
||||||
|
sort: 'releaseTime',
|
||||||
|
order: 'desc'
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
|
||||||
|
function onClick(type: string) {
|
||||||
|
let nextOrder = 'desc'
|
||||||
|
if (type === 'price') {
|
||||||
|
nextOrder = props.sort === 'price' && props.order === 'desc' ? 'asc' : 'desc'
|
||||||
|
}
|
||||||
|
emit('change', { sort: type, order: nextOrder })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.sort-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 72rpx;
|
||||||
|
background: #fff;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
.sort-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
&.active {
|
||||||
|
color: $light-color;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.arrows {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-left: 6rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
55
components/category/sub-tag-bar.vue
Normal file
55
components/category/sub-tag-bar.vue
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<scroll-view scroll-x scroll-with-animation class="tag-bar" :scroll-into-view="intoView">
|
||||||
|
<view
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.id"
|
||||||
|
:id="'tb-' + item.id"
|
||||||
|
class="tag-item"
|
||||||
|
:class="{ active: item.id === currentId }"
|
||||||
|
@click="$emit('change', item)"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
list?: any[]
|
||||||
|
currentId?: string | number | null
|
||||||
|
}>(), {
|
||||||
|
list: () => [],
|
||||||
|
currentId: null
|
||||||
|
})
|
||||||
|
|
||||||
|
defineEmits(['change'])
|
||||||
|
|
||||||
|
const intoView = computed(() =>
|
||||||
|
props.currentId != null ? `tb-${props.currentId}` : ''
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tag-bar {
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
padding: 8rpx 0;
|
||||||
|
}
|
||||||
|
.tag-item {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8rpx 24rpx;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #333;
|
||||||
|
background: #f5f5f5;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
&.active {
|
||||||
|
color: #fff;
|
||||||
|
background: $light-color;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
260
components/category/tpl-category-goods.vue
Normal file
260
components/category/tpl-category-goods.vue
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<view class="tpl-goods">
|
||||||
|
<!-- 模板2/3:顶部一级分类图标横滑 -->
|
||||||
|
<category-scroller
|
||||||
|
v-if="template !== 4"
|
||||||
|
:list="categoryList"
|
||||||
|
:current-id="currentL1 && currentL1.id"
|
||||||
|
mode="icon"
|
||||||
|
@change="onL1Change"
|
||||||
|
/>
|
||||||
|
<!-- 模板2:三级分类标签横滑 -->
|
||||||
|
<sub-tag-bar
|
||||||
|
v-if="template === 2 && l3List.length"
|
||||||
|
:list="l3List"
|
||||||
|
:current-id="currentL3 && currentL3.id"
|
||||||
|
@change="onL3Change"
|
||||||
|
/>
|
||||||
|
<view class="tpl-main">
|
||||||
|
<!-- 左侧:模板2/3 为二级分类,模板4 为一级分类 -->
|
||||||
|
<category-side-list
|
||||||
|
:list="sideList"
|
||||||
|
:current-id="sideCurrentId"
|
||||||
|
@change="onSideChange"
|
||||||
|
/>
|
||||||
|
<view class="tpl-right">
|
||||||
|
<!-- 模板4:右上二级分类文字横滑(起点为当前一级名称,作为"全部"入口) -->
|
||||||
|
<category-scroller
|
||||||
|
v-if="template === 4"
|
||||||
|
:list="l2Items"
|
||||||
|
:current-id="topCurrentId"
|
||||||
|
mode="text"
|
||||||
|
@change="onL2Change"
|
||||||
|
/>
|
||||||
|
<sort-bar :sort="sort" :order="order" @change="onSortChange" />
|
||||||
|
<scroll-view scroll-y class="goods-scroll" @scrolltolower="loadMore">
|
||||||
|
<m-goods-list
|
||||||
|
v-if="goodsList.length"
|
||||||
|
:res="goodsList"
|
||||||
|
type="oneColumns"
|
||||||
|
:show-fields="setting.showFields"
|
||||||
|
:tab-bar-gap="false"
|
||||||
|
@add-cart="onAddCart"
|
||||||
|
/>
|
||||||
|
<view v-else-if="!loading" class="empty">
|
||||||
|
<text>{{ failed ? '加载失败,请点击重试' : '暂无商品' }}</text>
|
||||||
|
<view v-if="failed" class="retry" @click="loadGoods(true)">重试</view>
|
||||||
|
</view>
|
||||||
|
<uni-load-more
|
||||||
|
v-if="goodsList.length"
|
||||||
|
:status="loading ? 'loading' : hasMore ? 'more' : 'noMore'"
|
||||||
|
></uni-load-more>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, watch } from 'vue'
|
||||||
|
import { getGoodsList } from '@/api/goods.js'
|
||||||
|
import CategoryScroller from './category-scroller.vue'
|
||||||
|
import CategorySideList from './category-side-list.vue'
|
||||||
|
import SubTagBar from './sub-tag-bar.vue'
|
||||||
|
import SortBar from './sort-bar.vue'
|
||||||
|
import MGoodsList from '@/components/m-goods-list/list.vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
categoryList?: any[]
|
||||||
|
setting?: any
|
||||||
|
template?: number
|
||||||
|
}>(), {
|
||||||
|
categoryList: () => [],
|
||||||
|
setting: () => ({ template: 1, showFields: {} }),
|
||||||
|
template: 2
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentL1 = ref<any>(null)
|
||||||
|
const currentL2 = ref<any>(null)
|
||||||
|
const currentL3 = ref<any>(null)
|
||||||
|
const sort = ref('releaseTime')
|
||||||
|
const order = ref('desc')
|
||||||
|
|
||||||
|
const goodsList = ref<any[]>([])
|
||||||
|
const pageNumber = ref(1)
|
||||||
|
const hasMore = ref(true)
|
||||||
|
const loading = ref(false)
|
||||||
|
const failed = ref(false)
|
||||||
|
|
||||||
|
// 模板2/3:左侧为当前一级的二级分类;模板4:左侧为一级分类
|
||||||
|
const sideList = computed(() =>
|
||||||
|
props.template === 4
|
||||||
|
? props.categoryList
|
||||||
|
: (currentL1.value && currentL1.value.children) || []
|
||||||
|
)
|
||||||
|
const sideCurrentId = computed(() =>
|
||||||
|
props.template === 4
|
||||||
|
? currentL1.value && currentL1.value.id
|
||||||
|
: currentL2.value && currentL2.value.id
|
||||||
|
)
|
||||||
|
// 模板2 的三级标签
|
||||||
|
const l3List = computed(() =>
|
||||||
|
(currentL2.value && currentL2.value.children) || []
|
||||||
|
)
|
||||||
|
// 模板4 顶部:当前一级名称(作为"全部") + 其二级分类
|
||||||
|
const l2Items = computed(() => {
|
||||||
|
if (!currentL1.value) return []
|
||||||
|
return [currentL1.value, ...((currentL1.value.children) || [])]
|
||||||
|
})
|
||||||
|
const topCurrentId = computed(() =>
|
||||||
|
(currentL2.value && currentL2.value.id) || (currentL1.value && currentL1.value.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
const queryCategoryId = computed(() =>
|
||||||
|
(currentL3.value && currentL3.value.id) ||
|
||||||
|
(currentL2.value && currentL2.value.id) ||
|
||||||
|
(currentL1.value && currentL1.value.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.categoryList,
|
||||||
|
(list) => {
|
||||||
|
if (list && list.length && !currentL1.value) {
|
||||||
|
currentL1.value = list[0]
|
||||||
|
currentL2.value = props.template === 4 ? null : (list[0].children && list[0].children[0]) || null
|
||||||
|
currentL3.value = (currentL2.value && currentL2.value.children && currentL2.value.children[0]) || null
|
||||||
|
loadGoods(true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
function onL1Change(item: any) {
|
||||||
|
if (currentL1.value && item.id === currentL1.value.id) return
|
||||||
|
currentL1.value = item
|
||||||
|
currentL2.value = props.template === 4 ? null : (item.children && item.children[0]) || null
|
||||||
|
currentL3.value = (currentL2.value && currentL2.value.children && currentL2.value.children[0]) || null
|
||||||
|
resetSort()
|
||||||
|
loadGoods(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSideChange(item: any) {
|
||||||
|
if (props.template === 4) {
|
||||||
|
onL1Change(item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (currentL2.value && item.id === currentL2.value.id) return
|
||||||
|
currentL2.value = item
|
||||||
|
currentL3.value = (item.children && item.children[0]) || null
|
||||||
|
loadGoods(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onL3Change(item: any) {
|
||||||
|
if (currentL3.value && item.id === currentL3.value.id) return
|
||||||
|
currentL3.value = item
|
||||||
|
loadGoods(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onL2Change(item: any) {
|
||||||
|
// 选中一级名称项 = 全部(L2 置空)
|
||||||
|
if (currentL1.value && item.id === currentL1.value.id) {
|
||||||
|
currentL2.value = null
|
||||||
|
} else {
|
||||||
|
currentL2.value = item
|
||||||
|
}
|
||||||
|
loadGoods(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSortChange(payload: { sort: string; order: string }) {
|
||||||
|
sort.value = payload.sort
|
||||||
|
order.value = payload.order
|
||||||
|
loadGoods(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetSort() {
|
||||||
|
sort.value = 'releaseTime'
|
||||||
|
order.value = 'desc'
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadGoods(reset = false) {
|
||||||
|
if (loading.value || !queryCategoryId.value) return
|
||||||
|
if (reset) {
|
||||||
|
pageNumber.value = 1
|
||||||
|
goodsList.value = []
|
||||||
|
hasMore.value = true
|
||||||
|
}
|
||||||
|
loading.value = true
|
||||||
|
failed.value = false
|
||||||
|
try {
|
||||||
|
const res = await getGoodsList({
|
||||||
|
categoryId: queryCategoryId.value,
|
||||||
|
sort: sort.value,
|
||||||
|
order: order.value,
|
||||||
|
pageNumber: pageNumber.value,
|
||||||
|
pageSize: 10,
|
||||||
|
})
|
||||||
|
const records = (res.data && res.data.result && res.data.result.records) || []
|
||||||
|
goodsList.value.push(...records)
|
||||||
|
hasMore.value = records.length >= 10
|
||||||
|
} catch (e) {
|
||||||
|
failed.value = true
|
||||||
|
uni.showToast({ title: '加载失败,请重试', icon: 'none' })
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadMore() {
|
||||||
|
if (!hasMore.value || loading.value) return
|
||||||
|
pageNumber.value += 1
|
||||||
|
loadGoods(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAddCart(item: any) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tpl-goods {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.tpl-main {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.tpl-right {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.goods-scroll {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
.empty {
|
||||||
|
padding: 120rpx 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
.retry {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
padding: 10rpx 48rpx;
|
||||||
|
border: 1rpx solid $light-color;
|
||||||
|
color: $light-color;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</u-navbar>
|
</u-navbar>
|
||||||
<view class="content">
|
<view class="content" v-if="pageTemplate === 1">
|
||||||
<scroll-view scroll-y scroll-with-animation class="left-aside">
|
<scroll-view scroll-y scroll-with-animation class="left-aside">
|
||||||
<view v-for="(item, index) in tabList" :key="item.id" class="f-item b-b" :class="{ active: item.id === currentId }" @click="tabtap(item, index)">
|
<view v-for="(item, index) in tabList" :key="item.id" class="f-item b-b" :class="{ active: item.id === currentId }" @click="tabtap(item, index)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
@@ -53,6 +53,12 @@
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
<tpl-category-goods
|
||||||
|
v-else
|
||||||
|
:category-list="tabList"
|
||||||
|
:setting="categoryPageSetting"
|
||||||
|
:template="pageTemplate"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -61,10 +67,17 @@ import { ref, computed } from 'vue'
|
|||||||
import { onLoad, onReady } from '@dcloudio/uni-app'
|
import { onLoad, onReady } from '@dcloudio/uni-app'
|
||||||
import { getCategoryList } from '@/api/goods.js'
|
import { getCategoryList } from '@/api/goods.js'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
|
import { DEFAULT_CATEGORY_PAGE_SETTING } from '@/utils/categoryPageSetting'
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
|
import TplCategoryGoods from '@/components/category/tpl-category-goods.vue'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
|
const categoryPageSetting = computed(
|
||||||
|
() => store.state.categoryPageSetting || DEFAULT_CATEGORY_PAGE_SETTING
|
||||||
|
)
|
||||||
|
const pageTemplate = computed(() => categoryPageSetting.value.template || 1)
|
||||||
|
|
||||||
const currentId = ref(0)
|
const currentId = ref(0)
|
||||||
const tabList = ref<any[]>([]) // 左侧标题列表
|
const tabList = ref<any[]>([]) // 左侧标题列表
|
||||||
const categoryList = ref<any[]>([]) // 右侧分类数据列表
|
const categoryList = ref<any[]>([]) // 右侧分类数据列表
|
||||||
|
|||||||
Reference in New Issue
Block a user