20230504----重返学习-vue2项目-跳转拦截-重定向并返回前一页-使用vuex调用接口-全选与全不选-总价计算
day-061-sixty-one-20230504-vue2项目-跳转拦截-重定向并返回前一页-使用vuex调用接口-全选与全不选-总价计算
vue2项目
跳转拦截
设置跳转拦截,比如在用户没token时,不能进入具体详情页,而是进入登录页进行登录。
跳转拦截具体思路
- 前端和后端约定好一个返回码,如resultCode为416,那么前端就跳转到登录页。
- 前端根据这返回码在axios的响应拦截器axios.interceptors.response.use()钩子函数中进行处理,如跳转到首页或登录面之类的操作。
- 前端发起一个需要token的请求。
- 后端收到前端的请求,校验token是否存在或合法。
- 如果存在并合法,正常返回数据。
- 如果token不存在或不合法,返回resultCode并为416。
- 如果后端返回resultCode并为416,就会触发axios的响应拦截器中的钩子函数,重定向到登录页。
跳转拦截实际步骤
- 在axios实例对象或axios原型上设置响应拦截器
-
/src/http/http.js
import axios from "axios";import router from '../router/index.js'// 添加响应拦截器 axios.interceptors.response.use((response) => {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么// 后端的resultCode为416时,要求重新登录。let { message, resultCode } = response.data;if (+resultCode === 416) {router.push(`/LoginView`)}return response.data;},function (error) {return Promise.reject(error);} ); export default axios;
-
重定向并返回前一页
因重定向跳转登录页并登录成功后,在登录页中跳转返回前一页
重定向并返回具体思路
- 在在axios的响应拦截器axios.interceptors.response.use()钩子函数中跳转到登录页时,给路由加一个字段表示要重返前一页,如needback为true。
- 在登录页中,设置登录成功后,如果
this.$route?.query?.needback
存在,就返回到前一页。
重定向并返回实际步骤
-
在axios实例对象或axios原型上的响应拦截器进行跳转时,在需要的路由中加上
?needback=true
。-
/src/http/http.js
import axios from "axios"; import router from '../router/index.js'// 添加响应拦截器 axios.interceptors.response.use((response) => {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么// 后端的resultCode为416时,要求重新登录。let { message, resultCode } = response.data;if (+resultCode === 416) {router.push(`/LoginView?needback=true`)}return response.data;},function (error) {return Promise.reject(error);} ); export default axios;
-
-
在登录成功后,跳转的页面中根据
this.$route?.query?.needback
决定是返回前一页还是首页。-
/src/views/LoginView.vue
<script> import { Notify } from "vant";export default {components: {Verify,},data() {return {username: "",password: "",flag: true,verifyFlag: false,};},methods: {onSubmit() {this.$api.login(this.username, this.password).then((value) => {let { resultCode, message, data } = value;if (resultCode !== 200) {return;}// 有needback就返回上一页if (this.$route?.query?.needback) {this.$router.back();return;}// 无needback就返回前面this.$router.push("/IndexView");}).catch((error) => {console.log(`error-->`, error);}).finally(() => {console.log("登录操作后执行");});},}, }; </script>
-
使用vuex调用接口
使用vuex调用接口,以便使用vuex中的全局数据,制作如购物车这类效果。
使用vuex调用接口具体思路
- 定义一个接口。
- 在vuex中配置state,及mutations用于同步修改state,actions用于请求数据并调用mautaions方法间接修改state。
- 在需要中页面中引入state中的数据及actions方法,根据需要使用state中的数据和调用actions中的方法。
使用vuex调用接口实际步骤
-
在axios中添加一个接口,用于vuex中进行操作。
-
/src/http/index.js
import http from "./http.js";// 获取购物车所有的产品 function getCartList() {return http.get("/shop-cart"); }export default {getCartList, };
-
-
在vuex中配置state,及mutations用于同步修改state,actions用于请求数据并调用mautaions方法间接修改state。
-
/src/store/index.js
import Vue from "vue"; import Vuex from "vuex";import api from "../http/index";Vue.use(Vuex);export default new Vuex.Store({state: {list: null,},mutations: {changeList(state, payload) {// 默认添加选中状态payload.map((item) => {item.selected = true;return item;});state.list = payload;},},actions: {async getCartListAsync({ commit }) {try {let res = await api.getCartList();console.log(`res-->`, res);let { data, resultCode } = res;if (+resultCode !== 200) {commit("changeList", []);return;}commit("changeList", data);} catch (err) {console.log(`err-->`, err);}},}, });
-
-
在需要中页面中引入state中的数据及actions方法,根据需要使用state中的数据和调用actions中的方法。
-
/src/views/DetialView.vue
<template><div class="detial-wrap"><van-goods-action><van-goods-action-iconv-show="list?.length <= 0"icon="cart-o"text="购物车"/><van-goods-action-iconv-show="list?.length > 0"icon="cart-o"text="购物车":badge="list?.length"/></van-goods-action></div> </template><script> import { mapState, mapActions } from "vuex"; export default {data() {return {detialData: {},};},computed: { ...mapState(["list"]) },created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
/src/components/FooterPage.vue
<template><div><van-tabbar v-model="active" active-color="#1baeae" :route="true"><van-tabbar-itemicon="shopping-cart-o"v-show="list?.length <= 0"to="/CartView">购物车</van-tabbar-item><van-tabbar-itemicon="shopping-cart-o"v-show="list?.length > 0":badge="list?.length"to="/CartView">购物车</van-tabbar-item></van-tabbar></div> </template><script> import { mapState, mapActions } from "vuex"; export default {data() {return {active: 0,};},computed: {...mapState(["list"]),},methods: {...mapActions(["getCartListAsync"]),},created() {if (this.list === null) {this.getCartListAsync();}}, }; </script>
-
全选与全不选
- 可以用一个变量isAll表示是否全选,用一个数组变量来记录所有已选值对应id。
- 之后对已选数组进行监听或对于所有会改变的已选数组的事件都执行判断已选数组长度与选项数组总长度是否全等。
- 若已选选项数组长度与选项数组总长度相等,那么就为true。
- 若已选选项数组长度与选项数组总长度不相等,值就为false。
- 全选与全不选中间态用另一个变量来表示。
- 如果已选数组长度为0 或 已选数组长度与选项数组总长度全等,值为false。
- 已选数组长度不为0并且已选数组长度与选项数组总长度不全等,值为true。
- 之后对已选数组进行监听或对于所有会改变的已选数组的事件都执行判断已选数组长度与选项数组总长度是否全等。
- 可以用计算属性来做处理,用对象变量的布尔值属性来表示该对象是否被选中。
- 在data或computed中定义一个基础对象数组,对象上有一个属性表示是否选中。
- 在计算属性的get()来做返回的结果值。
- 在计算属性的set()里来修改源头数组对象的表示是否选中的属性值,进而让get()得到的值发生改变。
- 这个的前提是数组里对象及它的属性值是响应式的。
全选与全不选-计算属性版具体思路
- 在data或computed中定义一个基础对象数组,对象上有一个属性表示是否选中。
- 在计算属性的get()来做返回的结果值。
- 在计算属性的set()里来修改源头数组对象的表示是否选中的属性值,进而让get()得到的值发生改变。
全选与全不选实际步骤
-
在vuex中定义好state并引入到单文件组件中的计算属性。
-
/src/store/index.js
import Vue from "vue"; import Vuex from "vuex";import api from "../http/index";Vue.use(Vuex);export default new Vuex.Store({state: {list: null,},mutations: {changeList(state, payload) {// 默认添加选中状态payload.map((item) => {item.selected = true;return item;});state.list = payload;},},actions: {async getCartListAsync({ commit }) {try {let res = await api.getCartList();console.log(`res-->`, res);let { data, resultCode } = res;if (+resultCode !== 200) {commit("changeList", []);return;}commit("changeList", data);} catch (err) {console.log(`err-->`, err);}},}, });
-
-
或者是在单文件组件里的data或computed中定义好要用的基础对象数组。
-
/src/views/CartView.vue
<script> import { mapState, mapActions } from "vuex"; export default {computed: {...mapState(["list"]),},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
-
在计算属性的get()来做返回的结果值,通过基础对象数组的every()函数。
-
/src/views/CartView.vue
<script> import { mapState, mapActions } from "vuex"; export default {computed: {...mapState(["list"]),checkedAll: {get() {return this.list?.every((item) => item.selected === true);},},},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
-
在计算属性的set()里来通过基础对象数组map()修改源头数组对象的表示是否选中的属性值,进而让get()得到的值发生改变。
-
/src/views/CartView.vue
<script> import { mapState, mapActions } from "vuex"; export default {computed: {...mapState(["list"]),checkedAll: {set(value) {this.list?.map((item) => {item.selected = value;return item;});},},},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
/src/views/CartView.vue
完整<template><div class="cart-wrap"><div class="content"><van-swipe-cell v-for="item in list" :key="item.goodsId"><div class="item"><van-checkboxv-model="item.selected"checked-color="#1BAEAE"></van-checkbox><img :src="item.goodsCoverImg" alt="" /><div><p>{{ item.goodsName }}</p><h3><span>¥{{ item.sellingPrice }}</span><van-stepper v-model="item.goodsCount" /></h3></div></div><template #right><van-button square text="删除" type="danger" class="delete-button" /></template></van-swipe-cell></div><van-submit-bar:price="allPrice"button-text="结算"button-color="#1BAEAE"><van-checkbox v-model="checkedAll">全选</van-checkbox></van-submit-bar></div> </template><script> import { mapState, mapActions } from "vuex"; export default {data() {return {};},computed: {...mapState(["list"]),checkedAll: {get() {return this.list?.every((item) => item.selected === true);},set(value) {this.list?.map((item) => {item.selected = value;return item;});},},allPrice() {return this.list?.reduce((res, item) => {return (res + (item.selected ? item.sellingPrice * item.goodsCount * 100 : 0));},0);},},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
总价计算
总价计算思路
- 在data或computed中定义一个基础对象数组,对象上有想要进行计算所需的全部数据。
- 在计算属性的get()来做返回的结果值或计算属性的函数式写法中计算出想要的结果。
总价计算步骤
-
在vuex中定义好state并引入到单文件组件中的计算属性。
-
/src/store/index.js
import Vue from "vue"; import Vuex from "vuex";import api from "../http/index";Vue.use(Vuex);export default new Vuex.Store({state: {list: null,},mutations: {changeList(state, payload) {// 默认添加选中状态payload.map((item) => {item.selected = true;return item;});state.list = payload;},},actions: {async getCartListAsync({ commit }) {try {let res = await api.getCartList();console.log(`res-->`, res);let { data, resultCode } = res;if (+resultCode !== 200) {commit("changeList", []);return;}commit("changeList", data);} catch (err) {console.log(`err-->`, err);}},}, });
-
-
在data或computed中定义一个基础对象数组,对象上有想要进行计算所需的全部数据。
-
/src/views/CartView.vue
<script> import { mapState, mapActions } from "vuex"; export default {computed: {...mapState(["list"]),},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
-
在计算属性的函数式写法中用reduce()计算出想要的结果。
-
/src/views/CartView.vue
<script> import { mapState, mapActions } from "vuex"; export default {data() {return {};},computed: {...mapState(["list"]),allPrice() {return this.list?.reduce((res, item) => {return (res + (item.selected ? item.sellingPrice * item.goodsCount * 100 : 0));},0);},},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
/src/views/CartView.vue
完整<template><div class="cart-wrap"><div class="content"><van-swipe-cell v-for="item in list" :key="item.goodsId"><div class="item"><van-checkboxv-model="item.selected"checked-color="#1BAEAE"></van-checkbox><img :src="item.goodsCoverImg" alt="" /><div><p>{{ item.goodsName }}</p><h3><span>¥{{ item.sellingPrice }}</span><van-stepper v-model="item.goodsCount" /></h3></div></div><template #right><van-button square text="删除" type="danger" class="delete-button" /></template></van-swipe-cell></div><van-submit-bar:price="allPrice"button-text="结算"button-color="#1BAEAE"><van-checkbox v-model="checkedAll">全选</van-checkbox></van-submit-bar></div> </template><script> import { mapState, mapActions } from "vuex"; export default {data() {return {};},computed: {...mapState(["list"]),checkedAll: {get() {return this.list?.every((item) => item.selected === true);},set(value) {this.list?.map((item) => {item.selected = value;return item;});},},allPrice() {return this.list?.reduce((res, item) => {return (res + (item.selected ? item.sellingPrice * item.goodsCount * 100 : 0));},0);},},created() {if (this.list === null) {this.getCartListAsync();}},methods: {...mapActions(["getCartListAsync"]),}, }; </script>
-
进阶参考
- 新峰商城
- vant2 – 配合vue2
- Blob的三种应用场景及Blob,url,base64之间的转换
- 为什么视频网站的视频链接地址是blob?
相关文章:
20230504----重返学习-vue2项目-跳转拦截-重定向并返回前一页-使用vuex调用接口-全选与全不选-总价计算
day-061-sixty-one-20230504-vue2项目-跳转拦截-重定向并返回前一页-使用vuex调用接口-全选与全不选-总价计算 vue2项目 跳转拦截 设置跳转拦截,比如在用户没token时,不能进入具体详情页,而是进入登录页进行登录。 跳转拦截具体思路 前端…...

(异或相消)猫猫数字异或和
E - Red Scarf (atcoder.jp) 刚入坑写的一道题被我拉出来对比分析了 我的思路: 垃圾运气选手凭借直觉乱搞猜出来的,没有思路。 题解思路: 由问题陈述中XOR的定义,我们可以看出计算3个或更多整数的XOR可以以任意顺序进行&#…...

树脂塞孔有哪些优缺点及应用?
树脂塞孔的概述 树脂塞孔就是利用导电或者非导电树脂,通过印刷,利用一切可能的方式,在机械通孔、机械盲埋孔等各种类型的孔内进行填充,实现塞孔的目的。 树脂塞孔的目的 1 树脂填充各种盲埋孔之后,利于层压的真空下…...

【Robot Framework】RF关键字大全
收录工作当中最常用的Robot Framework关键字 内容较多,可以CtrlF快速搜索自己想要的 1. RF循环使用(FOR循环) {list1} create list LOG TXT INI INF C CPP JAVA JS CSS LRC H ASM S ASP FOR ${file_type} IN {list1} log 构造请求参数 ${t…...

Xilinx Artix-7【XC7A35T-2CSG324I】【XC7A35T-1CSG324I】成本与收发器优化的FPGA器件
产品介绍: Xilinx Artix -7系列 FPGA 重新定义了成本敏感型解决方案,功耗比上一代产品降低了一半,同时为高带宽应用提供一流的收发器和信号处理能力。这些设备基于 28 纳米 HPL 工艺构建,提供一流的性能功耗比。与 MicroBlaze™ 软…...
K8S之自定义Controller
简介 在此之前我们先来了解下kubernetes的两个概念"声明式API"和"控制器模式"。"声明式API"核心原理就是当用户向kubernetes提交了一个API对象的描述后,Kubernetes会负责为你保证整个集群里各项资源的状态,都与你的API对象…...

无线电相关的SCI期刊有哪些? - 易智编译EaseEditing
以下是几个无线电相关的SCI期刊: IEEE Transactions on Wireless Communications: 这是一个IEEE无线通信协会的期刊,主要涵盖了无线通信领域的最新研究进展,包括无线网络,通信系统和信号处理等方面。 IEEE Transacti…...
Rust - 结构体基本使用
基础代码示例 为了理解何时需要使用结构体,官方文档给了一个案例,就是计算长方形的面积,这里我们会一步一步的重构代码直到使用结构体为止。 计算长方形的面积的具体逻辑就是获取长方形的宽度和高度,然后通过公式计算出长方形的…...
29. Kubernetes 核心组件讲解——Controller Manager
本章讲解知识点 Controller Manager 概述Replication ControllerNode ControllerResourceQuota ControllerNamespace ControllerService Controller 与 Endpoint Controller1. Controller Manager 概述 1.1 基本概念 一般来说,智能系统和自动系统通常会通过一个“操作系统”…...
BetaFlight统一硬件配置文件研读之feature命令
BetaFlight统一硬件配置文件研读之feature命令 1. 源由2. 代码分析3. 实例分析4. 配置情况4.1 feature4.2 feature list4.3 feature feature_name4.4 feature -feature_name 5. 参考资料 统一硬件配置文件的设计是一种非常好的设计模式,可以将硬件和软件的工作进行解…...

ChatGPT 不好用?那你看下这份 Prompt 工程指南
作为大型语言模型接口,ChatGPT 生成的响应令人刮目相看,然而,解锁其真正威力的关键还是在于提示工程。 在本文中,我们将揭示制作提示的专家级技巧,以生成更准确、更有意义的响应。无论你使用 ChatGPT 是为了服务客户、…...

冲浪杂记——
华为od是指什么? 华为OD(Open Developer Platform)是华为面向全球开发者推出的开放平台,旨在为开发者提供丰富的技术资源和开发工具,支持开发者快速构建基于华为技术的应用程序、解决方案和服务。华为OD平台为开发者提…...
深入理解Python中的进程与线程
前言 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务并发的执行,从而…...
Data retry场景介绍
本文介绍PDN激活失败或者IP Address缺失时的处理机制。 终端是否会retry? 如何设置data retry timer? Modem retry还是上层应用发起retry? IPV4V6 Fallback 3GPP TS 24.008 6.1.3.1定义了UE使用IPV4V6 pdp type建PDN失败后,如果网络以#Cause50、#Cause51或者#Cause52 …...

lua | 数组与迭代器的使用
目录 一、数组 一维数组 多维数组 二、迭代器 泛型for迭代器 无状态的迭代器 多状态的迭代器 本文章为笔者学习分享 学习网站:Lua 基本语法 | 菜鸟教程 一、数组 数组:相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数…...

【云原生】云原生服务网格流量控制思考
文章目录 前言一、什么是流量控制?二、存在三种场景三、场景分析 前言 随着云原生技术的不断发展及应用,很多服务都已部署上云。 保障云上环境的稳定是重要的一环。 一个重要的影响稳定的场景就是突发大流量冲击。 面对该场景,较好的应对…...
《数据库的嵌套查询和统计查询》
选择Study数据库,用SQL语句进行以下查询操作。 1.嵌套查询 ①求选修了数据结构的学生学号和成绩。 SELECT Sno, grade FROM sc WHERE Cno 007;②求007课程的成绩高于于文轩的学生学号和成绩。 SELECT Sno, grade FROM sc WHERE Cno 007 AND grade …...

【网站架构】Nginx 4层、7层代理配置,正向代理、反向代理详解
大家好,欢迎来到停止重构的频道。 本期我们讨论网络代理。 在往期《大型网站 安全性》介绍过,出于网络安全的考虑,一般大型网站都需要做网络区域隔离,以防止攻击者直接操控服务器。 网站系统的应用及数据库都会放在这个网络安全…...

mysql备份和恢复
mysql备份和恢复 数据丢失的原因: 程序错误 人为操作错误 运算错误 磁盘故障 灾难(火灾,地震)和盗窃 数据库备份分类 物理备份 数据库此操作系统的物理文件(数据文件,日志文件等)的备份 …...

新闻月刊 | GBASE 4月市场动态一览
产品动态 4月,GBASE南大通用大规模分布式并行数据库GBase 8a MPP Cluster中标人保财险“2022年基础软件产品及服务采购”项目。这是自2019年GBASE与人保财险达成合作以来支持建设的第三期项目。项目上线后,将极大满足人保财险大数据中心及研发中心的增量…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...

【Qt】控件 QWidget
控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态:enabled几何:geometrywindows frame 窗口框架的影响 窗口标题:windowTitle窗口图标:windowIconqrc 机制 窗口不透明度:windowOpacity光标:cursor…...

多模态大语言模型arxiv论文略读(112)
Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文标题:Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文作者:Jea…...