【Vue项目】商品汇前台(二)进度条插件+Vuex模块化仓库+函数的防抖与节流+路由传参
前言
1 nprogress进度条的使用
当请求发出进度条出现并向前走,请求成功后进度条消失。nprogress是一种进度条插件
1.1 nprogress进度条插件安装
npm i --save nprogress
随后可以在package.json中查看到安装的nprogress插件。
1.2 nprogress进度条插件的使用
①在对axios封装的请求和响应拦截器中使用nprogress的start和done方法
②引入进度条的样式,否则进度条不会显示
api/request.js
// 对axios进行二次封装
import axios from 'axios'
// 引入进度条
import nprogress from 'nprogress'
// 引入进度条样式
import 'nprogress/nprogress.css'
// 1 利用axios create创建一个axios实例
// 2 requests就是配置参数后的axios实例
const requests = axios.create({
// 基础路径,请求发出的时候,路径前面就会出现api
baseURL: '/api',
// 设置请求超出事件
timeout: 5000
})
// 请求拦截器,在请求发出之前能够检测到,做一些指定的业务
requests.interceptors.request.use((config)=>{
nprogress.start();
// 参数为config的回调函数
// config为配置对象,包含一个中要的属性headers请求头
return config;
});
requests.interceptors.response.use((res)=>{
nprogress.done();
// 响应成功的回调函数
return res.data;
}, error=>{
// 响应失败的回调函数
// 终止promise链
return Promise.reject(new Error('faile'))
})
export default requests;
③通过修改样式文件改变进度条的颜色
#nprogress .bar {
background: #e1251b;
2 Vuex模块式开发
Vuex是Vue官方提供的一个状态管理库插件,集中式管理项目中共用的数据。具体内容可以参考我之前写的这篇博文:【Vue】Vuex - Tod4 - 博客园
2.1 Vuex的安装
npm i vuex@3
2.2 Vuex的模块化
当项目很大的时候,几百个数据都放在数据仓库的state中就会显得十分臃肿,因此需要采用模块化的方法对这些数据进行模块化管理。
Vuex的模块化,就是将整个的大仓库按照模块划分为小仓库:在store文件夹下建立各模块文件夹和index.js,模块文件夹中的index.js包含模块的state,actions,mutations,getters并将它们都进行默认暴露,最后由总仓库外层index.js整合并暴露为一个vuex.Store。
search模块的index.js:
const actions = {
}
const mutations = {
}
const getters = {
}
const state = {
}
// 将模块仓库内容对外暴露
export default {
state,
actions,
mutations,
getters
}
home模块的index.js:
const actions = {
}
const mutations = {
}
const getters = {
}
const state = {
}
// 将模块仓库内容对外暴露
export default {
state,
actions,
mutations,
getters
}
/store/index.js
import vue from 'vue'
import vuex from 'vuex'
import home from './home'
import search from './search'
vue.use(vuex)
export default new vuex.Store({
modules: {
home, search
}
})
3 typeNav三级联动数据动态展示
3.1 组件通知Vuex向服务器发送数据
<script>
export default {
name: 'TypeNav',
mounted() {
// 通知vuex向服务器发送数据,并存储于home数据仓库中
this.$store.dispatch('CategoryList');
}
}
</script>
组件向Vuex dispatch CategoryList会调用Vuex actions中的CategoryList()方法
3.2 Vuex actions 通过api中的函数调用,向服务器发送请求,获取服务器数据
const actions = {
// 通过api中的函数调用,向服务器发送请求,获取服务器数据
async CategoryList(context) {
let result = await reqCategoryList();
if(result.code === 200) {
context.commit('CATEGORYLIST', result.data)
}
}
}
actions方法主要包含处理action和一些服务器请求,因此可以在actions的CategoryList()方法中通过api中的函数调用,向服务器发送请求,获取服务器数据;然后actions commit到mutations将获取到的数据进行修改
此外这里的async和await,是因为axios之前进行了二次封装,当请求成功时会返回一个promise,以此来实现异步操作的执行顺序,因此需要使用await得到promise中成功的数据。具体promise的介绍看一看我之前写的博客。
3.3 Vuex mutations修改仓库数据
const mutations = {
CATEGORYLIST(state, CateGoryList) {
state.CateGoryList = CateGoryList;
}
}
3.4Vuex state仓库的初始化定义
const state = {
CateGoryList: [],
}
当数据是对象的时候使用{},是数组的时候使用[]
之前自己写的前端数据的axios请求和处理都是放在script中的,写完之后非常地乱自己都不想再看,写完这部分后才明白当数据量较大时,数据请求和处理应该由模块化的vuex完成并且存储于模块化的数据仓库。
3.5 在typeNav中使用辅助函数mapState存储并显示home仓库数据
方式一:直接$store.state.home.xxx
<div class="item-list clearfix">
<div class="subitem" v-for="(c2, index) in c1.categoryChild" :key="c2.categoryId">
<dl class="fore">
<dt>
<a href="">{{c2.categoryName}}</a>
</dt>
<dd>
<em v-for="(c3, index) in c2.categoryChild" :key="c3.categoryId">
<a href="">{{c3.categoryName}}</a>
</em>
</dd>
</dl>
</div>
</div>
方式二:使用辅助函数mapState生成计算属性
具体mapState的介绍可以参考这篇博客:vuex 中辅助函数mapState的基本用法详解 - 只争朝夕,不负韶华 - 博客园
computed: {
// mapState自动生成计算属性
...mapState({
// 当使用cateGroyList时,右边的函数就会执行
cateGroyList:(state)=>{
return state.home.CateGoryList
}
})
}
当映射的计算属性的名称与 state 的子节点名称相同时,也即是没有模块化satate的时候,可以直接给 mapState 传一个字符串数组:
...mapState(["count", "name"]),
然后直接使用计算属性即可:
<div class="item" v-for="(c1, index) in CateGoryList" :key="c1.categoryId">
<h3>
<a href="">{{c1.categoryName}}</a>
</h3>
<div class="item-list clearfix">
<div class="subitem" v-for="(c2, index) in c1.categoryChild" :key="c2.categoryId">
<dl class="fore">
<dt>
<a href="">{{c2.categoryName}}</a>
</dt>
<dd>
<em v-for="(c3, index) in c2.categoryChild" :key="c3.categoryId">
<a href="">{{c3.categoryName}}</a>
</em>
</dd>
</dl>
</div>
</div>
</div>
3.6 三级联动动态背景颜色
方式一:使用css样式实现
.item:hover{
background: skyblue;
}
方式二:通过js实现
①用一个变量存储当前鼠标所在的索引值
data() {
return {
curIndex: -1
}
},
②使用鼠标事件绑定函数changeIndex
<h3 @mouseenter="changeIndex(index)">
<a href="">{{c1.categoryName}}</a>
</h3>
③在methods中创建changeIndex方法
methods: {
changeIndex(index) {
this.curIndex = index
}
}
如此一来,当鼠标滑动到一个地方,组件就能够获取到所在的索引
④为索引值为当前索引变量值的行添加cur样式
<div class="item" v-for="(c1, index) in CateGoryList" :key="c1.categoryId" :class="{cur:index==curIndex}">
⑤添加移出效果
<div @mouseleave="leaveIndex()">
⑥移出函数
leaveIndex() {
this.curIndex = -1;
},
3.5 通过Js控制二三级分类的显示与隐藏
<div class="item-list clearfix" :style="{display:index==curIndex?'block':'none'}">
4 解决卡顿现象
卡顿现象:事件触发非常平凡,而且每一次触发,回调函数都要去执行,如果时间很短,而且回调函数内部有计算,那么可能会使浏览器反应不过来产生卡顿现象。
4.1 函数防抖、节流 lodash插件的使用
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。中文文档地址:https://www.lodashjs.com/
4.1.1 lodash的安装
npm i --save lodash
4.1.2 lodash的使用
lodash插件里面封装了函数的防抖与节流的业务【闭包+延迟器】,对外暴露_函数。
4.1.3 lodash的防抖函数 _.debounce
防抖:前面的所有触发都会被取消,最后一次执行在规定时间之后才会触发,也就是说连续快速的多次触发,只会执行最后一次。
_.debounce(function, wait),第一个参数为防抖的函数,第二个参数为上面说的规定的时间,返回的函数即为可以防抖的函数。
4.1.3 lodash的节流函数 _.throttle
节流
:在规定的时间内不会重复触发回调,只有大于这个时间间隔才会触发函数回调,把频繁触发变为少量触发。
创建一个节流函数,在 wait 秒内最多执行 func
一次的函数。 该函数提供一个 cancel
方法取消延迟的函数调用以及 flush
方法立即调用。 可以提供一个 options 对象决定如何调用 func
方法, options.leading 与|或 options.trailing 决定 wait 前后如何触发。 func
会传入最后一次传入的参数给这个函数。 随后调用的函数返回是最后一次 func
调用的结果。
4.2 实现三级联动的节流
①引入lodash
import _ from 'lodash'
按需引入,throttle采用的默认暴露:
import throttle from "lodash/throttle";
②采用es5的写法对原函数进行节流封装
methods: {
changeIndex: throttle(function(index){
this.curIndex = index;
}, 50),
leaveIndex() {
this.curIndex = -1;
},
},),
5 typeNav三级联动组件路由跳转和传参
5.1 分析
方式一:对三级标签使用声明式路由导航router-link
router-link会被当做一个组件,当服务器数据返回之后,会循环出很多的router-link组件去创建组件实例,一瞬间创建这么多组件非常消耗内存,可能会造成卡顿现象。
方式二:使用编程式路由导航
这样做的缺陷是每一个标签都有自己的回调函数,循环之后可能出现上千个回调函数。
5.2 使用事件委派到父元素 + 编程式导航
①将三级分类元素的事件委派给父元素
<div class="item"
v-for="(c1, index) in CateGoryList" :key="c1.categoryId"
:class="{cur:index==curIndex}"
@click="goSearch"
>
但是这样存在着两个问题,一个是点击父元素中的所有元素都会触发事件,而我们只是想让三级分类元素的a标签触发;另一个是这样无法获取元素的参数。
②通过自定义属性筛选三级分类子元素
即只为三级分类元素的a标签添加一个自定义属性cateGoryName
<h3 @mouseenter="changeIndex(index)">
<a :data-cateGoryName="c1.categoryName">{{c1.categoryName}}</a>
</h3>
<div class="item-list clearfix" :style="{display:index==curIndex?'block':'none'}">
<div class="subitem" v-for="(c2, index) in c1.categoryChild" :key="c2.categoryId">
<dl class="fore">
<dt>
<a :data-cateGoryName="c2.categoryName">{{c2.categoryName}}</a>
</dt>
<dd>
<em v-for="(c3, index) in c2.categoryChild" :key="c3.categoryId">
<a :data-cateGoryName="c3.categoryName">{{c3.categoryName}}</a>
</em>
</dd>
</dl>
</div>
</div>
然后在goSearch方法中通过dataset获取自定义属性判断有没有cateGoryName的方式,判断元素是不是三级分类的a标签,如此一来便实现了只有三级分类的a标签才能进行路由跳转的功能。
只有使用 data- 声明的自定义属性,dataset才能够检测到
goSearch(event) {
let element = event.target;
let {categoryname} = element.dataset;
if(categoryname)
this.$router.push({name:'search'})
}
自定义属性经过编译之后全部变为了小写,所以这是写的是categoryname
③通过添加自定义属性分别三级分类
通过添加一个自定义属性cateGoryId判断当前是哪一级标签触发了事件。
<h3 @mouseenter="changeIndex(index)">
<a :data-cateGoryName="c1.categoryName" :data-cateGory1Id="c1.categoryId">{{c1.categoryName}}</a>
</h3>
<div class="item-list clearfix" :style="{display:index==curIndex?'block':'none'}">
<div class="subitem" v-for="(c2, index) 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, index) in c2.categoryChild" :key="c3.categoryId">
<a :data-cateGoryName="c3.categoryName" :data-cateGory3Id="c3.categoryId">{{c3.categoryName}}</a>
</em>
</dd>
</dl>
</div>
</div>
在goSearch方法中进行参数真理和路由转发
goSearch(event) {
let element = event.target;
let { categoryname, category1id, category2id, category3id } =
element.dataset;
if (categoryname) {
// 整理参数
let location = {
name: 'search',
};
let query = {
categoryname: categoryname
};
if (category1id) {
query.category1id = category1id;
} else if (category2id) {
query.category2id = category2id;
} else {
query.category3id = category3id;
}
location.query = query;
// 转发路由传递参数
this.$router.push(location)
}
},
【Vue项目】商品汇前台(二)进度条插件+Vuex模块化仓库+函数的防抖与节流+路由传参的更多相关文章
- 在vue项目中使用Nprogress.js进度条
NProgress是一款在网页顶部添加细长进度条的工具,非常轻巧,使用起来也非常便捷,灵感来源于Google, YouTube. 1.安装 $ npm install --save nprogress ...
- vue使用nprogress页面加载进度条
vue使用nprogress页面加载进度条 NProgress是页面跳转是出现在浏览器顶部的进度条 官网:http://ricostacruz.com/nprogress/ github:https: ...
- JQuery中简约的进度条插件推荐
JQuery Progress Bar是基于JQuery开发的进度条插件,秉承了JQuery的简约哲学.不仅容易使用,而且可以轻松定制外观.对于使用了JQuery框架的项目来说,需要使用进度条控件时这 ...
- YprogressBar,html5进度条样式,js进度条插件
简介 YprogressBar是一款基于HTML5的进度条插件. YprogressBar是一款轻量级进度条插件,使用方便,资源占用少,模仿好压的解压界面,带有数字显示,同时支持在描述中增加参数,以动 ...
- 简单实用的纯CSS百分比圆形进度条插件
percircle是一款简单实用的纯CSS百分比圆形进度条插件.你不需要做任何设置,只需要按该圆形进度条插件提供的标准HTML结构来编写代码,就可以生成一个漂亮的百分比圆形进度条. 首先要做的就是引入 ...
- 一个Notification 进度条插件(android,NJS实现,直接就可使用)
参考文章:http://ask.dcloud.net.cn/article/503 源码地址下载 如题,分享一个Notification 进度条插件(android,用js调用原生api实现,直接就可 ...
- 30款基于 jQuery & CSS3 的加载动画和进度条插件
我们所生活每一天看到的新技术或新设计潮流的兴起,Web 开发正处在上升的时代.HTML5 & CSS3 技术的发展让 Web 端可以实现的功能越来越强大. 加载动画和进度条使网站更具吸引力.该 ...
- 基于Jquery的进度条插件(实用)
Spin.js 最喜欢这款插件了,动画图片的长度.粗细.速度和角度都可以灵活控制,想要做成什么样都可以. 源码下载 在线演示 Percentage Loader 一款轻量的 jQuery 进 ...
- 简单的jquery进度条插件LineProgressbar.js,myProgress.js
参考 http://www.lanrenzhijia.com/jquery/4121.html demo下载 <script src="js/jquery.lineProgress ...
- HTML5圆形百分比进度条插件circleChart
在页面中引入jquery和circleChart.min.js文件. <script src="path/to/jquery.min.js"></script&g ...
随机推荐
- centos7安装ffmpeg shell脚本
#!/bin/sh # # Date: 2021-04-28 # Author: yb # Description: 安装ffmpeg # 检测当前用户是否为root [ $(id -u) != &q ...
- 关于lesscss和颜色梯度(linear-gradient )的一些问题
一.什么是less? 一种 动态 样式 语言. LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承,运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, F ...
- 如何用算法把一个十进制数转为十六进制数-C语言基础
这一篇文章要探讨的是"如何用算法实现十进制转十六进制"并不涉及什么特别的知识点.属于C语言基础篇. 在翻找素材的时候,发现一篇以前写的挺有意思的代码,这篇代码里面涉及的知识点没有什 ...
- porps传参
porps传参(最常用的 布尔传值)(基于前面的步骤进行修改) ①index.js //定义动态路由 props:trueconst routes =[ {path:"/user/:id/: ...
- hbase master 无法启动
环境部署: hbase 采用azure的虚机,存储采用azure的blockblob. 问题: 生产碰到过几次,hbase master无法启动的问题,这种情况下是可以正常读写,但是如果这个时候,发生 ...
- 01 ansible的基本介绍
1.现有的企业服务器环境 在现在的企业中,特别是互联网公司,他们的业务量众多:比如负载均衡服务器.web服务器.动态解析(php)服务器.数据库(mysql)服务器以及网站缓存服务器,等等: 例如:一 ...
- MATLAB默认路径修改
笔者曾尝试在软件界面的"设置路径"或者Parallel中修改默认路径,但多次尝试均失败.后来经人提点,MATLAB默认文件夹路径可以在桌面图标属性中"起始位置" ...
- 解决com.alibaba.excel.exception.ExcelGenerateException: Can not close IO.
我在使用easycel导出到zip包中时,出现了这个问题.各种文件输出时产生的问题其实大同小异 查看了一些网上的文章,还有github上关于此bug的issue,总算是理清并解决了. 解决方法一 主要 ...
- mock数据规则
Mock数据规则 随机生成100条内的list数据 let Mock = require("mockjs"); let basicData = Mock.mock({ " ...
- WSL安装Ubuntu 22.04 (2)
1.安装系统环境 1.1.设置软件包源为国内镜像 参考:Ubuntu更换国内镜像源 - 知乎 1.2.更新系统软件包 sudo apt-get update && sudo apt-g ...