【Vue3从零开始-实战】S13:列表和详情页的异步路由与组件拆分复用

简介: 【Vue3从零开始-实战】S13:列表和详情页的异步路由与组件拆分复用

@@DVBVTGC2D7ROIYF4YK_@O.png


前言


实战已经开始了!上一篇文章将首页中的店铺列表数据动态化了,也是为了详情页而做准备的,从本章节起就要开始做详情页了,但是随着页面路由越来越多,在做详情页之前,需要将路由变为异步加载。其次首页列表和详情页顶部部分是一样的,所以将其组件化。


详情页路由 - 异步路由


🌀 既然要做详情页了,就得先创建页面,在配置路由。


K5I3~~E)R0P_$8W[Q$WSE]T.png


  • 在views目录下新建shop文件夹 - Shop.vue文件


  • 内容可以是默认的空模板


  • 在router配置文件中,引入shop页面,并配置shop路由。


import Shop from '../views/shop/Shop'
复制代码
{
    path: '/shop',
    name: 'Shop',
    component: Shop
}
复制代码


😫 目前路由配置中已经有四个路由配置了,在加载首页的时候,也会将其他暂时不需要加载的页面配置一起加载进来,这样其实是没必要的,所以需要将路由配置成异步的。


😲 以前的文章中,一起学习过异步路由配置,下面就简单回顾一下


👉 首先将首页和登录页配置异步路由,看看页面加载时的效果


{
    path: '/',
    name: 'Home',
    component: () => import(/* webpackChunkName: "home" */ '../views/home/Home')
},{
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "login" */ '../views/login/Login'),
    beforeEnter (to, from, next) {
      const { isLogin } = localStorage
      isLogin ? next({ name: 'Home' }) : next()
    }
}
复制代码


  • component中是一个回调函数,通过import实现异步加载路由。


  • webpackChunkName是异步加载路由时,打包的js名称。


(~RD~TI~X)0Y1_BWT%DE}7A.png


  • 通过页面加载可以看出,进入首页时会单独加载首页配置路由,进入登录页时也会单独加载登录页的路由,但是进入注册页的时候,不会单独加载注册页的路由,那是因为注册页的路由在另外一个公共js里面加载出来的。


🔆 根据上面的方式,将所有路由配置都改成异步路由。


import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import(/* webpackChunkName: "home" */ '../views/home/Home')
  }, {
    path: '/shop',
    name: 'Shop',
    component: () => import(/* webpackChunkName: "shop" */ '../views/shop/Shop')
  }, {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "login" */ '../views/login/Login'),
    beforeEnter (to, from, next) {
      const { isLogin } = localStorage
      isLogin ? next({ name: 'Home' }) : next()
    }
  },
  {
    path: '/register',
    name: 'Register',
    component: () => import(/* webpackChunkName: "register" */ '../views/register/Register'),
    beforeEnter (to, from, next) {
      const { isLogin } = localStorage
      isLogin ? next({ name: 'Home' }) : next()
    }
  }
]
复制代码


  • 因为是异步加载路由,所以顶部不需要引入路由文件了,只需要在component中异步引入路由即可。


拆分列表组件

II)%%R{~81BA%((E~VMGIRM.png


🌀 通过对比稿图,我们发现列表页和详情页的部分内容是一致的,可以将其拆分出来单独维护。


👉 在components文件夹下新建shopItem组件


2{VI@)1]C3CO~$R5GSUQSB2.png


👉 将首页中循环列表里面的内容和样式复制到shopItem组件中


<template>
  <div class="shop">
    <img :src="item.imgUrl" class="shop__img">
    <div class="shop__content">
      <div class="shop__content__title">{{item.name}}</div>
      <div class="shop__content__tags">
        <span class="shop__content__tag">月售:{{item.sales}}</span>
        <span class="shop__content__tag">起送:{{item.expressLimit}}</span>
        <span class="shop__content__tag">基础运费:{{item.expressPrice}}</span>
      </div>
      <p class="shop__content__highlight">{{item.slogan}}</p>
    </div>
  </div>
</template>
复制代码
<style lang="scss" scoped>
@import "../style/viriables.scss";
.shop {
  display: flex;
  padding-top: 0.12rem;
  &__img {
    margin-right: 0.16rem;
    width: 0.56rem;
    height: 0.56rem;
  }
  &__content {
    flex: 1;
    padding-bottom: 0.12rem;
    border-bottom: 1px solid #f1f1f1;
    &__title {
      line-height: 0.22rem;
      font-size: 0.16rem;
      color: $content-font-color;
    }
    &__tags {
      margin-top: 0.08rem;
      line-height: 0.18rem;
      font-size: 0.13rem;
      color: $content-font-color;
    }
    &__tag {
      margin-right: 0.16rem;
    }
    &__highlight {
      margin: 0.08rem 0 0 0;
      line-height: 0.18rem;
      font-size: 0.13rem;
      color: #e93b3b;
    }
  }
}
</style>
复制代码


  • 需要注意的是公共样式也要引入进来。


  • 为了符合当前页面的内容,所以将样式名称统一成一样的前缀。


👉 首页引入子组件


import ShopItem from '../../components/shopItem'
复制代码


👉 通过components定义组件


components: {
    ShopItem
}
复制代码


👉 循环展示子组件,并传递循环内容给子组件


<ShopItem v-for="item in nearbyList" :key="item.id" :item="item" />
复制代码


  • 循环的时候还是使用id作为key值,并将循环的item通过v-bind指令传递给子组件。


👉 子组件接收传递过来的值并渲染出来


<script>
export default {
  name: 'ShopItem',
  props: ['item']
}
</script>
复制代码


UKJJ(C(_1JVL(E_1J(TJUMK.png


详情页引入组件


G5Q~~$$DYMMAJAW[3DVF[A7.png


🌀 通过详情页稿图可以看出只有顶部一块内容是子组件,所以不需要进行循环,我们可以先定义静态数据渲染出来,后续在改成动态数据。


👉 详情页引入组件


import ShopItem from '../../components/shopItem'
复制代码


👉 通过components定义组件


components: {
    ShopItem
}
复制代码


👉 模板中使用子组件


<template>
  <div class="wrapper">
    <ShopItem :item="item" />
  </div>
</template>
复制代码


👉 setup函数中定义静态数据渲染


setup () {
    const item = {
      id: 1,
      name: '沃尔玛',
      imgUrl: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a8a16cef-f2b9-4644-b216-3b95bcb12602/e9e2929d-f491-489d-8fa5-bd6223e67b06.png',
      sales: 1000,
      expressLimit: 0,
      expressPrice: 5,
      slogan: 'VIP尊享满89元减4元运费券(每月3张)'
    }
    return { item }
  }
复制代码


(4W6VPE~O0AF$G$C1}DV6HK.png


  • 详情页中渲染子组件之后发现这里有一条线,是在首页用来分割列表的,详情页中是不需要的。


⭕️ 我们可以使用基础篇章中用过的动态样式来渲染这条线的显隐。


动态渲染样式


👉 在shopItem组件中接收一个参数:hideBorder


props: ['item', 'hideBorder']
复制代码


👉 将content中的border样式注释,并新增一个下级样式


~{R_39O6ABVNK48YY1Q_0`H.png


&--bordered {
  border-bottom: 1px solid #f1f1f1;
}
复制代码


  • 表示只有标识了bordered的样式名才显示底部边框线。


👉 将content样式通过动态绑定样式来显示


<div :class="{'shop__content': true, 'shop__content--bordered': hideBorder ? false : true}"></div>
复制代码


  • shop__content是原始样式名,所以直接设置为true。


  • shop__content--bordered是用来显示底部边框线的,通过hideBorder来判断显示隐藏。


👉 由于详情页不需要显示边框线,所以在详情页中给子组件传递hideBorder


<template>
  <div class="wrapper">
    <ShopItem :item="item" :hideBorder="true" />
  </div>
</template>
复制代码


V]6VA]MGBDI4DNE8LTEMYNA.png


👆 详情页的border就隐藏了。


4{E9VPVKRMOF4{3`K5~TA%B.png


👆 首页的列表就会多出一个bordered样式名用来显示边框线了。


总结


本篇文章主要是将路由配置中引用组件的时候变成异步引入的方式,并且将首页和详情页中公共的组件拆分出来复用,通过动态样式传递来显隐部分样式内容。

相关文章
|
29天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
129 64
|
3天前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
22 3
|
29天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
33 8
|
28天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
30 1
|
28天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
38 1
|
1月前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
8天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
1月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
43 1
vue学习第一章
|
1月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
30 1
|
1月前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
38 1
vue学习第四章

热门文章

最新文章