note
1. vue模块开发
- 当项目比较大,组件通信数据比较复杂,这种情况在使用vuex Vuex是插件,通过vuex仓库进行存储项目的数据
- vuex模块式开发【modules】 由于项目体积比较大,你向服务器发请求的接口过多,服务器返回的数据也会很多,如果还用以前的方式存储数据,导致vuex中的state数据格式比较复杂。采用vuex模块式管理数据。 Vuex核心概念:state、actions、mutations、getters、modules
1:重写push与replace方法 工作的时候想处理掉,不想处理对于你的程序没有任何影响 function push(){ return new Promise(resolve,reject){
}
}
2. 商品分类三级联动展示动态数据
1.数据的获取,在组件中使用获取数据的方法
- TypeNav三级联动展示动态数据,全局组件,放在component中
- 组件挂载完毕,发送请求,通知vue发送请求,获取数据,存储于仓库中 TypeNav/index.js
- 挂载的时候发送请求,获取数据。用计算属性“接”返回的数据
mounted() {
// 通知vue发送请求,获取数据,存储于仓库中
this.$store.dispatch("categoryList");
},
computed: {
// 对象写法:name:函数(1. 会注入一个参数state,是大仓库的数据 2. 当使用此计算属性时,此函数会立即被调用)
...mapState({
categoryList: (state) => {
return state.home.categoryList;
},
}),
},
-
以前基础课程的时候,发请求操作如下:在组件的mounted中书写axios.get||post,获取到数据存储到组件的data当中进行使用
-
你们写项目的时候发请求在哪里发呀? mounted|created:都可以 mounted:模板已经变为真是DOM【只不过没有数据,显示空白】,因为ajax是异步,需要时间的。 created:稍微好那么一丢丢(不算啥)
2.数据结构的分析
[
{
id:1,categoryName:'图书',
child:[
{id:3.14,
categoryName:'影像',
child:[
{id:4,categoryName:'华为'}
]
}
]
}
]
// 根据返回的数组,使用v-for
3.vuex 中的共享数据,请求数据的方法
store/search.js
- 在actions中发送异步的数据请求
reqCategoryList,根据返回状态调用mutations里的方法[[06async 与 await]] - 在mutations里面修改数据
- 根据返回的数组的类型,在state中为数据设初始值
const state = {
//* state中的默认初始值不要瞎写,与服务器返回值类型一致
categoryList: []
};
const mutations = {
GATEGORYLIST(state, categoryList) {
state.categoryList = categoryList;
}
};
const actions = {
async categoryList({ commit }) {
// 通过api里面的函数接口调用,想服务器发请求,获取数据.根据接口的返回值初始化
let result = await reqCategoryList();
// console.log(result);
if (result.code == 200) {
commit("GATEGORYLIST", result.data)
}
}
};
4.跨域问题的解决
[[vue_cli#13 vue脚手架配置代理服务器]] [[05跨域]] 本地代理服务器 vue.config,js
//*配置代理跨域
// !服务器与服务器之间无跨域问题,浏览器与服务器有
devServer: {
proxy: {
"/api": {
target: "http://gmall-h5-api.atguigu.cn",
},
},
}
3. 三级联动动态背景颜色
第一种解决方案:CSS hover 怎么接单怎么来
- 设置一个currentIndex存储用户鼠标移到了哪一个一级分类,并设置changeIndex,leaveIndex改变currentIndex的值
data() {
return {
// 存储用户鼠标移到了哪一个一级分类
currentIndex: -1, //*
};
},
methods: {
// 鼠标进入,修改currentIndex
changeIndex(index) {
// index:鼠标移到哪一个一级分类的索引值
this.currentIndex = index;
},
leaveIndex() {
// 鼠标移出
this.currentIndex = -1;
}
},
- vue的class绑定之对象写法:currentIndex的值与当前index相等,使用此class
<h3 @mouseenter="changeIndex(index)" :class="{ cur: currentIndex == index }">
<a href="">{{ c1.categoryName }}</a>
</h3>
- 时间委托。把mouseleave事件委托给公共的父盒子
<div @mouseleave="leaveIndex">
<h2 class="all">全部商品分类</h2>
<div class="sort">···
</div>
</div>
4. 通过js控制二三级菜单的显示与隐藏
- css方法:display:none/block隐藏与显示二三级菜单
- js :
<!-- 二级分类 -->
<div class="item-list clearfix" :style="{display:currentIndex == index?'block':'none'}">
5.防抖与节流
卡顿现象:用户触发过快。浏览器执行不过来==> 触发多个不重复事件,没有全部执行
@mouseenter="changeIndex(index)" 可能发生
- 正常:事件触发非常频繁,而且每一次的触发,回调函数都要去执行(如果时间很短,而回调函数内部有计算,那么很可能出现浏览器卡顿)
1.防抖
防抖:前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发%%也就是说如果连续快速的触发,只会执行最后一次%%
<body>
<button id="debounce">防抖</button>
<script>
// 防抖
/* 函数防抖是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。 */
function debounce(fn, wait) {
let timer = null;
return function () {
let context = this,
args = arguments;
if (timer) {
clearTimeout(timer);
//清空timer
timer = null;
} else {
timer = setTimeout(() => {
// 用apply改变this走向
fn.apply(context, args);
}, wait);
}
};
}
// 防抖测试
document.querySelector("#debounce").onclick = debounce(() => {
console.log("debounce");
}, 2000);
</script>
2.节流
节流:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发
<body>
<button id="throttle">节流</button>
<script>
// 节流
/* 函数节流是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。 */
function throttle(fn, delay) {
let curTime = Date.now();
// Date.now() 方法返回自 1970 年 1 月 1 日 00:00:00 (UTC) 到当前时间的毫秒数。
return function () {
let nowTime = Date.now(),
context = this,
args = arguments;
// 如果两次时间间隔超过了指定时间,则执行函数
if (nowTime - curTime >= delay) {
fn.apply(context, args);
curTime = Date.now();
}
// !只有触发成功了才会更新时间
};
}
// 节流测试
document.querySelector("#throttle").onclick = throttle(() => {
console.log("throttle");
}, 2000);
</script>
D:\我的学习\前端\基础算法\手撕\02防抖节流.html
- 防抖与节流的原理,通过JS实现【闭包 + 延迟器】
3.三级联动的节流操作
- 引入
lodash,node_modules中已经引入
import throttle from 'lodash/throttle';//按需引入,throttle默认暴露,不需要加{}
methods: {
// 鼠标进入,修改currentIndex
// changeIndex(index) {
// // index:鼠标移到哪一个一级分类的索引值
// this.currentIndex = index;
// console.log("鼠标进入"+index);
// },
changeIndex: throttle(function (index) {
// throttle不要使用箭头函数,可能出现this问题
this.currentIndex = index;
console.log("鼠标进入" + index);
}, 50),
},
6.三级联动路由跳转与传参
1. 需求分析
- 路由跳转-参数传递:
categoryNamecategoryId%%路由跳转的时候【home->search】:需要进行路由传递参数【分类的名字、一、二、三级分类的id】%% - 卡顿现象-编程式路由导航 %%三级分类由于使用router-link的时候,会出现卡顿现象,因此采用编程式导航。 两种路由导航
- 声明式导航:为什么使用router-link组件的时候,会出现卡顿那? router-link是一个组件:相当于VueComponent类的实例对象,当服务端返回数据后,会循环出很多router-link组件,一瞬间 new VueComponent很多实例(1000+),很消耗内存,因此导致卡顿。
- 编程式导航:push|replace%%
- 要绑定的路由跳转事件太多===>事件委派
2.解决方案
编程式导航+事件委派 ===>路由跳转+传参数 存在问题:使用事件委派后,如何辨别点击的时目标标签?如何辨别点击时几级标签?自定义属性 新知识: 1. element.dataset,存储当前节点的自定义属性与属性值 2. 浏览器会自动把自定义属性的名字全部改为小写 %%事件委派,把所有的子节点都(h3,3m,dt,dl)等都委托给父节点。但当点击a标签的时候,才会进行跳转。
- 如何辨别点击的目标标签?如何辨别点击时几级标签? 解决方案:a标签加上自定义属性,event.target (触发当前事件的dom元素)%%
- 加上自定义属性
<a
:data-categoryName="c1.categoryName"
:data-category1Id="c1.categoryId"
>{{ c1.categoryName }}</a>
- 根据自定义属性判断a标签,是几级标签
- 整理路由参数location
goSearch(event) {
let element = event.target;
// 1. element.dataset,存储当前节点的自定义属性与属性值
// 2. 浏览器会自动把自定义属性的名字全部改为小写
let { categoryname, category1id, category2id, category3id } = element.dataset;//对象的解构赋值
// todo 整理路由参数
let location = { name: 'Search' };
let query = { categoryName: categoryname }
// *判断是否为a标签:自定义标签上有categoryname的是a标签
// *判断为几级标签:自定义标签是category1id,还是category2id,还是category3id
if (categoryname) {
if (category1id) {
query.category1Id = category1id
} else if (category2id) {
query.category2Id = category2id
} else if (category3id) {
query.category3Id = category3id
}
}
// todo 路由参数整理完毕
location.query = query;
// todo路由跳转
this.$router.push(location)
}
location 内部结构示例
this.$router.push()
{
name:'search',
query:{
categoryName:'电子书',
category2Id:4
}
}
question
报错
1. Uncaught ReferenceError: VueX is not defined vuex的模块化与一般形式
面试
1.性能优化
v-if|v-show 按需加载 函数防抖与节流 按需加载:对于loadsh插件,它里面封装的函数功能很多;import _ from lodash 相当于把全部功能引入进来,但是我们只是需要节流。