上一篇:VUE2项目:尚品汇VUE-CLI脚手架初始化项目以及路由组件分析(一)
项目需要使用到请求与响应的拦截器,分别在请求前与响应后做一些请求的响应处理,使用request.js文件对axios
进行封装,前提是需要安装axios
。
安装:npm install --save axios
import axios from "axios";
// 引入进度条
import nprogress from 'nprogress';
// 引入进度条样式
import "nprogress/nprogress.css"
const requests = axios.create({
//基础路径,发请求会带上api,每个路径的前缀
baseURL: "/api",//对应vue.config文件里面的proxy代理
//请求不能超过5S
timeout: 5000,
});
//请求拦截器(可以在请求发出去之前,做一些事情)
requests.interceptors.request.use((config) => {
//config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
//响应成功,进度条开始
nprogress.start();
return config;
});
//响应拦截器(在数据返回之后,做一些事情)
requests.interceptors.response.use(
(res) => {
//响应成功,进度条结束
nprogress.done();
return res.data;
},
(err) => {
//响应失败
return Promise.reject(new Error("Fail"))
}
);
// 对外暴露
export default requests;
API接口统一在api文件夹下的index.js
进行管理
import requests from "./request"
// 获取商品三级分类数据
export const reqCategoryList = ()=>{
return requests({
url: "/product/getBaseCategoryList",
method: "get"
})
}
若仅仅发的是接口,还需要解决代理跨域问题,所谓的跨域问题就是前后端的访问地址的协议,域名,端口号有一个不一样就需要跨域,前端在vue全局配置文件vue.config.js
进行配置:
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
// vue配置代理跨域
devServer: {
proxy: {
'/api': {
target: "http://gmall-h5-api.atguigu.cn",
},
}
},
})
为了让用户更加直观的看到页面的加载情况,现引入nprogress
插件。
效果如下:
安装:npm install --save nprogress
使用步骤很简单,引入进度条,引入样式,请求响应开始与结束时候调用方法即可。
相当于一个仓库来集中管理组件中的数据,详细请参考vuex。
安装:npm install --save vuex
数据过多,可以使用vuex的模块化开发,将大仓库中放入各个模块下的数据。
在store文件夹下的index.js作为总的配置文件:
index.js:这里相当于一个大仓库,集成了其它小仓库中的数据,并对外暴露。
import Vue from "vue";
import Vuex from "vuex";
// 使用插件
Vue.use(Vuex)
import search from "./search";
import home from "./home";
// 对外暴漏
export default new Vuex.Store({
modules: {
home,
search
}
})
随后导入仓库并注册:
下面的步骤就是将之前的商品的三级分类存储到vuex仓库中,具体步骤如下:
导入接口
导入之前在api下定义的请求三级分类的接口:
import { mapState } from 'vuex';
<div class="type-nav" @mouseenter="enterShow" @mouseleave="enterShowLeave()">
<div class="container">
<h2 class="all">全部商品分类h2>
<div @mouseleave="changeIndex(-1)">
<transition name="sort">
<div class="sort" v-show="show">
<div class="all-sort-list2" @click="goSearch">
<div class="item bo" v-for="(c1, index) in categoryList" :key="c1.categoryId"
:class="{ cur: currentIndex == index }">
<h3 @mouseenter="changeIndex(index)">
<a :data-categoryName="c1.categoryName" :data-category1Id="c1.categoryId">{{
c1.categoryName
}}a>
h3>
<div class="item-list clearfix">
<div class="subitem" v-for="c2 in c1.categoryChild" :key="c2.categoryId">
<dl class="fore">
<dt>
<a :data-categoryName="c2.categoryName" :data-category2Id="c2.categoryId">{{
c2.categoryName }}a>
dt>
<dd>
<em v-for="c3 in c2.categoryChild" :key="c3.categoryId">
<a :data-categoryName="c3.categoryName"
:data-category3Id="c3.categoryId">{{
c3.categoryName }}a>
em>
dd>
dl>
div>
div>
div>
div>
div>
transition>
div>
<nav class="nav">
<a href="###">服装城a>
<a href="###">美妆馆a>
<a href="###">尚品汇超市a>
<a href="###">全球购a>
<a href="###">闪购a>
<a href="###">团购a>
<a href="###">有趣a>
<a href="###">秒杀a>
nav>
div>
div>
我们希望鼠标在分类上移动时会有背景颜色的显示:
有两种方案,直接在导航栏中改样式即可:
或者使用导航的索引进行JS的方式进行控制,先声明变量:
data() {
return {
// 鼠标位置,用来实现鼠标移入三级联动的样式
currentIndex: -1,
show: true
}
},
鼠标监听索引的方法,这里需要使用节流的方式,不然鼠标滑动的时候会有卡顿的现象。
所谓节流就是,连续触发事件但是在 n 秒中只执行一次函数。
导入我们所需要的节流函数:
import throttle from 'lodash/throttle';
使用:
定义样式是否展示的方法:
enterShow() {
this.show = true;
},
对导航栏的样式进行监听:
可以使用JS来控制二三级的分类与隐藏:
触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新再次触发事件并延长触发的时间。
有些事件比如mousemove
,mousehover
等,我们需要做限制保证它们不被频繁的被触发。
点击三级路由跳转到对应的搜索页面,需要将一二三级的分类名称与ID带入路径参数中:
使用编程式导航+事件委派机制的方式实现:
点击对应的分类将分类的名称与ID带入路径参数中:
添加方法:
goSearch(event) {
// 编程式导航+事件委派
// 事件委派就是将所有的子节点的事件全部委托给父亲节点,点击a标签才会跳转
// 事件委派会将所有的子节点交给父节点.data-categoryName区别为a标签
// 获取到当前鼠标点击的标签
let element = event.target;
let { categoryname, category1id, category2id, category3id } = element.dataset;
// 如果有categoryname则一定是a标签
if (categoryname) {
// 跳转路由的参数
let location = { name: 'search' };
let query = { categoryName: categoryname };
// 区分一级,二级。三级a标签
if (category1id) {
query.category1Id = category1id;
} else if (category2id) {
query.category2Id = category2id;
} else {
query.category3Id = category3id;
}
// 判断,如果路由跳转,带有params参数,传递过去
if (this.$route.params) {
location.params = this.$route.params;
location.query = query;
this.$router.push(location);
}
}
},