Browse Source

feat: 导览折叠展开

dev
jiannibang 3 years ago
parent
commit
8c84de2255
  1. 59
      src/components/BrandScroll/BrandScroll.vue
  2. BIN
      src/components/BrandScroll/btn.png
  3. BIN
      src/components/BrandScroll/closeCollapse.png
  4. BIN
      src/components/BrandScroll/openCollapse.png
  5. 2
      src/views/Guide/Guide.vue

59
src/components/BrandScroll/BrandScroll.vue

@ -1,11 +1,14 @@
<template>
<div class="toggle" :class="{ active: toggle }" @click="handleToggle"></div>
<ScrollView ref="scroll" :class="['brand-scroll', $route.path === '/guide' ? 'guide' : 'brand']" scrollbar>
<div class="brand-content">
<div class="groups" v-for="item of list" v-show="item.shopList.length" :key="item.name">
<h1 class="info">
{{ item.name }}<span class="meta">/ {{ item.shopList.length }}</span> <span v-if="item.name === currentFloor.floor" class="current">您在本层</span>
<div class="btn" :class="{ active: !item.collapsed }" @click="handleCollapseBtnClicked(item)"></div>
</h1>
<TransitionGroup name="zoom" mode="out-in" tag="div" :class="{ group: true }">
<TransitionGroup v-show="!item.collapsed" name="zoom" mode="out-in" tag="div" :class="{ group: true }">
<ShopItem
:config="config"
:shop="el"
@ -31,6 +34,7 @@ const store = useStore()
const { currentFloor } = storeToRefs(store)
const scroll = ref(null)
const toggle = ref(false)
const props = defineProps({
list: Array,
config: Object,
@ -38,7 +42,15 @@ const props = defineProps({
shop: Object,
needFocus: Boolean
})
const handleToggle = () => {
toggle.value = !toggle.value
props.list.forEach(el => {
el.collapsed = toggle.value
})
nextTick(() => {
scroll.value.refresh()
})
}
const emits = defineEmits(['click', 'nav'])
function handleShop(item) {
emits('click', item)
@ -46,6 +58,12 @@ function handleShop(item) {
function handleShopNav(item) {
emits('nav', item)
}
const handleCollapseBtnClicked = item => {
item.collapsed = !item.collapsed
nextTick(() => {
scroll.value.refresh()
})
}
watch(
() => props.list,
() =>
@ -62,17 +80,34 @@ watch(
})
)
watch([scroll, () => props.shop], () => {
watch([scroll, () => props.shop], async () => {
if (!props.needFocus || !scroll.value || !props.shop || !props.list) return
const group = props.list.find(({ shopList }) => shopList?.find(({ houseNumber }) => houseNumber === props.shop.houseNumber))
if (group && group.collapsed) {
group.collapsed = false
await nextTick()
scroll.value.refresh()
await nextTick()
}
const el = document.getElementById(props.shop.houseNumber)
if (!el) return
nextTick(() => {
scroll.value.scrollToElement(el, 500, 0, -100)
})
await nextTick()
scroll.value.scrollToElement(el, 500, 0, -100)
})
</script>
<style lang="scss" scoped>
.toggle {
position: absolute;
top: 41px;
left: 0;
width: 48px;
height: 196px;
background: center / cover no-repeat url(./closeCollapse.png);
&.active {
background: center / cover no-repeat url(./openCollapse.png);
}
}
.brand-scroll {
overflow: hidden;
height: 848px;
@ -113,6 +148,7 @@ watch([scroll, () => props.shop], () => {
padding-bottom: 180px;
}
.info {
position: relative;
margin-right: 68px;
font-weight: 900;
font-size: 32px;
@ -142,6 +178,17 @@ watch([scroll, () => props.shop], () => {
border-radius: var(--global-radius, 6px);
margin-left: 12px;
}
.btn {
position: absolute;
right: 0;
top: 12px;
width: 48px;
height: 48px;
background: center / cover no-repeat url(./btn.png);
&.active {
transform: rotateX(180deg);
}
}
}
.group {
display: grid;

BIN
src/components/BrandScroll/btn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/components/BrandScroll/closeCollapse.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
src/components/BrandScroll/openCollapse.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

2
src/views/Guide/Guide.vue

@ -139,6 +139,7 @@ function changeFloor(index) {
floorIdx.value = index
selectedShopList.value = shopList.value.map(brand => ({
...brand,
collapsed: false,
shopList: brand.shopList.filter(item => item.floor === floor.floor)
}))
resolve()
@ -164,6 +165,7 @@ function filterAboutCurrentInfo() {
floorIdx.value = currentBuildingFloorsList.value.findIndex(item => item.floorCode === floorCode)
selectedShopList.value = shopList.value.map(brand => ({
...brand,
collapsed: false,
shopList: brand.shopList.filter(item => item.floor === floor)
}))

Loading…
Cancel
Save