手把手教你做小兔鲜网站(vue3实战)

背景:先学习前端基础(html、css、js、ajax、axios),学习vue2,学习vue3(响应式、计算属性、watch、生命周期hook、路由、pinia、组件通信........)

day1

先create vue,如图

 然后导包,打开脚手架,确保能跑起来

项目起步

1、然后用git工具进行管理,在vscode的terminal中输入

git init
git add .
git commit -m "init"

2、然后就完成了项目初始化和git管理。

3、然后进行ElementPlus自动按需导入配置(上官网查看):

4、然后进行axios基础配置,搭建一个基础的架子

 5、然后根据项目页面配置路由,创建一级路由:Layout和Login,二级路由:Home和Category...

6、然后进行静态资源引入和ErrorLen安装

7、然后在styles下新建var.scss,在config文件中自动导入,免去每次都要导入的麻烦

8、然后初始化阶段就完成了,开始做真正的项目

day2

Layout

1、Layout模块静态模板搭建

2、再然后引入阿里的字体图标库(font-class)

<link rel="stylesheet" href="//at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">

font-class地址已经给大家生成好了,复制粘贴到index.html即可

3下一步:使用后端接口渲染(render)一级导航

步骤:根据接口文档封装接口函数、发送请求获取数据列表、v-for渲染页面

4、下一步实现吸顶交互(向下滑动到一定值时,顶部导航在最上面不动)

步骤:准备导航组件基础结构、(用插件vueUse)获取滚动距离、用滚动距离做判断条件控制组件盒子展示隐藏

5、下一步:Pinia优化重复请求(两个导航列表是一致的,但是要发两次网络请求,浪费。使用Pinia集中式管理数据,再把数据给组件使用),如下图

 home页面

1、搭建一下home的大致结构

 2、实现home-整体结构拆分以及分类渲染

 3、下一步呢:实现home-banner轮播图实现(直接使用elementplus插件实现,然后拿数据渲染就ok了)

4、然后进行面板组件封装(解决复用问题:新鲜好物和人气推荐模块结构相似、内容不同,通过组件封装可以实现服用结构的效果)(非复杂的模板抽象成props,复杂的结构模板抽象为插槽)

5然后实现新鲜好物和人气推荐模块:准备模板(HomePanel组件)、定制Props、定制插槽内容(接口 + 渲染模板)

6、再写一个图片懒加载(vueUse),优化网页。(当图片进入视口时,发送图片资源请求)(可以把懒加载指令封装为插件,然后在入口文件只需要负责注册插件即可)

7、然后实现Product产品列表(常规的列表渲染):准备静态模板、封装接口、获取数据渲染模板、图片懒加载

8、再然后进行GoodsItem组件的封装(在项目中的每个业务模块中都需要用到同样的商品展示模块,没必要重复定义,封装起来,方便复用)

一级分类

1、然后简单配置一下路由

2、然后写一个面包屑导航(常规):准备组件模板、封装接口函数、调用接口获取数据(使用路由参数useRoute)、渲染模板

3、然后把首页的轮播图迁移到category(重写接口,其他复制即可)

4、再写一个分类列表渲染

!!!!!

路由缓存问题:由于用户从'/users/johny'到'/user/jolyne'时,相同的组件实例将被重复使用,生命周期hook将不会被调用,导致数据无法更新

5、然后解决一下本项目的路由缓存问题(方案一:让组件实例不复用,强行销毁重建;方案二:监听路由变化,变化之后执行数据更新操作)

建议用方案二,因为banner轮播图是可以复用的,如果用方案一,banner轮播图必须要再次发送请求,不够优雅

!!!!!

6、然后呢,用逻辑函数把同一组件中的独立的业务封装,提升代码的可维护性(思想),具体实现呢:category文件夹中含有banner轮播图和分类数据两个业务,我们需要把这两个业务分别封装

二级分类

1、然后给二级分类做一个面包屑导航

2、再然后做基础商品列表实现:实现基础列表渲染、添加额外参数实现筛功能、实现无限加载功能(太麻烦了,就不一步一步写了)

虽然已经过了第二天了,但只要没睡,就不算新的一天(^_^)

详情页

然后就开始做详情页了

1、先整体认识以及路由配置

2、然后做详情页的基础数据渲染(常规)

3、再做热榜区的基础数据渲染(常规)(封装Hot热榜组件、获取渲染基础数据、适配不同的标题Title、视频不同列表内容)

day3

4、然后对图片预览组件进行封装(实现通过小图切换大图显示的功能、放大镜效果)

5、通过小图切换大图功能:静态模板、为小图绑定事件,记录当前激活下标值、通过下标切换大图显示、通过下标实现激活状态显示

6、放大镜效果:引入vueuse的useMouseInElement,使用elementX, elementY, isOutside三个参数,

 用watch监听这三个参数

下图是运算逻辑

根据运算逻辑算得left和top之后,给滑块,控制滑块跟随移动,放大之后的图(简称大图)是未放大图的两倍大,横向纵向都是left、top的 - 2 倍,然后给大图,控制大图移动即可

7、sku组件:商品规格(颜色、大小....)

使用别人写好的sku组件(太复杂了,太麻烦了,没必要自己写),完成 选择商品规格功能

8、然后把components文件夹中的imageView组件和sku组件写成插件,并在全局引用,这样就不需要再引入了

登录

1、先进行路由配置

2、然后做一下登录页面的表单校验(校验账号密码格式....)(elementPlus内置了表单校验功能,按照组件要求配置必要参数)

3、然后做一下条款协议的校验(由于内置的校验功能不能满足我们的需求,所以使用自定义校验)

4、然后再做一下整体校验(处理用户上来直接点击登录的情况)

5、然后实现一下基础的登录业务流程(表单校验通过 => 封装登录接口 => 调用登录接口 => 登录成功/失败的后续逻辑)

6、然后用pinia管理用户数据,以便于多个组件访问用户数据

7、然后做到使用户数据持久化,保持token在刷新时不丢失(存到localStorage)(pinia-plugin-persistedstate插件,适用于Pinia的持久化存储)

8、再然后做一下登录和非登录状态下的模板适配(同一区域在不同登录状态下的不同模板显示)

9、然后实现一下 在请求拦截器中携带token 的功能(token作为用户标识,在很多接口中必须携带token才可以正确获取资源,所以需要在接口调用时携带token)

config.headers.Authorization = `Bearer ${token}`

记得这段代码是按照后端的要求来的,是固定的

10、退出登录功能实现(点击退出登录弹出确认框、点击确认按钮实现退出登录逻辑、清除当前用户信息&&跳转到登录页面)

11、token失效401拦截处理(o_o)(token的有效性可以保持一定的时间,如果用户一段时间不做任何操作,token就会失效,使用失效的token再去请求一些接口,接口就会报401状态码错误,需要做额外处理(重新登录))

购物车:最难的功能

 业务逻辑梳理{ 未登录 => 所有操作不走接口直接操作Pinia中的本地购物车列表

已登录 => 所有操作直接走接口,操作完毕获取购物车列表更新本地购物车列表 }

1、实现本地加入购物车的功能(用pinia实现添加购物车功能,再把数据持久化)

2、给头部购物车添加一个列表渲染功能

3、给头部购物车添加一个删除功能(

法一:找到要删除项的下标值,用slice  不好写,但是可能不用遍历全部

法二:用filter 好写,但是要遍历全部

4、实现头部购物车统计计算功能(计算属性)

5、实现列表购物车基础数据渲染

6、实现列表购物车单选功能

day4

7、实现列表购物车全选功能(底层实现v-model,不能直接用v-model,因为v-model的计算属性是只可读的)

8、做两个接口分别实现 加入 和 删除 购物车功能,(之前做的都是直接操作Pinia中的本地购物车列表(未登录状态),现在我们做的是已登录状态的操作)

9、退出登录,清空购物车数据(在cartStore中补充清除购物车的action、userStore中找到退出登录action,执行清除业务)

10、登录时,把本地购物车的数据和服务端购物车数据进行合并操作(登录时调用合并购物车接口,获取最新购物车列表,覆盖本地)

 结算

 1、先做路由配置和整体数据渲染

2、地址切换 - 打开弹框交互式实现

3、地址激活交互实现:点击哪个,哪个地址就变成激活状态,然后把地址覆盖

4、提交订单功能实现,提交订单跳转之后,更新购物车状态

支付

1、渲染基础数据 

2、完成支付功能:跳转支付地址(get请求)(订单id+回跳地址url)

//支付地址
const baseURL = 'http://pcapi-xiaotuxian-front-devtest.itheima.net/'
const backURL = 'http://127.0.0.1:5173/paycallback'
const redirectUrl = encodeURIComponent(backURL)
const payUrl = `${baseURL}pay/aliPay?orderId=${route.query.id}&redirect=${redirectUrl}`

支付完毕后,跳转到回跳地址url(订单id+支付状态)

3、做支付成果展示功能

4、封装倒计时函数(格式化时用插件dayjs)(这一步代码比较集中,就粘过来了)

//封装倒计时逻辑函数
import { ref,computed, onUnmounted } from "vue"
import dayjs from "dayjs"

export const useCountDown = () => {
  let timer = null
  //1、响应式数据
  const time = ref(0)
  //格式化时间为 XX分XX秒
  const formatTime = computed(() => {
    return dayjs.unix(time.value).format('mm分ss秒')
  })
  //2、开启倒计时的函数
  const start = (currentTime) => {
    //开始倒计时的逻辑
    //核心逻辑:每隔一秒减一
    time.value = currentTime
    timer = setInterval(() => {
      time.value--
    },1000)

  }
  //组件销毁时,清除定时器
  onUnmounted(() => {
    timer && clearInterval(timer)
  })
  return {
    formatTime,
    start
  }
}

 记得渲染。

会员中心--最后一个模块

1、路由配置:三级路由 

2、个人中心信息渲染( 个人信息 部分直接使用Pinia中的数据, 猜你喜欢 部分走接口获取)

3、tab切换获取状态数据并渲染

4、分页逻辑实现

然后就ok了

终于写完了,这下可以好好玩黑神话悟空了

jjuaien/vue3-rabbit (github.com)     <=     手写的源代码在这里

  • 30
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值