前端Vue项目:旅游App-(10)city:以indexBar的形式显示数据

Posted karshey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端Vue项目:旅游App-(10)city:以indexBar的形式显示数据相关的知识,希望对你有一定的参考价值。

文章目录

目标

上一篇显示了服务器中的数据:【前端】Vue项目:旅游App-(9)city:固定tab栏、内容中显示数据

本篇目标:将数据展示成这个效果。

过程与代码

分析数据并展示

首先我们要分析要展示的数据。以国内数据为例:

数据分为citieshotcitiestitle。我们这里要展示的是cities

cities详情:是一个数组,里面的每一个元素都是一个对象。
每个对象有两个属性:

  • group:表示以本字母开头
  • cities:一个数组,表示以group开头的所有城市

这就是我们要展示的数据。显然需要两层循环。



代码:

<div class="content">
  <template v-for="(item,index) in currentGroup?.cities" :key="index">
      <h2 class="title">
          标题 item.group 
      </h2>
      <div class="cities">
          <template v-for="(itemm,indexx) in item.cities" :key="indexx">
              <div class="cityName">
                   itemm.cityName 
              </div>
          </template>
      </div>
  </template>
</div>

效果:

封装到一个组件

为了代码的可维护性,封装一下。

currentGroupCity.vue:

<template>
    <template v-for="(item, index) in currentGroup?.cities" :key="index">
        <h2 class="title">
            标题 item.group 
        </h2>
        <div class="cities">
            <template v-for="(itemm, indexx) in item.cities" :key="indexx">
                <div class="cityName">
                     itemm.cityName 
                </div>
            </template>
        </div>
    </template>
</template>

<script setup>
// 定义数据currentGroup:一个对象
defineProps(
    currentGroup: 
        type: Object,
        default: () => ()
    
)
</script>

<style lang="less" scoped>
h2
    font-size: 20px;
    font-weight: 700;

</style>

city.vue把数据传一下:

<div class="content">
   <currentGroupCity :current-group="currentGroup"/>
</div>

添加indexBar

数据已经展示好了,我们还要添加样式。要添加的样式叫做:IndexBar 索引栏 - Vant 4 (gitee.io)

注册好后,根据indexBar的代码进行修改。


代码:

<template>
    <van-index-bar>
        <template v-for="(item, index) in currentGroup?.cities" :key="index">
            <van-index-anchor :index="item.group" />
            <template v-for="(itemm, indexx) in item.cities" :key="indexx">
                <van-cell :title="itemm.cityName" />
            </template>
        </template>       
    </van-index-bar>
</template>

效果:


出了一些bug:

Failed to resolve component: van-cell
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

解决方法:【vue】Failed to resolve component: van-cell If this is a native custom element, make sure to exclude

效果:

样式修改

把颜色改成主题色橙色。具体步骤见之前的博客,不再赘述。

common.css的:root:

--van-primary-color:var(--primary-color) !important;

还有一件事:我们的滚轮往下滑的时候索引栏会被挡住:


给类top增加z-index:

.top 
    position: fixed;
    top: 0;
    left: 0;
    right: 0;

    // 不被indexBar挡住
    z-index: 9;

当然,让它被挡住也行,具体看产品的需求。这里只是写一下如果不让他被挡住的方法。

优化tab栏的切换

写到这里我们发现,每点一次tab栏的切换,数据就会重新加载。这样的效率其实是不高的。

我们可以这样做:把两份数据都写出来,用v-show显示对应的数据。就像前面对title所做的一样。

<div class="content">
    <template v-for="(value, key, index) in allCity">
        <currentGroupCity v-show="key===TabActive" :current-group="value" />
    </template>
</div>

切换的直观感受:快了一些。虽然数据上差别不大。

效果

总代码

修改或新增的文件

common.css

修改了样式:主题颜色。

:root 
    --van-primary-color:var(--primary-color) !important;

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="(value, key, index) in allCity">
                <currentGroupCity v-show="key===TabActive" :current-group="value" />
            </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';
import currentGroupCity from './cpns/currentGroupCity.vue';

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])

console.log(currentGroup)
</script>

<style lang="less" scoped>
.top 
    position: fixed;
    top: 0;
    left: 0;
    right: 0;

    // 不被indexBar挡住
    z-index: 9;


.content 
    margin-top: 98px;

</style>

currentGroupCity.vue

循环显示数据的组件。

<template>
    <van-index-bar>
        <template v-for="(item, index) in currentGroup?.cities" :key="index">
            <van-index-anchor :index="item.group" />
            <template v-for="(itemm, indexx) in item.cities" :key="indexx">
                <van-cell :title="itemm.cityName" />
            </template>
        </template>       
    </van-index-bar>
</template>

<script setup>
// 定义数据currentGroup:一个对象
defineProps(
    currentGroup: 
        type: Object,
        default: () => ()
    
)
</script>

<style lang="less" scoped>
h2 
    font-size: 20px;
    font-weight: 700;

</style>

main.js

引入组件。

以上是关于前端Vue项目:旅游App-(10)city:以indexBar的形式显示数据的主要内容,如果未能解决你的问题,请参考以下文章

前端Vue项目:旅游App-(11)city:添加热门数据动态修改索引栏点击跳转显示城市

前端Vue项目:旅游App-city:搜索框search和标签页Tabs

前端Vue项目:旅游App-city:固定tab栏内容中显示数据

前端Vue项目:旅游App-city:隐藏TabBar的2种方法

前端Vue项目:旅游App-city:标签页Tabs动态数据:网络请求axios与request数据管理store与pinia各种封装

前端Vue项目:旅游App-博客总结