0
点赞
收藏
分享

微信扫一扫

ThingsBoard 开源物联网平台

首先,我们需要理清楚什么是一级分类,上一篇文章中,我们已经请求后台接口拿到了导航栏中不同商品分类相关的数据,那么,我们怎样编写代码来实现这样一个效果呢?当我们点击不同分类的时候,首页会渲染出该分类下的所有商品?在这里,就需要我们配置一级分类的路由,当我们点击每个分类的时候,拿到这个分类对应的id,然后携带着去向后台发起数据请求,然后在底下渲染出来。

详细步骤如下:

(1)配置占位符

{
          path: 'category/:id',
          component: Category
        },

(2)点击跳转

 <RouterLink active-class="active" :to="`/category/${item.id}`">
        {{ item.name }}
      </RouterLink>

2、一级分类-面包屑导航渲染

先来看下效果:在导航栏中,当我们点击某个商品分类的时候,例如,在这里点了“居家”

在底下会弹出这样一个效果,可以让用户看着更加舒服,

其实这个呢,就是面包屑,接下来,一起看看怎么实现吧?

首先,我们需要知道这个数据来自哪里?很显然是后端接口传过来的数据。那么,首先,我们就需要封装接口,去向后台请求这个数据。

(1)封装接口

export function getCategoryAPI (id) {
  return request({
    url: '/category',
    params: {
      id
    }
  })
}

(2)调用接口返回数据:

<script setup>
import { getCategoryAPI } from '@/apis/category'
import { tryOnMounted } from '@vueuse/core';
import { ref } from 'vue'
import {useRoute } from 'vue-router'
const route = useRoute()
const categoryData = ref([])
const getCategory = async () => {
  const res = await getCategoryAPI(route.params.id)
  categoryData.value = res.result
  console.log(res)
}
tryOnMounted(()=>getCategory())

</script>

浏览器返回:

(3)模板渲染

3、一级分类-轮播图功能实现

通过观察整个项目,我们发现,一级分类下的轮播图和首页的轮播图结构是一模一样的,只是调用的接口不同,在这里,很显然,我们可以把之前首页的轮播图相关的逻辑代码直接拿过来复用,只需要修改一下参数即可。

(1)改造接口(apis/home.js)


export function getBannerAPI (params = {}) {
  // 轮播图数据,1为首页, 2为商品分类页,默认为1
  const { distributionSite = '1' } = params
  return httpInstance({
    url: '/home/banner',
    params: {
      distributionSite
    }
  })
}

(2)HomeBanner中获取数据

<script setup>
import { getBannerAPI } from '@/apis/home'
import { onMounted, ref } from 'vue'

const bannerList = ref([])

const getBanner = async () => {
  const res = await getBannerAPI()
  console.log(res)
  bannerList.value = res.result
}

onMounted(() => getBanner())

</script>

查看接口是否发送成功:这里的接口是1

根据后台数据要求,更改参数设置,“2”为商品分类页

修改代码,这里的接口变成了2

把首页轮播图的相关代码拿过来:

<template>
  <div class="home-banner">
    <el-carousel height="500px">
      <el-carousel-item v-for="item in bannerList" :key="item.id">
        <img :src="item.imgUrl" alt="">
      </el-carousel-item>
    </el-carousel>
  </div>
</template>

样式代码也拿过来:

<style scoped lang='scss'>
.home-banner {
  width: 1240px;
  height: 500px;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 98;

  img {
    width: 100%;
    height: 500px;
  }
}
</style>

保存之后,查看运行结果:

4、一级分类-激活状态控制和分类列表渲染

(1)激活状态显示:

直接添加类名即可

active-class="active"

(2)分类列表渲染

1)Category/index.vue中轮播图下面添加如下静态代码:

<div class="sub-list">
        <h3>全部分类</h3>
        <ul>
          <li v-for="i in categoryData.children" :key="i.id">
            <RouterLink :to="`/category/sub/${i.id}`">
              <img :src="i.picture" />
              <p>{{ i.name }}</p>
            </RouterLink>
          </li>
        </ul>
      </div>
      <div class="ref-goods" v-for="item in categoryData.children" :key="item.id">
        <div class="head">
          <h3>- {{ item.name }}-</h3>
        </div>
        <div class="body">
          <GoodsItem v-for="good in item.goods" :goods="good" :key="good.id" />
        </div>
      </div>

2)V-for遍历已有数据

 <div class="ref-goods" v-for="item in categoryData.children" :key="item.id">
        <div class="head">
          <h3>- {{ item.name }}-</h3>
        </div>
        <div class="body">
          <GoodsItem v-for="good in item.goods" :goods="good" :key="good.id" />
        </div>
      </div>

3)由于这里每个商品分类下的模块使用到了GoodsItem中的模板,所以需要将其引入。

import GoodsItem from '../Home/components/GoodsItem.vue'

5、一级分类-路由缓存问题解决

首先,来看看什么是路由缓存问题?为什么会出现这个问题?

由于路由在只有参数变化时,会复用组件实例,会导致生命周期函数不执行,这个问题体现在哪里呢?当我们从导航栏中的某一个商品分类切换到下一个分类的时候,我们可以看到这样一个问题:浏览器地址栏的数据确实在发生变化,导航栏中的下一个商品分类也确实被激活了,但是分类下的数据根本就没有发生变化,这样,很显然是不行的,那么,我们怎样去解决这个问题呢?既然是组件实例被复用了,那么,我们就寻思让组件实例不再复用。很显然,这种方法是可行的,来看一下实现过程。

 <!-- 添加key,破坏复用机制,强制销毁重建 -->
  
  <RouterView :key="$route.fullPath"/>

但是,这种方法虽然简单粗暴,设置之后,组件实例确实不复用了,但是,它也存在一个很严重的问题。

它把整个实例都销毁重建了。在浏览器我们看到这个效果(看最上面两行)

每次点击都会请求这两个接口

而在项目中,每个分类下面的轮播图是一样的,不需要重新请求数据,所以,这种方法仍然存在资源的浪费,那么,还有没有其它的办法呢?肯定是有的,只要思想不滑坡,办法总比困难多。beforeRouteUpdate这个导航钩子它提供了一种解决方案,它可以用来监听路由参数的变化,当路由参数发生变化时,重新向后台发送接口请求。

详细步骤如下:

(1)Category/index.vue

运行结果演示:

这样,当切换路由的时候,接口只有一个了。

6、一级分类-使用逻辑函数拆分业务

在代码实现之前,需要考虑以下三个问题:

什么是使用逻辑函数拆分业务?

为什么要使用逻辑函数来对业务进行拆分?

怎么拆分?

在项目开发中,我们会遇到这样一个问题。有一些独立的业务代码,为了方便后去维护它们,我们需要将其拆分出来,封装成一个独立的函数,后面需要维护哪一块代码,直接找到对应的函数来进行维护即可,这样做,可以答复提升工作效率。

实现步骤如下:

1)逻辑封装时一个拆分再组合的过程,函数以use打头,内部封装逻辑。

2)把index.vue中与banner和category相关的逻辑分别拆分出去放到Usebanner.js和useCategory.js中,注意最后要return出去

Usebanner.js

import { ref , onMounted} from 'vue'
import { getBannerAPI } from '@/apis/home'
export function useBanner() {
  const bannerList = ref([])
const getBanner = async () => {
  const res = await getBannerAPI({
    distributionSite : '2'
  })
  
  console.log(res)
  bannerList.value = res.result
}
onMounted(() => {
  getBanner()
})
return {
  bannerList
}
}

useCategory.js

import { ref,onMounted } from 'vue'
import { getCategoryAPI } from '@/apis/category'
import { onBeforeRouteUpdate  } from 'vue-router'
import {useRoute } from 'vue-router'
const route = useRoute()
export function useCategory() {
const categoryData = ref([])
const getCategory = async (id= route.params.id) => {
  const res = await getCategoryAPI(id)
  categoryData.value = res.result
  console.log(res)
}
onMounted(()=>getCategory())
//路由参数变化的时候,可以把分类数据接口重新发送
onBeforeRouteUpdate((to)=> {
  console.log('路由变化了')
  //存在的问题,使用最新的路由参数获取最新的分类数据
  console.log(to)
  getCategory(to.params.id)

})
return {
  categoryData
}

}

3)在index.vue中导入解构使用

举报

相关推荐

0 条评论