【Vue3从零开始-实战】S14:详情页回退事件及路由参数的传递获取数据

1,983 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

前言

实战已经开始了!上一篇已经将详情页的店铺信息展示出来了,但是顶部还有一个搜索框和返回按钮,而且详情页的店铺数据是在页面中固定写死的,所以本章节会将顶部搜索栏进行布局,并且通过返回按钮可以回到首页。其次会通过路由传参的方式,从首页跳转到详情页,并动态获取详情页店铺数据。

搜索框布局

image.png

🌀 根据稿图,我们发现搜索框部分只有一个input输入框和一个返回按钮,比较简单,所以下面就直接贴代码了,有兴趣的朋友可以自己设计的哦。

👉 DOM元素

<div class="search">
  <div class="search__back iconfont">&#xe6f2;</div>
  <div class="search__content">
    <span class="search__content__icon iconfont">&#xe62d;</span>
    <input class="search__content__input" placeholder="请输入商品名称" />
  </div>
</div>

👉 样式

.search {
  display: flex;
  margin: .2rem 0 .16rem 0;
  line-height: .32rem;
  &__back {
    width: .3rem;
    font-size: .24rem;
    color: #B6B6B6;
  }
  &__content {
    display: flex;
    flex: 1;
    background: #F5F5F5;
    border-radius: .16rem;
    &__icon {
      width: .44rem;
      text-align: center;
      color: #B7B7B7;
    }
    &__input {
      display: block;
      width: 100%;
      padding-right: .2rem;
      border: none;
      outline: none;
      background: none;
      height: .32rem;
      font-size: .14rem;
      color: #333;
      &::placeholder {
        color: #333;
      }
    }
  }
}

image.png

router-link标签实现跳转

🌀 页面跳转之前在首页和登录注册页面之间都有写过,但是用的点击事件去跳转的,这次我们就用以前学过但没有实际用过的router-link标签实现

<router-link to="/shop" v-for="item in nearbyList" :key="item.id">
    <ShopItem :item="item" />
</router-link>
  • 将Nearby.vue中的子组件标签用router-link标签包裹起来。
  • 由于列表页上的每一条数据都得点击跳转,所以需要将循环事件放在router-link标签上。
  • router-link标签还会接收一个参数 to ,它表示需要跳转到哪个路由(对应路由配置页中的path)

Kapture 2022-06-24 at 22.27.04.gif

  • 在浏览器中可以看到多了几个 a 标签包裹着列表中的元素
  • 由于 a 标签的默认样式,所以列表页上有下划线。

👉 去掉a标签的下划线

a{
    text-decoration: none;
}

image.png

router.back函数回退

router.back函数是vue-router插件提供的一个回退事件方法。

👉 给详情页顶部栏中的返回按钮一个点击事件

<div class="search__back iconfont" @click="handleBackClick">&#xe6f2;</div>

👉 引入所需的路由插件

import { useRouter } from 'vue-router'

👉 在setup函数中定义路由,并调用回退事件的方法

const router = useRouter()
const handleBackClick = () => {
  router.back()
}

chrome-capture (1).gif

店铺信息动态数据

🌀 详情页中的店铺信息是固定的数据,在实际项目中我们应该通过接口请求获取到对应的店铺信息,所以就需要根据首页列表的店铺ID来请求接口获取到对应的店铺数据了。

mock接口

👉 打开mock接口后台,新增店铺详情接口

image.png

👉 在详情页中通过get请求接口

  • 引入get请求
import { get } from '../../utils/request'
  • 进入页面就需要直接请求接口
const data = reactive({ item: {} })
const getItemData = async () => {
  const result = await get('/api/shop/1')
  if (result.data.code === 0 && result.data.data) {
    data.item = result.data.data
  }
}
getItemData()
const { item } = toRefs(data)

👉 为了看到效果,需要将setup函数里面原来写死的数据删除

image.png

Kapture 2022-06-25 at 14.35.09.gif

  • 在接口请求的时候动态传递了一个id,也就是接口url后面的/:id

😲 在实际项目中,id是通过列表传递过去的,然后去请求接口,也就是需要将id动态化。

动态路由传参

🌀 在接口后面可以添加/:id的方式获取动态参数,其实在路由中也可以通过这种方式获取到动态参数。

👉 打开路由配置文件,并重新配置详情页路由,在路由后面添加/:id

{
    path: '/shop/:id',
    name: 'Shop',
    component: () => import(/* webpackChunkName: "shop" */ '../views/shop/Shop')
}

👉 首页列表中点击跳转时,就需要通过v-bind指令动态绑定参数

<router-link :to="`/shop/${item.id}`" v-for="item in nearbyList" :key="item.id">
    <ShopItem :item="item" />
</router-link>
  • router-link标签中的to就是动态跳转路径,里面绑定了当前循环的店铺id

Kapture 2022-06-25 at 14.51.15.gif

  • 在浏览器地址栏中可以发现,当我们点击列表中的店铺时,地址栏的URL后面就会动态添加当前点击的店铺ID

😲 但是接口请求的时候,需要获取到地址栏的店铺id才能让接口后面的参数也变成动态的。

route获取路由参数

👉 在详情页中引入useRoute

import { useRouter, useRoute } from 'vue-router'

👉 为了知道useRoute是干啥的,我们需要在setup函数中调用useRoute方法,并打印出来看看

const route = useRoute()
console.log(route)

image.png

useRoute函数是vue-router提供的一个用来获取路由配置项的方法,里面有配置项中的name、path、params等。

  • name:配置项中路由的名称。
  • params:路由项中传递的参数
  • path:路由项中跳转的路径

🔆 通过打印出来之后发现,可以通过useRoute函数中的params获取到店铺id

👉 修改接口传递参数的方式,将静态参数改为动态参数

const result = await get(`/api/shop/${route.params.id}`)

Kapture 2022-06-25 at 15.06.55.gif

由于是模拟接口数据,所以每次请求的ID虽然变了,但是接口数据还是固定的。

拆分详情页setup函数

🌀 不管是在首页,亦或是登录注册页面,我们都去拆分过setup函数中的逻辑,也在前面的文章中说明过setup函数的职责。

🔆 下面就直接拆分了,也会按照前面文章中的拆分方式。

<script>
import { reactive, toRefs } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { get } from '../../utils/request'
import ShopItem from '../../components/shopItem'

// 获取当前店铺信息
const useShopInfoEffect = () => {
  const route = useRoute()
  const data = reactive({ item: {} })
  const getItemData = async () => {
    const result = await get(`/api/shop/${route.params.id}`)
    if (result.data.code === 0 && result.data.data) {
      data.item = result.data.data
    }
  }
  const { item } = toRefs(data)
  return { item, getItemData }
}

// 点击回退逻辑
const useBackRouterEffect = () => {
  const router = useRouter()
  const handleBackClick = () => {
    router.back()
  }
  return handleBackClick
}

export default {
  name: 'Shop',
  components: {
    ShopItem
  },
  setup () {
    const { item, getItemData } = useShopInfoEffect()
    const handleBackClick = useBackRouterEffect()
    getItemData()
    return { item, handleBackClick }
  }
}
</script>

总结

本篇文章主要讲解了路由中的回退事件和动态传参的方式,并在接口请求中获取到路由传递的参数。