dingdong-mall/components/multi-level-nav/vertical-nav.vue

200 lines
5.3 KiB
Vue

<template>
<view>
<!-- 搜索栏 -->
<view class="cu-bar search bg-white">
<view class="search-form round">
<text class="cuIcon-search"></text>
<input @confirm="searchGoods" :adjust-position="true" type="text" placeholder="输入搜索内容"
confirm-type="search"></input>
</view>
</view>
<view class="VerticalBox" :style="'height:calc(' + containerHeight + ' - 100rpx)'">
<scroll-view class="VerticalNav nav" scroll-y scroll-with-animation :scroll-top="verticalNavTop">
<view class="cu-item" :class="item.goodsCategoryId==tabCur?'text-main-color cur':''" v-for="(item,index) in list"
:key="index" @tap="tabSelect" :data-index="index" :data-id="item.goodsCategoryId"
:data-main-cur="item.child && item.child.length > 0 ? item.child[0].goodsCategoryId : -1">
{{item.goodsCategoryName}}
</view>
</scroll-view>
<scroll-view class="VerticalMain" scroll-y scroll-with-animation :scroll-into-view="'main-'+mainCur"
@scroll="verticalMain">
<view class="padding-top padding-lr" v-for="(type, index1) in childrenList" :key="index1"
:id="'main-'+type.goodsCategoryId">
<view class="cu-bar bg-white bottom-border">
<view class="action">
<text class="cuIcon-title text-main-color"></text>{{type.goodsCategoryName}}
</view>
</view>
<view class="cu-list menu">
<view class="cu-item" :class="curNavItem.goodsCategoryId === subType.goodsCategoryId ? 'bg-main-color light' : ''" v-for="(subType,index2) in type.child" :key="index2" @click="chooseNavItem(subType)">
<view class="content">
<text>{{subType.goodsCategoryName}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
name: 'vertical-nav',
props: {
list: {
type: Array,
default: []
},
containerHeight: {
type: String,
default: '100vh'
},
isClick2ShowProducts: {
type: Boolean,
default: false
}
},
data() {
return {
// list: [],
childrenList: [],
tabCur: 0,
mainCur: 0,
load: true,
verticalNavTop: 0,
curNavItem: {}
}
},
onReady() {
this.loadData();
},
// onLoad() {
// this.loadData();
// },
methods: {
loadData() {
// this.list = await this.$api.data('categoryList');
this.tabCur = this.list[0].goodsCategoryId;
for (let i = 0; i < this.list.length; i++) {
let children = this.list[i].child;
if (children && children.length > 0) {
for (let j = 0; j < children.length; j++) {
children[j].pIndex = i;
// children[j].pId = this.list[i].id;
}
this.childrenList = this.childrenList.concat(children);
}
}
},
tabSelect(e) {
this.tabCur = e.currentTarget.dataset.id;
this.mainCur = e.currentTarget.dataset.mainCur;
this.verticalNavTop = (e.currentTarget.dataset.index - 1) * 50;
},
verticalMain(e) {
// #ifdef MP-ALIPAY
return false //支付宝小程序暂时不支持双向联动
// #endif
let that = this;
let tabHeight = 0;
if (this.load) {
for (let i = 0; i < this.childrenList.length; i++) {
let view = uni.createSelectorQuery().select("#main-" + this.childrenList[i].goodsCategoryId);
view.fields({
size: true
}, data => {
this.childrenList[i].top = tabHeight;
tabHeight = tabHeight + data.height;
this.childrenList[i].bottom = tabHeight;
}).exec();
}
this.load = false
}
let scrollTop = e.detail.scrollTop + 10;
for (let i = 0; i < this.childrenList.length; i++) {
if (scrollTop > this.childrenList[i].top && scrollTop < this.childrenList[i].bottom) {
this.verticalNavTop = (this.childrenList[i].pIndex - 1) * 50
this.tabCur = this.childrenList[i].parentCategoryId;
console.log(scrollTop + ";tabCur=" + this.tabCur)
return false
}
}
},
chooseNavItem(curNavItem) {
this.curNavItem = curNavItem;
uni.$emit(this.$globalFun.VERTICAL_NAV_GET_ITEM, curNavItem);
},
searchGoods(e) {
uni.$emit(this.$globalFun.VERTICAL_NAV_SEARCH, e.detail.value);
}
}
}
</script>
<style scoped>
/* .fixed {
position: fixed;
z-index: 99;
} */
.VerticalNav.nav {
width: 200upx;
white-space: initial;
}
.VerticalNav.nav .cu-item {
width: 100%;
text-align: center;
background-color: #fff;
margin: 0;
border: none;
height: 50px;
position: relative;
}
.VerticalNav.nav .cu-item.cur {
background-color: #f1f1f1;
}
.VerticalNav.nav .cu-item.cur::after {
content: "";
width: 8upx;
height: 30upx;
border-radius: 10upx 0 0 10upx;
position: absolute;
background-color: currentColor;
top: 0;
right: 0upx;
bottom: 0;
margin: auto;
}
.VerticalBox {
display: flex;
}
.VerticalMain {
background-color: #f1f1f1;
flex: 1;
}
.cu-list>.cu-item {
transition: all 0.2s ease-in-out 0s;
-webkit-transform: translateX(0.5px);
transform: translateX(0rpx);
}
.cu-list.menu-avatar>.cu-item:after, .cu-list.menu>.cu-item:after {
border: none;
}
.cu-list>.cu-item:last-child:after, .cu-list.menu>.cu-item:last-child:after {
border: none;
}
.bottom-border {
border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
}
</style>