购买产品个数

  • Detail/index.vue

<template>
......<input autocomplete="off" class="itxt" v-model="skuNum" @change="changeSkuNum"/><a href="javascript:" class="plus" @click="skuNum++">+</a><a href="javascript:" class="mins" @click="skuNum>1?skuNum--:skuNum=1">-</a>
</template><script>
......
export default {name: "Detail",data(){return {//购买产品的个数skuNum:1}},methods:{//用户自定义商品数量change函数:表单元素修改产品个数changeSkuNum(event){//用户输入进来的文本let value = event.target.value * 1;//如果用户输入进来的非法if(isNaN(value) || value < 1){this.skuNum = 1;}else{//若出现小数,转为整数this.skuNum = parseInt(value);}}}
};
</script>

加入购物车

  • 任务1 : 点击加入购物车按钮 ==> 跳到 AddCartSuccess 路由组件,根据后台接口文档,需要传递: skuNum( 购买商品个数)、skuId(产品的 Id)

  • AddCartSuccess 路由组件

<template><div class="cart-complete-wrap"><div class="cart-complete"><h3><i class="sui-icon icon-pc-right"></i>商品已成功加入购物车!</h3><div class="goods"><div class="left-good"><div class="left-pic"><img :src="skuInfo.skuDefaultImg"></div><div class="right-info"><p class="title">{{skuInfo.skuName}}</p><p class="attr">{{skuInfo.skuDesc}} 数量:{{$route.query.skuNum}}</p></div></div><div class="right-gocart"><router-link class="sui-btn btn-xlarge" :to="`/detail/${skuInfo.id}`" >查看商品详情</router-link><router-link  to="/shopCart">去购物车结算</router-link></div></div></div></div>
</template><script>export default {name: 'AddCartSuccess',computed:{skuInfo(){return JSON.parse(sessionStorage.getItem('SKUINFO'));}}}
</script><style lang="less" scoped>.cart-complete-wrap {background-color: #f4f4f4;.cart-complete {width: 1200px;margin: 0 auto;h3 {font-weight: 400;font-size: 16px;color: #6aaf04;padding-top: 15px;padding-bottom: 15px;margin: 0;.icon-pc-right {background-color: #fff;border: 2px solid #6aaf04;padding: 3px;margin-right: 8px;border-radius: 15px;}}.goods {overflow: hidden;padding: 10px 0;.left-good {float: left;.left-pic {border: 1px solid #dfdfdf;width: 60px;float: left;img {width: 60px;height: 60px;}}.right-info {color: #444;float: left;margin-left: 10px;.title {width: 100%;line-height: 28px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;font-size: 14px;}.attr {color: #aaa;}}}.right-gocart {float: right;a {padding: 7px 36px;font-size: 15px;line-height: 22px;color: #333;background-color: #eee;text-decoration: none;box-sizing: border-box;border: 1px solid #e1e1e1;}a:hover {background-color: #f7f7f7;border: 1px solid #eaeaea;}a:active {background-color: #e1e1e1;border: 1px solid #d5d5d5;}.btn-danger {background-color: #e1251b;color: #fff;}.btn-danger:hover {background-color: #e1251b;}}}}}
</style>
  • 注册路由前 的固定写法 router/index.js

//配置路由的地方
import Vue from 'vue';
import VueRouter from 'vue-router';//引入路由配置文件
import routes from './routes'
//使用插件
Vue.use(VueRouter);//解决编程导航方式路由跳转方式不可重复提交相同参数的问题 ==> 重写 push 和 replace 方法
//1.先把 VueRouter 原型对象的 push 保存一份
let originPush = VueRouter.prototype.push;//重写 push | replace
//第一个参数:跳转地址和参数
VueRouter.prototype.push = function (location, resolve, reject) {if (resolve && reject) {originPush.call(this, location, resolve, reject);} else {originPush.call(this, location, () => { }, () => { });}
}//配置路由
export default new VueRouter({//配置路由routes: routes,scrollBehavior(to, from, savedPosition) {// 始终滚动到顶部return { y: 0 }},
})
  • 注册路由 router.js

//引入路由插件
import AddCartSuccess from '@/pages/AddCartSuccess'export default [//注册路由addCartSuccess{path: "/addCartSuccess",name:"addCartSuccess",component: AddCartSuccess,meta: {  //显示footer 全局组件showFooter: true}},......
]
  • 写接口前提: api/request.js

//对 axios 进行二次封装
import axios from "axios";//引入进度条 nprogress 以及样式(可修改) 并在请求和响应拦截器中 调用 star 和 done 方法
import nprogress from 'nprogress';
import "nprogress/nprogress.css"
//引入游客临时id
import store from "@/store";//1.利用axios对象的create,去创建一个axios实例
//2.request就是axios,只不过稍微配置一下
const requests = axios.create({//配置对象//基础路径,发请求的时候,路径当中会出现apibaseURL:"/api",timeout:5000,
});//请求拦截器
requests.interceptors.request.use((config)=>{//config:配置对象,对象里面有一个属性很重要,headers请求头//进度条开始nprogress.start();if(store.state.detail.uuid_token){//请求头添加一个字段(userTempId) ==> 游客临时身份config.headers.userTempId = store.state.detail.uuid_token;}return config;
});//响应拦截器
requests.interceptors.response.use((res)=>{//响应成功的回调函数//进度条结束nprogress.done();return res.data;},(error)=>{//响应失败的回调函数return Promise.reject(new Error('faile'));})//暴露export default requests;
  • 写接口 :api/index.js

// 此 index.js:    对 API 进行统一管理//引入二次封装的axios ==> requests
import requests from "./request";
......//获取 将产品添加到购物车(获取更新某一产品的个数)的接口    地址:/api/cart/addToCart/{skuId}/{skuNum}  请求方式post
export const reqAddOrUpdateShopCart = (skuId,skuNum)=>requests({url:`/cart/addToCart/${skuId}/${skuNum}`,method:'post'
})
......
})
  • Vuex三连环 :store/detail/index.js

//引入接口
import { reqAddOrUpdateShopCart } from "@/api"
//封装游客临时身份的模块 uuid ==> 生成一个随机字符串(唯一不变)
import { getUUID } from "@/utils/uuid_token";
//search 模块的小仓库
const state = {......//游客的临时身份uuid_token:getUUID()
}
const mutations = {}
const actions = {......//将产品添加到购物车中async addOrUpdateShopCart({commit},{skuId,skuNum}){//因为我们只是发通知给服务器,让服务器保存数据,而不用向服务器获取数据,所以不用vuex三连环获取数据以及捞数据展示数据let result = await reqAddOrUpdateShopCart(skuId,skuNum);//代表服务器加入购物车成功if(result.code == 200) {return "ok"}else{//代表加入购物车失败return Promise.reject(new Error('faile'))}}}
//为简化数据而生
const getters = {......}export default {state,mutations,actions,getters
}
  • 组件派发请求(请求成功则 进行路由跳转)、捞数据展示数据(此处不需要) :Detail/index.js

<template>......<div class="add"><a @click="addShopCart">加入购物车</a></div>......
</template><script>//添加购物车方法,发请求async addShopCart(){//发请求,通知服务器将产品加入到数据库,并非向服务器获取数据,所以不需要 vuex 三连环//this.$store.dispatch('addOrUpdateShopCart',{skuId:this.$route.params.skuId,skuNum:this.skuNum})这行代码,实际上就是调用了store中//addOrUpdateShopCart,因为 addOrUpdateShopCart 加上了 asyc,返回的一定是 Promise(要么成功,要么失败)try{await this.$store.dispatch('addOrUpdateShopCart',{skuId:this.$route.params.skuId,skuNum:this.skuNum});//通过会话存储(会话结束==>关闭页面 就消失)//本地存储 or 会话存储,一般存储的是 字符串,如果要存对象,就得使用jsonsessionStorage.setItem("SKUINFO",JSON.stringify(this.skuInfo));//进行路由跳转this.$router.push({name:'addCartSuccess',query:{skuNum:this.skuNum}})  //params参数才需要占位}catch (error){//失败alert(error.message)}}
</script>
<script>//添加购物车方法,发请求async addShopCart(){//发请求try{await this.$store.dispatch('addOrUpdateShopCart',{skuId:this.$route.params.skuId,skuNum:this.skuNum});//通过会话存储(会话结束==>关闭页面 就消失)//本地存储 or 会话存储,一般存储的是 字符串,如果要存对象,就得使用jsonsessionStorage.setItem("SKUINFO",JSON.stringify(this.skuInfo));//进行路由跳转this.$router.push({name:'addCartSuccess',query:{skuNum:this.skuNum}})   //params参数才需要占位}catch (error){//失败alert(error.message)}}
</script>

路由跳转时有动态参数要这样写:< router-link :to=" ``/xxx/${参数}`" >xxx

  • Detail/index.js.js

<script>......<router-link class="sui-btn btn-xlarge" :to="`/detail/${skuInfo.id}`" >查看商品详情</router-link><router-link  to="/shopCart">去购物车结算</router-link>......
</script>
......
//获取 购物车列表    地址:/api/cart/addToCart/{skuId}/{skuNum}  请求方式 get
export const reqCartList = ()=>requests({url:'/cart/cartList',method:'get'
})
import {v4 as uuidv4} from 'uuid';
//要生成一个随机字符串,且每次执行不发生变化,而且这个游客id需要持久存储
export const getUUID = () => {//先判断本地存储有没有uuidlet uuid_token = localStorage.getItem('UUIDTOKEN');//如果没有uuid,随机生成一个if(!uuid_token){uuid_token = uuidv4();//存储到本地localStorage.setItem('UUIDTOKEN',uuid_token);}return uuid_token;
}
  • store/detail.js 生成游客临时身份

......
//封装游客临时身份的模块 uuid ==> 生成一个随机字符串(唯一不变)
import { getUUID } from "@/utils/uuid_token";
const state = {......//游客的临时身份uuid_token:getUUID()
}
......
  • api/request.js 在请求头中存储 游客临时身份

......
//引入游客临时id
import store from "@/store";//请求拦截器
requests.interceptors.request.use((config)=>{......if(store.state.detail.uuid_token){//请求头添加一个字段(userTempId) ==> 游客临时身份config.headers.userTempId = store.state.detail.uuid_token;}return config;
});
......
  • 任务5 :购物车 各功能实现

https://blog.csdn.net/weixin_54966486/article/details/124009161

Vue —— 购买产品个数与加入购物车相关推荐

  1. Vue.js-小demo实现简单的游戏购物车table

    Vue.js-小demo实现简单的游戏购物车table 最近通过学习vue框架,基本熟悉了其中的动态绑定属性,计算属性,监听,条件判断,循环遍历,所以通过一个小demo来巩固一下.这个小demo主要是 ...

  2. LeetCode MySQL 1398. 购买了产品A和产品B却没有购买产品C的顾客

    文章目录 1. 题目 2. 解题 1. 题目 Customers 表: +---------------------+---------+ | Column Name | Type | +------ ...

  3. ecshop简化虚拟商品购买收货人信息【ECSHOP购物车不存在实体商品电话改为非必须以及隐藏掉】

    插件简介 ECSHOP默认购买虚拟商品,收货人信息页面需要填写收货人.邮箱.电话.手机.这里我们做了简化处理,只需要填写收货人以及邮箱,其余的只有存在实体商品下才采用. 实测演示效果截图: 如果购物车 ...

  4. vue实战-产品详情页(轮播图、放大镜)

    vue实战-产品详情页(轮播图.放大镜) 1.添加产品详情页的静态组件 因为它是路由组件,将其放入pages文件夹下. 注册路由组件 1)router中添加Detail的路由. {path:'/det ...

  5. 苹果官网php,苹果官方购买产品服务器端验证代码PHP版

    苹果官方购买产品服务器端验证代码PHP版 function getReceiptData($receipt, $isSandbox=false) { if($isSandbox){ $endpoint ...

  6. Apple内购(IAP)恢复购买产品在网络问题导致超时情况下的处理

    问题现象 Apple 内购(IAP)正常的交易流程,小伙伴们都能很好的处理. 不过正所谓"天有不测风云",如果在 IAP 恢复购买时网络信号很差或者干脆没有网络,就会导致 App ...

  7. 用vue和node写的简易购物车

    [新增vue中使用pug模板] 在webpack.config.js引入pug的loader,就可以在vue中使用pug模板. module: {loaders: [{test: /\.vue$/,l ...

  8. 客户购买产品的本质是什么,如何快速寻找到客户的需求,提高转化率?

    销售大师博恩崔西说过:"在销售中不要推销产品,而是要推销产品带给客户的好处." 趋利避害是人类的本能,任何人都无法摆脱这一客观现实.销售员在寻找客户需求的过程中,可以从趋利这一点入 ...

  9. Vue/vant——未登陆时清空购物车以及拦截未登录的状态拒绝进入购物车页面

    cart.js // 清空购物车clearCart(state){state.list = [],state.selectAll = []} axios.js "use strict&quo ...

最新文章

  1. 和12岁小同志搞创客开发:手撕代码,做一款遥控灯
  2. 5.3.1 TCP协议特点和TCP报文段格式
  3. Linux下Scala(2.12.1)安装
  4. 第三天·HTML常用标签
  5. 使用VC++ 读取显示DEM文件
  6. tableau linux无网络安装_举个栗子!Tableau 技巧(110)两种方法实现正态分布 Normal distribution...
  7. C++实现虚拟内存页面置换算法(FIFO, OPT, LRU)
  8. android sdio 时钟 ios-clock,iOS 炫酷时钟
  9. graph-easy 纯文本图绘制工具(表格或流程图)
  10. toj 4613 Number of Battlefields
  11. 和yupeng的讨论
  12. 谁该为马化腾表态这个乌龙尴尬?
  13. 集成电路的设计 —— 引脚
  14. CentOS7安装了nginx后启动本机访问不到
  15. innodb 索引 mysql_InnoDB索引实现
  16. 高阶篇:4.4)FMEA手册的疑问与不足(个人观点)
  17. 树莓派WiFi设置固定IP地址
  18. 给大家推荐一波Python书单,电子版拿走不谢
  19. 理论物理极础附录:有心力和行星轨道
  20. 计算机右侧不显示桌面,显示器右边显示不出来怎么办

热门文章

  1. java武功秘籍_请问java全套内容都有什么呢?
  2. 国海证券分析报告(0608)
  3. 教女朋友学习 vue中的组件
  4. oracle tns和sid,oracle tns listener配置 (附TNS介绍)
  5. C语言实战--QQ友爱机
  6. 解决esxi主机vmware 无法清除磁盘的报错
  7. MySQL表复制SQL语句
  8. filetype判断与使用
  9. [计蒜客][贪心]节约用电
  10. MATLAB 单纯形法算法