效果
需求
我们这个页面顶部有tabs 栏 而且可以滑动到底部 进行分页
实现这样的页面我们应该怎么做 你应该会想到scroll-view 这个组件吧
下面我们来详情介绍一下这个页面的实现和功能开发
首先展示一下代码
item 循环项
<template><div class="wechat-order-item-container"><div class="box"><div class="header"><div class="cinema-name">金逸影城(安庆星光荟店)</div><div class="status">订单超时</div></div><div class="content"><div class="movie-img"><imagesrc="https://gw.alicdn.com/tfscom/i3/O1CN01s4djbH29FutyK4fzY_!!6000000008039-0-alipicbeacon.jpg_300x300.jpg"style="width: 90px; border-radius: 5px"mode="widthFix"></image></div><div class="movie-data"><div class="name marginTop">我们一起摇太阳</div><div class="time marginTop">2024-04-15 21:30:00</div><div class="hall marginTop color858a99">4号激光厅</div><div class="address marginTop color858a99">宜秀区独秀大道安庆星光荟第四层</div><div class="seat marginTop color858a99">4排六座</div></div><div class="right"><div class="city">安庆市</div><div class="num">共1张</div><div class="price">¥45.00</div></div></div><div class="footer"><div class="timer">创建时间:2024-04-15 17:34</div><div class="btn"><nut-buttonplaintype="default"size="small"style="border: 1px solid #eee">订单详情</nut-button></div></div></div></div>
</template>
<script setup></script>
<style lang="scss">
.wechat-order-item-container {background-color: #fff;padding: 20px 25px;font-size: 26px;border-radius: 15px;.box {.header {color: #858a99;padding-bottom: 20px;display: flex;align-items: center;justify-content: space-between;border-bottom: 1px solid #f7f8f9;.cinema-name {}.status {font-size: 24px;}}.content {padding: 20px 0;border-bottom: 1px solid #f7f8f9;display: flex;.right {flex: 1;margin-left: 20px;display: flex;flex-direction: column;align-items: center;.city {color: #15181d;font-weight: 700;}.num {}.price {color: #028fd4;}}.movie-data {margin-left: 20px;.marginTop {margin-top: 5px;}.color858a99 {color: #858a99;}.name {font-size: 26px;color: #15181d;font-weight: 700;}.time {color: #028fd4;}}}.footer {margin-top: 15px;display: flex;justify-content: space-between;align-items: center;.timer {color: #858a99;font-size: 24px;}}}
}
</style>
这个算是 每一个item的代码 我把他封装成了一个组件
tabs 栏
<template><div class="filter-container"><nut-tabs v-model="selected" title-scroll type="smile" title-gutter="10"><nut-tab-pane v-for="item in tabList" :title="item.name"></nut-tab-pane></nut-tabs></div>
</template>
<script setup>
import { ref, watch, toRefs } from "vue";
const props = defineProps({tabList: Array,
});
const emit = defineEmits(["onChange"]);
const { tabList } = toRefs(props);
const selected = ref(0);//监听当前的tabs选中 变化出发自定一函数 子传父组件数据
watch(selected, (index) => {emit("onChange", tabList.value[index]);
});
</script>
<style lang="less">
.filter-container {.nut-tabs__content {display: none !important;}.nut-tabs__list {background-color: #fff;}.nut-tabs__titles {// background: #ffffff !important;.nut-tabs__titles-item {.nut-tabs__titles-item__smile {display: none;}.nut-tabs__titles-item__text {color: #858a99;font-size: 24px;}.nut-tabs__titles-item__line {background: linear-gradient(to right, #028fd4, #028fd6) !important;}.nut-tabs__titles-item__smile .nut-icon {color: #028fd4 !important;}}.nut-tabs__titles-item.active {.nut-tabs__titles-item__smile {display: block;margin-top: 10px !important;}.nut-tabs__titles-item__text {color: #15181d;}}}
}
</style>
我也把他封装成了一个组件 都是经过二次封装的
这个做法 巧妙的将每一项的item 的上下距离页拉开了
<template><div class="wechat-order-container"><Tabbar></Tabbar><div class="wechat-list" :style="{ marginTop: `${tabbarHeight}` + 'px' }"><Filter :tab-list="tabList" @onChange="handleClickTabs"></Filter><divclass="flex-list":style="{ height: `${listContainerHeight}` + 'px' }"><templatev-if="list.length > 0 && listContainerHeight > 0":style="{ height: `${listContainerHeight}px` }"><scroll-view:scroll-y="true"scrollAnchoring@scrolltolower="onScrollBottom":scroll-top="scrollTop":style="{ height: `${listContainerHeight}` + 'px' }"><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><div class="flex-item"><Item></Item></div><!-- <Loading:page="pageinfo.currentPage":total="totalpage":loadingFlag="loadingFlag":tipFlag="tipFlag"></Loading> --></scroll-view></template><template v-else><nut-empty description="无数据"></nut-empty></template></div></div></div>
</template>
<script>
import { needLogin } from "../../../utils/needLoginHook";
export default {mixins: [needLogin],
};
</script>
<script setup>
import { onMounted, ref, computed } from "vue";
import Taro, { useDidShow } from "@tarojs/taro";
import { storeToRefs } from "pinia";
import Tabbar from "../../../components/wx-tabbar/index.vue";
import Filter from "./filter.vue";
import { useTabbarStore } from "../../../store";
import Item from "./item.vue";
const tabbarStore = useTabbarStore();
const { selected, tabbarHeight } = storeToRefs(tabbarStore);
onMounted(() => {tabbarStore.setSelected(1);
});
useDidShow(() => {getListContainerHeight();
});
const list = ref([1, 2, 3]);
const scrollTop = ref(0);
const listContainerHeight = ref(0);
const tabList = ref([{id: 0,name: "全部",},{id: 1,name: "已创建",},{id: 2,name: "已支付",},{id: 3,name: "已出票",},{id: 4,name: "已退票",},
]);
//计算当前页面的高度
const getListContainerHeight = () => {const query = Taro.createSelectorQuery().select(".flex-list").boundingClientRect();query.selectViewport();query.exec(function (res) {if (res[0]) {listContainerHeight.value = res[0].height;}});
};
//滑动到底部的执行方法
const onScrollBottom = () => {console.log("到底了");
};
const handleClickTabs = () => {};
</script>
<style lang="scss">
.wechat-order-container {height: 100%;.wechat-list {position: fixed;left: 0;right: 0;bottom: 0;top: 0;display: flex;flex-direction: column;.flex-list {flex: 1;.flex-item {padding: 10px 20px;}}}
}
</style>
主页面的代码
详细介绍
scroll-view 是需要 高度的 这个高度 就是外面盒子的高度
高度计算
const getListContainerHeight = () => {const query = Taro.createSelectorQuery().select(".flex-list").boundingClientRect();query.selectViewport();query.exec(function (res) {if (res[0]) {listContainerHeight.value = res[0].height;}});
};
这个外面的盒子需要去计算 我们计算scroll-view 的高度是和父组件的高度一致得
最后一个注意点
.wechat-list 这个盒子 是需要我们将他变为fixed 的定位 相当于操作就是 属于wechat-list 的了 摆脱了 最外面的大盒子的滑动