前端Vue项目:旅游App-city:固定tab栏内容中显示数据
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端Vue项目:旅游App-city:固定tab栏内容中显示数据相关的知识,希望对你有一定的参考价值。
文章目录
目标
上一篇获取了服务器中的数据:【前端】Vue项目:旅游App-(8)city:标签页Tabs动态数据:网络请求axios与request、数据管理store与pinia、各种封装
本篇目标:显示这些数据。
效果如下:(把两张图拼在一起了)
过程与代码
Tab一直显示的两种方法
我们把city.vue划分为两部分,top和content。
top部分是要一直显示的搜索框和tab栏,content部分是要显示的数据内容。
下面介绍两种一直显示top的方法。
方法1:fixed定位
我们可以把top栏定位为fixed,让它固定在屏幕的上面。
css:
.top
position: fixed;
top: 0;
left: 0;
right: 0;
写一点内容:
<div class="content">
<template v-for="item in 100">
<div> item </div>
</template>
</div>
效果:
显然出现了问题:1-7的部分会被遮盖住。
我们令content从top下面开始:
.content
margin-top: 98px;
效果:好。
方法2:设置height和overflow-y(效果不好)
直接设置content的height,并令overflow-y为auto,则会在content部分自动产生滚动条。
.content
height: calc(100vh-98px);
overflow-y: auto;
效果:竟然出现了两个滚动条,还有一个穿到了Tab栏。这个效果不好,我们不用它。我们只需知道可以有这两种方法即可。(在一些情况下这种方法比上种方法好,视情况而定)
content显示数据
我们先观察一下数据的结构:
data分为cityGroup和cityGroupOverSea,分别表示国内数据和国外数据,正好对应两个Tab的content显示。这两个对象的结构是相似的。
以cityGroup为例,它是一个对象。我们要显示的数据是cities。
因此,想要拿到数据,我们要用key去找到它们。
我们观察之前写的代码,我们v-model绑定了一个属性TabActive:
<van-tabs v-model:active="TabActive">
<template v-for="(value, key, index) in allCity">
<van-tab :title="value.title"></van-tab>
</template>
</van-tabs>
根据vant文档,它绑定的是索引值:
然而,我们要显示的数据是对象的属性,用索引去找数据是很不方便的,我们要想办法获取key。
根据文档,有这样一个方法:
代码:动态绑定属性name,则双向绑定的TabActive属性的值是name,这里我们传入的是key。
<van-tabs v-model:active="TabActive">
<template v-for="(value, key, index) in allCity">
<van-tab :title="value.title" :name="key"></van-tab>
</template>
</van-tabs>
F12,找到vue插件验证一下:确实如此。
content:
<div class="content">
<template v-for="item in allCity[TabActive].cities">
item
</template>
</div>
效果:
写到这里我们要思考一下,万一有时候我们没有从服务器中拿到数据该怎么办?比如以下情况:
这时我们会想到ES6的语法可选链运算符:?.
在.之前是undefined时不会报错。
currentGroup :注意响应式
// currentGroup:当前选了哪个tab,是key值
// allCity和TabActive都是响应式,因此要用value取到值
// computed:依赖的东西改变则重新计算,相当于令currentGroup响应式,否则它是写死的(只算一次)
const currentGroup = computed(() => allCity.value[TabActive.value])
template:
<div class="content">
<template v-for="item in currentGroup?.cities">
item
</template>
</div>
效果:不报错。
ps:这样写刷新几次之后都能从服务器拿到数据了。好怪…,我以为会有可能拿不到的
效果
总代码
city.vue
<template>
<div class="city top-page">
<div class="top">
<!-- show-action:显示 “取消” -->
<van-search shape="round" v-model="value" show-action placeholder="城市/区域/位置" @search="onSearch"
@cancel="onCancel" />
<van-tabs v-model:active="TabActive">
<template v-for="(value, key, index) in allCity">
<van-tab :title="value.title" :name="key"></van-tab>
</template>
</van-tabs>
</div>
<div class="content">
<template v-for="item in currentGroup?.cities">
item
</template>
</div>
</div>
</template>
<script setup>
import computed, ref from 'vue';
import showToast from 'vant';
import useCityStore from '@/store/modules/city'
import storeToRefs from 'pinia';
const value = ref('');
const TabActive = ref(0);
const onSearch = (val) => showToast(val);
const onCancel = () =>
showToast('取消');
// tabs的数据
const cityStore = useCityStore()
cityStore.fetchAllCity()
// cityStore是响应式的
const allCity = storeToRefs(cityStore)
// console.log(allCity)
// currentGroup:当前选了哪个tab,是key值
// allCity和TabActive都是响应式,因此要用value取到值
// computed:依赖的东西改变则重新计算,相当于令currentGroup响应式,否则它是写死的(只算一次)
const currentGroup = computed(() => allCity.value[TabActive.value])
</script>
<style lang="less" scoped>
.top
position: fixed;
top: 0;
left: 0;
right: 0;
.content
margin-top: 98px;
</style>
相关参考
以上是关于前端Vue项目:旅游App-city:固定tab栏内容中显示数据的主要内容,如果未能解决你的问题,请参考以下文章
前端Vue项目:旅游App-city:搜索框search和标签页Tabs
前端Vue项目:旅游App-city:隐藏TabBar的2种方法
前端Vue项目:旅游App-(10)city:以indexBar的形式显示数据
前端Vue项目:旅游App-(17)home:页面滚动显示搜索栏节流时间同步