首页 > 其他分享 >vue3项目-小兔鲜儿笔记-登录页02和购物车01

vue3项目-小兔鲜儿笔记-登录页02和购物车01

时间:2022-09-07 23:44:59浏览次数:109  
标签:02 skuId 01 const 登录 鲜儿 购物车 组件 payload

1. 登录-消息提示组件封装

组件功能分析:

  • 固定顶部显示,有三种类型:成功、错误、警告

  • 显示消息提示时需要动画从上滑入

  • 组件使用的方式不够便利,封装成工具函数的方式

<template>
  <div class="xtx-message" :style="style[type]">
    <!-- 上面绑定的是样式 -->
    <!-- 不同提示图标会变 -->
    <i class="iconfont" :class="[style[type].icon]"></i>
    <span class="text">{{text}}</span>
  </div>
</template>
<script setup>
import {ref, onMounted} from "vue";

defineProps({
  text: {
    type: String,
    default: ''
  },
  type: {
    type: String,
    // warn 警告, success 成功, error 错误
    default: 'warn'
  }
})

// 定义一个包含三种情况样式的对象
const style = {
  warn: {
    icon: 'icon-warning',
    color: '#e6a23c',
    backgroundColor: 'rgb(253, 246, 236)',
    borderColor: 'rgb(250, 236, 216)'
  },
  error: {
    icon: 'icon-shanchu',
    color: '#F56C6C',
    backgroundColor: 'rgb(254, 240, 240)',
    borderColor: 'rgb(253, 226, 226)'
  },
  success: {
    icon: 'icon-queren2',
    color: '#67C23A',
    backgroundColor: 'rgb(240, 249, 235)',
    borderColor: 'rgb(225, 243, 216)'
  }
}

// 控制消息组件的显示和隐藏
const visible = ref(false)
onMounted(() => {
  visible.value = true
})
</script>
实现从上滑入的效果
.down-enter-from, .down-leave-to {
  transform: translateY(-75px);
  opacity: 0;
}

.down-enter-to, .down-leave-from {
  transform: none;
  opacity: 1;
}

.down-enter-active, .down-leave-active {
  transition: all 0.3s ease;
}
Message.js:封装成工具函数
// 封装消息组件并挂载到app.config.globalProperties中,使得组件可直接调用消息组件
import { createVNode, render } from 'vue'
import XtxMessage from '@/components/library/xtx-message'

// 先创建一个div容器,让消息组件挂载到这个容器上
const div = document.createElement('div')
div.classList.add('xtx-message-container')
document.body.appendChild(div)

// 定时器标识
let timer = null

export default function ({ type, text }) {
  // 将消息组件渲染成vnode
  const vnode = createVNode(XtxMessage, { type, text })
  // 将vnode挂到上述定义的div容器中
  render(vnode, div)
  // 定时器作用:消息显示一段时间后删除
  clearTimeout(timer)
  timer = setTimeout(() => {
    render(null, div)
  }, 3000)
}

main.js
// 挂载消息组件到全局vue对象上
app.config.globalProperties.$message = Message

显示效果:

 

 

2. 购物车功能分析

  • 购物车的各种状态都会有登录和未登录两种状态的区分,这种区分逻辑封装在pinia的actions中,组件不需区分。

  • pinia的actions中的区分:

    • 未登录:直接修改cart模块中的数据即可

    • 已登录:通过api接口去后端操作,响应成功后再修改cart模块中的数据

  • 不管何种状态最后均返回一个promise,让组件去判断操作是否成功。

  • 登录后,需要合并本地购物车到服务端,退出后,清空cart模块的数据也会同步清空本地数据。

 

3. 加入购物车-本地

完成商品详情的添加购物车操作,支持未登录状态

首先约定本地存储的字段信息:

id skuId name attrsText picture price nowPrice selected stock count isEffective

    // 加入购物车
    insertCart(payload) {
      // 约定加入购物车字段必须和后端一致:payload的字段
      // 它们是:id skuId name attrsText picture price nowPrice selected stock count isEffective
      // 插入数据的规则:
      // 1.先找是否有相同的商品
      // 如果有:找到这个商品的数量,累加到payload上,然后删除原来的商品,将payload保存到最新的位置上
      // 如果没有:直接将payload保存到最新的位置上
      const sameIndex = this.list.findIndex(
        (goods) => goods.skuId === payload.skuId
      )
      if (sameIndex > -1) {
        const count = this.list[sameIndex].count
        payload.count += count
        this.list.splice(sameIndex, 1)
      }
      this.list.unshift(payload)
    },

    // 判断登录还是未登录逻辑的加入购物车
    asyncInsertCart(payload) {
      const userStore = useUserStore()
      return new Promise((resolve, reject) => {
        if (userStore.profile.token) {
          // 已登录
        } else {
          // 未登录
          this.insertCart(payload)
          resolve()
        }
      })
    },
商品详情页:
// 加入购物车
const insertCart = () => {
  // 判断是否选择完整的sku
  if (currSku.value && currSku.value.skuId) {
    // 约定字段:id skuId name attrsText picture price nowPrice selected stock count isEffective
    const {skuId, price, inventory: stock, specsText: attrsText} = currSku.value
    const {id, name, mainPictures} = goods.value
    cartStore.asyncInsertCart({
      id,
      skuId,
      name,
      attrsText,
      picture: mainPictures[0],
      price,
      nowPrice: price,
      selected: true,
      stock,
      count: num.value,
      isEffective: true
    }).then(() => {
      Message({type: 'success', text: '成功加入购物车'})
    })
  } else {
    Message({text: '请选择完整的规格信息'})
  }
}

 

4. 头部购物车-商品列表-本地

目的:当进入首页时,根据本地存储的商品获取最新的库存价格和有效状态,更新商品列表信息

    // 一次性获取购物车列表的所有商品并更新商品信息
    findCartList() {
      return new Promise((resolve, reject) => {
        const userStore = useUserStore()
        if (userStore.profile.token) {
          // 已登录
        } else {
          // 未登录
          // Promise.all() 一次发送多个请求,等所有请求完毕后调用then
          // 传参是promise数组
          const promiseList = this.list.map((goods) => {
            // 发送请求返回的是promise
            return getNewCartGoods(goods.skuId)
          })

          Promise.all(promiseList).then((dataList) => {
            // dataList结果和promiseList一一对应
            dataList.forEach((data, i) => {
              this.updateGoods({ skuId: this.list[i].skuId, ...data.result })
            })
          })

          resolve()
        }
      })
    },
// 头部栏组件
<script setup>
import useCartStore from "@/store/cart";
import Message from "@/components/library/Message";

const cartStore = useCartStore()
// 一开始进入首页时就应该更新购物车列表的商品信息
cartStore.findCartList().then(() => {
  Message({type: 'success', text: '更新购物车列表成功'})
})
。。。

 

5. 头部购物车-删除操作-本地

目的:完成头部购物车删除操作,支持未登录状态

    // 通过skuId删除购物车中的商品
    deleteCart(skuId) {
      const index = this.list.findIndex((goods) => goods.skuId === skuId)
      this.list.splice(index, 1)
    },

    //结合登录逻辑和未登录逻辑的删除购物车中的商品
    asyncDeleteCart(skuId) {
      return new Promise((resolve, reject) => {
        const userStore = useUserStore()
        if (userStore.profile.token) {
          // 已登录
        } else {
          // 未登录
          this.deleteCart(skuId)
          resolve()
        }
      })
    }
// 头部栏组件
// 删除购物车中的商品
const deleteCart = (skuId) => {
  cartStore.asyncDeleteCart(skuId).then(() => {
    Message({type: 'success', text: '成功删除商品'})
  }).catch(error => {
    Message({type: 'error', text: '删除商品失败'})
  })
}

 

标签:02,skuId,01,const,登录,鲜儿,购物车,组件,payload
From: https://www.cnblogs.com/jzhFlash/p/16667742.html

相关文章

  • 石家庄铁道大学2022年秋季 2021 级课堂测试试卷(一)(15分)
    石家庄铁道大学2022年秋季  2021 级课堂测试试卷(一)(15分)课程名称: JAVA语言程序设计  任课教师:王建民       考试时间: 150分钟  一、考试要求:1、......
  • 02-运维--安装软件
    Linux安装1.Sentinel只是一个jar包,启动即可#https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0#https://github.com/alibaba/Sentinel/releas......
  • 01.SpringCloudAlibaba 项目
    SpringCloudAlibaba项目1.简述SpringCloudAlibaba项目,采用的SpringCloudAlibaba相关组件:Nacos:注册与发现、配置Gateway:网关Feign:远程调用Sentinel:限流、熔断Se......
  • 2022年你要知道的软件测试工作流程
    不同类型的软件产品测试的方式和重点不一样,测试流程也会不一样。同样类型的软件产品,不同的公司所制定的测试流程也会不一样。虽然不同软件的详细测试步骤不同,但它们所遵循......
  • Day01
    Markdowm学习标题二级标题三级标题四级标题 字体Hello,World!Hello,World!Hello,World!Hello,World!Hello,World!引用选择狂神说Java,走向人生巅峰 分割线图片......
  • 【2021ICPC上海站】H-Life is a Game(kruskal重构树)
    题意你本身有一个权值。每个点有一个权值,到达一个点可以获得这个权值;每条边也有一个权值,只有你自己当前权值大于等于边权才可以走这条边。q次询问,每次给出初始点和初始......
  • 巧用SQL语句中的OR查询完成业务新需求-2022新项目
    一、业务场景目前参与开发的项目,之前的一个已上线的版本中有一类查询是根据两张表进行LEFTJOIN查询用来取数据,主表中有一个字段field用来区分不同的数据类型比如说A......
  • 01-项目简介
    当你站在我的面前看我时,你知道我心里的悲伤吗商城模式B2C模式 项目技术&特色前后端分离开发,并开发基于Vue的后台管理系统springcloud全新的解决方案应用监......
  • 数据库学习笔记 (本数据库学习笔记以SQL sever 2019 为例进行学习) 20220906 第五节课
    通过一个表,抽象出表的关系模式:列是同质:即每一列中的分量来自同一域,是同一类型的数据列位置互换性:区分一列是靠列名行位置互换性:区分哪一行是靠某一或某几列的值(关键字......
  • gin实践,搭建blogs-02
    定义接口本节正是编写标签的逻辑,我们想一想,一般接口为增删改查是基础的,那么我们定义一下接口吧!获取标签列表:GET(“/tags”)新建标签:POST(“/tags”)更新指定标签:PUT(......