1. vue过渡动画
vue提供过渡动画效果,过渡动画效果[原生DOM标签、自定义标签(组件)]
前提:标签、组件必须使用v-if | v-show,让元素可以显示与隐藏
-
在template标签中使用transition标签包裹要添加过渡动画的标签。
-
可以给过渡动画起单独的名字,在transition标签的name属性添加
-
在style标签中使用 以下,添加属性
进入阶段:
name(起的名字)-enter 起始效果
name-enter-active 过渡所需的属性(transition)
name-enter-to 最终效果
离开阶段:
name(起的名字)-leave
name-leave-active
name-leave-to
2.组件通信
##1. props: 父子组件通信
父组件给子组件传递是非函数,父亲要给儿子传递参数
父组件给子组件传递函数,实质就是子组件给父组件传递参数
##2. pubsub:react + 微信小程序
##3. 自定义事件
DOM事件:原生DOM事件 --> onclick | ondbclick | focus | blur
1:事件源
2:事件类型
3:事件回调函数
4:事件回调函数触发,注入event
自定义事件:可以实现(组件)通信,子组件给父组件传递参数.
自定义事件:当前事件源通过$emit触发的 [N个参数]
原生DOM:浏览器自动触发[事件对象]
注意:1
自定义事件,子组件给父组件传递参数[组件]
HTML标签绑定自定义事件没有任何意义,没办法调用$emit方法
注意2:
只要是组件身上书写@百分百自定义事件 click|erha|taidi|focus
##4. ref可以实现父子组件通信
5 全局事件的总线$bus
作用:可以实现任意组件通信[兄弟、父子、子父、隔辈…],类似于pubsub[发布、订阅]
o
n
与
on与
on与emit
全局事件总线:可以实现任意组件之间通信[兄弟、父子、子父、隔辈…],
全局事件总线,其实就是自定义事件升级版
VM与VC的关系?*****
VM的原型[Vue.prototype]与VC的原型的原型[Vue.prototype]指向同一个人
注意:VM与VC的关系—>VM的原型与VC的原型的原型指向同一个人—Vue.prototype
全局事件总线使用步骤:
第一步:在入口文件配置全局实现总线
b
u
s
第二步
:
t
h
i
s
.
bus 第二步:this.
bus 第二步:this.bus.
o
n
∣
t
h
i
s
.
on|this.
on∣this.bus.$emit
6. slot 插槽
7. Vuex
#3. vue使用axios发请求?
什么是ajax?
ajax是一门技术,在页面没有刷新的情况下,可以实现页面局部更新的技术。
常用的状态码?
code: 200 | 404 | 304 | 500
##3.1 axios发请求的语法
axios.get | axios.post
axios({
url:‘’,
methods:‘’,
data:{}
})
代理跨域:路径重写pathRewrite,看后台接口文档去确定要不要重写
4.代理跨域
在vue.config.js中设置如下
devServer: {
open: true,
host: "localhost", (也可以写成 127.0.0.1)
port: 8080, (端口号)
proxy: {
'/api': { (当路径中以有 /api 开头时,会执行工作)
target: 'http://localhost:3000',
pathRewrite: { '^/api': '' }, (路径重写,当路径含有api会在向后台服务器发请求时去除)
},
},
},
5.vuex
vuex集中式管理状态容器管理项目的数据
##5.1 vuex 核心概念
state
mutations
actions
getters
modules:vuex 仓库可以模块化管理
vuex优点:集中式管理数据,全部vc共享数据!!!
##5.2 vuex模块化管理state说明
state = { a:1, b: 2 } // 大仓库
state = { home: { a: 1 }, search: { b: 2 } }
6.mock接口流程
第一步:安装 mockjs 插件
第二部:在 src / mock 文件夹 — 造的接口在这个文件夹内部
第三步:通过JSON文件造你需要的数据
第四步:mockServe.js --> 造假的接口 Mock.mock
第五步:在入口文件需要引入 mockServer.js 一次。让里面的代码执行一次
7.vue-awesome-swiper插件
vue-awesome-swiper是在swiper基础之上进行封装的
使用步骤
第一步:安装 Swiper@5 与 vue-awesome-swiper@4
cnpm i swiper@5 vue-awesome-swiper@4
第二部:在入口文件定义全局组件以及引入样式
import {Swiper, SwiperSlide} from 'vue-awesome-swiper';
// 轮播图需要的样式
import "swiper/css/swiper.min.css";
// 注册轮播图的全局组件
Vue.component('Swiper',Swiper);
Vue.component("SwiperSlide",SwiperSlide);
问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FR491dtl-1677243545237)(C:\Users\24601\AppData\Roaming\Typora\typora-user-images\image-20230210130726991.png)]
发生这个问题是因为 options 配置项出现了 html 结构不存在的内容
8.封装分页器
<template>
<div class="pagination">
<button @click="$emit('getCurrent', current - 1)" :disabled="StartEnd.start==1">上一页</button>
<button @click="$emit('getCurrent', 1)" v-show="StartEnd.start > 1">1</button>
<button v-show="StartEnd.start > 2">···</button>
<button @click="$emit('getCurrent', page)" :class="{'active': page==current}" v-for="(page, index) in StartEnd.end" :key="index" v-show="page >= StartEnd.start">{{page}}</button>
<button v-show="StartEnd.end < totalPage - 1">···</button>
<button @click="$emit('getCurrent', totalPage)" v-show="StartEnd.end < totalPage">{{totalPage}}</button>
<button @click="$emit('getCurrent', current + 1)" :disabled="StartEnd.end==totalPage">下一页</button>
<select v-model="size" @change="$emit('getLimit', size)">
<option value="3">3/页</option>
<option value="5">5/页</option>
<option value="7">7/页</option>
<option value="9">9/页</option>
</select>
<button style="margin-left: 30px">共 {{ total }} 条</button>
</div>
</template>
<script>
export default {
name: "Pagination",
props: ['current', 'pageCount', 'limit', 'total'],
data() {
return {
size: 3
}
},
computed: {
totalPage() {
return Math.ceil(this.total / this.limit);
},
StartEnd() {
let start = 0, end = 0;
let {current, pageCount, totalPage} = this;
if(pageCount > totalPage) {
start = 1;
end = totalPage;
} else {
start = current - 2;
end = current + 2;
if(start < 1) {
start = 1;
end = pageCount;
}
if(end > totalPage) {
end = totalPage;
start = totalPage - pageCount + 1;
}
}
return {start, end};
}
},
}
</script>
<style lang="less" scoped>
.pagination {
button {
margin: 0 5px;
background-color: #f4f4f5;
color: #606266;
outline: none;
border-radius: 2px;
padding: 0 4px;
vertical-align: top;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
border: 0;
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
.select {
width: 80px;
height: 23px;
border: 1px solid #ccc;
outline: none;
}
}
</style>
#9. 持久化存储数据方案
浏览器存储功能
本地存储:localStorage *****
持久化存储数据,浏览器关闭、电脑关机重启,数据还是存在的,只要是在同一域名下,全部页面共享数据
会话存储:sessionStorage
会话存储,网页关闭、电脑关机会话存储的数据即消失
本地存储与会话存储数据的缺点?
浏览器存储数据上限小于5M
10.函数防抖与节流
防抖[debounce]:前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发只会执行一次
节流[throttle]:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发
#面试题
你们公司人员的前端与后端的比例?
一般 1 : 3
闭包:函数套函数,内部函数可以访问外部函数变量。
缺点:由于内部函数一直引用外部函数变量,导致外部函数变量内存泄漏,不会被垃圾回收机制回收
优点:防抖
key 的作用?
v-if与v-show区别?
v-if:销毁创建DOM节点,实现显示与隐藏
v-show: 通过样式dispaly,控制元素的显示与隐藏
项目中性能优化手段有哪些?
v-if 与 v-show 选择,选择 v-show
防抖与节流
事件委派
路由懒加载
按需引入
请求次数优化(typeNav)
cdn 优化
vue-cli脚手架 public 与 assets区别
public: 里面放置的静态资源。原封不动的打包到dist文件夹里面
assets: 放置静态资源,但是在打包的时候assets文件夹里面静态资源会当中webpack一个模块打包到 js | css 文件里面
在项目中如何实现params参数可以传递,也可以不传递?怎么实现?
配置路由的时候在占位的后面加上一个问号,params参数可有可无。
vue路由params参数可以传递,也可以不传递?万一params传递空串怎么解决?
http://127.0.0.1:8080/search/123
http://127.0.0.1:8080/search(传入 ’ ’ 造成路径缺失)
解决方法:params: {keyword: this.keyword || undefind} ( 底层使用undefind进行判断 )
params: {keyword: this.keyword || null}
HTML5新特征有哪些?
—语义化标签:Header、Footer、Main、nav、section、aside… (便于su 搜索优化)
—多媒体 video、audio
—新增表单元素 tel、search、color (颜色选择器)
—CS3: flex布局、选择器、动画 3D | 2D、属性选择器、结构伪类选择器、伪元素选择器、盒子模型 (怪异盒模型、标准盒模型)、过渡
—本地存储 | 会话存储
—canvas | svg
—本地存储 | 会话存储
优点:数据存储持久化的—电脑关机重启还是存在的
缺点:不同浏览器上线大约 5M 左右
1024 KB --> 1 MB 1024MB --> 1 G 1024G --> 1 T
axios二次封装过吗?为什么二次封装?
— 基础路径 以及 超时时间 的配置
— 使用请求、响应拦截器
— 请求拦截器:给服务器携带公共的参数,添加进度条功能
— 响应拦截器:简化数据 + 根据服务器返回的状态码处理不同业务
你在项目当中是否封装通用的组件?
封装过:分页器组件
a:项目封装了一个全局分页器?
b:组件在不copy到B项目中如何使用?
上传到 npm 社区,下载依赖即可
vuex的缺点?
Vuex 存储数据并非持久化,就是用一个破 js 对象存储数据
vuex 核心概念?
state | mutations | actions | getters | modules
优点:集中式管理数据
浏览器存储功能?
localStorage 本地存储
sessionStorage 会话存储
缺点:上限只有 5 MB
GET与 POST 请求的区别?
GET:携带 query 参数有上限的,不安全
POST:携带参数’无上限’(够用),相对安全
Vue前台项目笔记
day 01
创建项目前需要配置好的
vue-cli地址:https://cli.vuejs.org/zh/guide/
nodejs:http://nodejs.p2hp.com/download/
vscode:插件备份 + git + node.js + webpack + vue-cli
vue-router@3 – 3.6.5
axios – 1.3.2
less – 4.1.3
less-loader – 11.1.0
任务
- 项目初始化
- Header、Footer、TypeNav 全局组件
- Home路由组件的实现(List、Recommend、Rank、Like、Floor、Brand、TypeNav)
Vue脚手架文件分析
vue-cli脚手架目录与文件的解释
node_modules: 项目全部依赖的地方[Vue核心源码、babel、eslint、webpack-dev-server]
public: 里面放置的静态资源。原封不动的打包到dist文件夹里面
src: 程序员源代码区域
assets: 放置静态资源,但是在打包的时候assets文件夹里面静态资源会当中webpack一个模块打包到 js | css 文件里面
assets文件夹的静态资源是组件都要使用的
components 文件夹: 项目通用的全局组件
pages / views 文件夹:专门放路由组件的
router 文件夹:专门放路由的
utils 文件夹:一般放置项目通用工具—请求相关的文件
脚手架其他的配置
浏览器自动打开
关闭eslint
// 在 vue.config.js 中进行配置
devServer: {
open: true, // 设置自动打开 (或者在package.json中在serve指令后面添加 --open)
host: '127.0.0.1', // 域名(主机名) (也可以设置为 localhost)
port: 8080, // 端口号
proxy: {
"/api": { // 如果请求以 /api 开头执行工作
"target": 'http://sph-h5-api.atguigu.cn'
// 后端接口携带 /api 则不需要重写
}
}
},
lintOnSave: false // 禁用每次保存时进行 eslint 语法检查
day01项目–操作流程
- 初始化 App.vue 以及 main.js 文件
- 创建 components 文件夹,创建组件 Header 和 Footer
- 在 main.js 文件中将 Header、Footer 组件注册为全局组件(Vue.component(组件.name, 组件))
- 在 App.vue 引入 Header、Footer 组件
- 创建 pages 文件夹,创建 Home、Login、Register、Search 组件
- 创建 router 文件夹,创建 index.js 文件,引入 Home、Login、Register、Search 组件,配置路由(search中需要用到params,使用占位,以及?实现可传可不传, 使用meta设置flag的布尔值,控制Footer组件显示与隐藏)
- 在 main.js 中导入路由
- 在 App.vue 中使用 router-view 标签在 Header与Footer组件实例中间(内容放置区)
- 在 Header 组建的结构中,把相应的 a 标签使用 router-link 代替(声明式导航),search组件使用编程式导航
- 创建全局组件 TypeNav(侧边栏),并在 main.js 注册为全局组件
- 在 Home 路由组件文件夹下创建拆分的组件(List,Recommend,Rank,Like,Floor,Brand),引入结构、样式、以及图片等资源(注意引入路径的问题)
- 在 Home 将拆分的组件注册,并使用
day 02
新安装的依赖
nprogress – 0.2.0 (实现进度条功能)
vuex@3
任务
- axios二次封装
- 封装 api
- 渲染TypeNav页面
- 实现跳转(search页面)
知识点
- axios二次封装
axios 请求相应拦截器 + 进度条 [nprogress插件]
nprogress.start() 进度条开始 (在请求拦截器开启)
nprogress.done() 进度条结束 (在响应拦截器关闭)
- 项目统一管理接口地址(api文件夹)
api文件夹:一般用于统一管理项目接口
- vuex集中式管理状态容器管理项目的数据
state
mutations
actions
getters
modules:vuex 仓库可以模块化管理
4、商品分类数据的展示
4.1一级分类的名字高亮效果
第一种解决方案:样式
第二种解决方案:纯纯js搞定
4.2二级、三级分类显示与隐藏
二级、三级分类显示与隐藏开始的时候,老师们通过样式搞定的!!!
5.路由跳转与携带参数?
typeNav分类组件:路由跳转与携带参数 分类ID与分类的名字
一级分类:
this.$router.push({path: ‘/search’, query{category1Id:6,categoryName:‘手机’}})
二级分类:
this.$router.push({path: ‘/search’, query{category2Id:6,categoryName:‘对讲机’}})
三级分类:
this.$router.push({path: ‘/search’, query{category3Id:6,categoryName:‘对讲’}})
第一种测试:声明式导航
因为声明式导航 router-link 是组件,过多 new 很多 VC 开辟空间大,出现卡顿现象 !!!
第二种测试:编程式导航(事件委派)
day02项目–操作流程
- 创建utils文件夹创建request.js(axios二次封装),设置请求响应拦截器以及进度条功能
- 创建api文件夹,封装 api 函数
- 在TypeNav全局组件中的mounted钩子函数中,使用$store,在store的modules文件中,编写对应actions、getters、mutations、state
- 在TypeNav中,在计算属性中使用 mapState 获取数据
- 实现页面内容的渲染(多层for循环)
- 在TypeNav结构中,使用编程时导航,事件委派,实现路由跳转
- 实现params参数与query参数合并
day 03
新安装的依赖
swiper@5 与 vue-awesome-swiper@4
mockjs (造假的接口)
任务
- mock接口封装
- mock接口的axios封装
- swiper实现轮播图
知识点
1.路由跳转合并
在跳转时通过 this.$route拿到对应的query或者params,加在请求中即可
2.swiper组件使用
3.mock接口使用
day03项目流程
- 创建mock文件,编写 banner.json 轮播图数据
- 在utils 文件中封装造假的axios(因为默认路径为 /mock)
- 创建 mockServe 编写造假的轮播图接口
- 在 list 组件 mounted钩子函数 中 派发actions
- 在 store的modules 文件夹的 home 文件中 编写actions、mutations、state 处理bannerArr 数据
- 在 list 使用 mapState接收 bannerArr 数据
- 在 list 结构中,使用 swiper 完成轮播图功能
- 在mock中编写造假的 floor 数据,api封装对应接口
- Home 组件 派发action,拿到数据,遍历 Floor ,给floor传递数据
- floor 通过props接收,并渲染轮播图等数据
day 04
任务
实现搜索页面部分功能
知识点
-
一般通过 $route 和 v-show 来实现一个组件的显示与隐藏,一个组件在多个地方使用,路由跳转会引起组件的销毁与重建,每次重建都会执行一次 mount 钩子函数,可以在钩子函数判断 $route 中的 path 路径,来决定显示与隐藏
-
性能优化
2.1 v-show v-if
2.2 路由懒加载
2.3 按需引入
2.4 请求次数优化
- 三级分类的优化
TypeNav:在 Home | Search 路由组件当中作为子组件,每一次路由跳转路由组件都会销毁重建(子组件销毁重建),
导致 TypeNav 重新发请求,导致请求次数过多
解决策略:
1. keep-alive:缓存路由组件->销毁重建(发两次请求) 【不推荐】
2. 在 App 组件写派发 actions 的逻辑,App 根组件只会执行一次,所以请求只会发一次。
- 接口的查看
地址: /api/list
方式: post
例子: 携带的参数
{
“category1Id”: “2”, //一级分类的ID
“category2Id”: “13”,//二级分类的ID
“category3Id”: “61”,//三级分类的ID
“categoryName”: “手机”,//一级分类的名字
“keyword”: “小米”,//关键字
“props”: [“3:安卓手机:手机系统”],//平台属性需要携带搜索的条件
“trademark”: “4:小米”,//品牌需要携带搜索条件
“order”: “1:desc”,//排序需要携带的搜索条件 1:综合 2:价格 asc:升序 desc:降序 默认初始值:1:desc
“pageNo”: 1,//分页器当前页码
“pageSize”: 10,//一页展示几条数据
}
- 根据搜索条件展示对应的数据
day04项目–操作流程
1.在 TypeNav 组件中,设置 flag (初始值为 true,因为 home 组件使用)标识,当 $route.path 不为 ‘/home’ 时,在移入 h3 时显示,离开上一级标签隐藏
2.封装 list 接口
3.编写 store 中的 module 的 search.js 发送请求,获取数据,然后在 Search 组件中使用 …mapstate获取数据
4.渲染 Search 组件 和 SearchSelector 组件(子组件)
5.在 Search 组件编写 getGoods 发请求的函数,在 data 中编写 SearchParams 设置发送请求的配置项,发送请求之前,通过从 $route 中获取 query 和 params 参数,去修改 data 中的值
6.使用监视属性,监听 $route, $route 发生改变就是 url 改变,调用 getGoods 函数
7.编写面包屑,点 x 时,如果是清除 query 或者 params 传递的参数
第一步: 在data数据中清除参数
第二部:⭐⭐⭐$router 的 push 跳转到本页面(search页面),因为要使 上方的 url 路径发生变化,如果 url 不改变,getGoods不会调用( 单纯调用 getGoods 会导致发送请求之前,仍然会通过获取 url 中的 query 和 params 信息,改了 searchParams的数据也没用 )
第三步:如果是 params 的话,使用 $bus 向 Header 组件传递空字串,让搜索框的 input 框清空
x如果是其他时,先把data中对应的参数清空,然后调用 getGoods 参数
8.search 组件用自定义事件得到子组件的参数信息,给 data 中的参数赋值,调用 getGoods 函数
day 05
任务
1.封装分页器
2.商品详情页的一部分
知识点
1.搜索页面根据品牌属性和属性值进行搜索
2.搜索条件之排序业务
排序: 综合1 价格2 升序 asc 降序 desc --> 默认综合排序
1 : desc 1: asc 2 : desc 2 : asc
2.1 综合与价格旁边都有箭头 (二选一)(谁选中有箭头和高亮)
2.2 箭头采用的是阿里图标的样式
2.3 高亮切换的时候,箭头默认朝下
第一步:解决价格与综合高亮问题 1 | 2
第二部:箭头显示与隐藏的判断与高亮一致
3.封装分页器
封装分页器需要哪些条件?
条件一:total(数据总条数)
条件二:pageSize (一页展示多少条数据)
条件三:PageNo (当前的页码)
条件四:pagerCount (分页器中间连续的页码个数)
发现财富:通过 total / pageSize (向上取整) 可以求出总页数
核心: Start End
中间的数字为当前页码,判断 start 与 end 取值
连续五页:当前第六页
4 5 6 7 8
连续五页:当前第九页
7 8 9 10 11
连续五页:当前第一页
-1 0 1 2 3 -> 1 2 3 4 5
连续五页:当前第二页
0 1 2 3 4 -> 1 2 3 4 5
连续五页:当前第33页
31 32 33 34 35-> 29 30 31 32 33
连续五页:当前第32页
30 31 32 33 34->29 30 31 32 33
day05项目–操作流程
1.阿里图标的箭头,添加到项目,把链接引入到 html,使用上下箭头
2.在search拿到点击品牌和手机类型的数据(自定义事件),设置面包屑以及点x的回调
3.排序,通过计算isOne等,看 searchParam s的 order 中是否含有对应的 1(降)2(升)来控制高亮以及箭头的显示隐藏,通过order 是否包含 desc 和 asc 控制箭头的朝向
4.切换综合和价格时,都会默认降序,只有点击同一个才会设置升序,点击综合传入 1,点击价格传入 2,判断 order 中是 1 还是 2,来判断排序方式 和 箭头朝向
5.分页器封装,需要 current,limit, pageCount(中间的连续页个数),total (总条数)
6.先计算总页数,totalPage = Math.ceil( total / limit ), 燃后 计算startEnd,起始和结束,判断 pageCount > totalPage,start此时为1,end 为 totalPage,正常情况,start = current - 2,end = current + 2,如果start < 1,start = 1, end 就是 pageCount,end如果大于 totalPage ,end = totalPage, start = totalPage - pageCount + 1
7.给按钮绑定 v-show,判断是否显示,绑定 @click 事件 点击时将 current 的修改值,通过自定义事件,getCurrent 传递 修改值,limit 改变,给 select 绑定 @change 事件,自定义事件传递limit 的值
8.在search组件使用分页器(必要参数:current、limit、pageCount(中间连续的页码个数)、total、getCurrent、getLimit)
day 06
任务
1.商品详情业务
2.滚动条行为
知识点
1.VueRouter 设置滚动条滚动行为
// 路由跳转就会触发 scrollBehavior 函数
scrollBehavior(to, from) { // to 是可以得到跳转后的 路径参数, from 是可以得到跳转前的 路径参数
return {y: 0};
}
2.⭐⭐⭐mapGetter 简化读取仓库数据的流程
…mapState 不会发生找不到的问题,第一次会获取到一个空对象,在detail 页面调用时,空对象使用( {} . ) . 会返回 undefined,在页面不会展示
…mapGetters 发生加报错,是因为在 store中直接使用 . 语法,在第一次直接返回的是一个undefined,所以在 detail 页面再次使用 . 语法会造成 undefined . 造成找不到,发生假报错
day06项目--操作流程
1.配置detail组件和路由
2.search 路由组件在点击图片时,跳转detali 组件(声明式导航)
3.配置api,skuId 从 $route 的 params参数获取
4.发送请求获取数据,渲染 detail 组件
5.编写放大镜效果
6.用户输入框(商品数量)的非法情况判断
7.编写加入购物车的接口和路由
8.点击加入购物车按钮跳转加入购物车组件(skuId,skuNum)
day 07
依赖
uuid (vue脚手架自带,不需要安装)
任务
1.请求拦截器添加唯一标识
2.添加购物车成功组件
3.购物车组件
知识点
1.GET与POST请求区别? ⭐⭐⭐⭐
GET:携带query参数上线的 POST:携带参数’无上线’
GET:不安全 POST:相对安全—程序员
2.加入购物车业务? Promise
点击加入购物车按钮:发请求(异步),
加入购物车成功(请求成功)->才会进入加入购物车成功页面
加入购物车失败(请求失败)->弹出一个提示框
问题: 请求成功与失败->vuex
组件需要知道这次请求成功了、还是失败了,dispatch函数返回一个Promise,在store中通过状态码200 | 201 返回对应成功或者失败的Promise来决定dispatch的返回值,用try、carch来实现,接收失败的Promise 会去往 catch
2.1加入购物车成功页面,展示商品详情数据?
vuex获取数据,刷新数据消失,因为vuex存储数据是js对象存储,并非持久化
2.2持久化存储数据方案?⭐⭐⭐⭐
浏览器存储功能
本地存储:localStorage⭐⭐⭐⭐
持久化存储数据,浏览器关闭、电脑关机重启,数据还是存在,只要是在同一域名下,全部页面共享数据
会话存储:sessionStorage
会话存储,网页关闭、电脑关机会话存储的数据即消失
本地存储与会话存储数据的缺点?
不同浏览器存储数据上限大于5M
3、购物车业务
3.1配置购物车路由与静态查看
3.2微调购物商品的静态样式
删除第三个li 15 35 10 17 10 13
3.3获取购物车的数据
请求地址:/api/cart/cartList
请求方式:get
参数:无
4、获取用户购物车的数据
京东|淘宝|多多:电商项目都有购物车,不同账号|用户,购物车内容是不同的!
张三:大炮
李四:拖鞋
王五:手机
4.1利用uuid生成用户未登录游客身份的唯一标识
4.2获取购物车数据并且展示用户购物车的数据
4.3计算用户商品总个数与总价?
reduce计算累加之和
5、修改商品的勾选状态?
修改商品勾选状态:/api/cart/checkCart/{skuID}/{isChecked}
请求方式: get
##day 08
依赖
loadsh (vue脚手架自带,不需要安装)
任务
1.购物车的业务完成
2.注册与登录的业务
知识点
1.修改商品数量存在一些问题?
商品数量使用防抖,减 使用节流
2.批量删除业务(全选业务相同)
实际工作当中:一个接口即可!!!
点击删除选中按钮:
只要购物车选中商品都会被删除掉[发请求]
才会再次获取最新购物车数据[再发请求]
Promise.all 实现,结果返回重新获取页面数据
3.登录注册业务⭐⭐⭐⭐⭐
市场当中大多数项目,拥有登录、注册功能,但是有一类项目,不需要注册的!!!
->中台项目[后台管理系统]
3.1拷贝登录与注册的路由组件
样式当中也可以使用@符号,文件夹src别名
assets文件:放置项目当中多个组件共用的静态资源
3.2获取验证码
获取验证API:书写好
/api/user/passport/sendCode/{phone} GET 手机号码
3.3完成新用户注册业务
/api/user/passport/register 请求方式:post phone|password|code
账号:18899888725 密码:111
账号:19937188457 密码:111
4、用户登录业务?⭐⭐⭐
接口地址:/api/user/passport/login 请求方式:post phone|password
企业登录接口:返回数据格式
{
code:200,
message:‘成功’,
data:‘xxxxxxxxbbbbbb’,
ok:true
}
5.token的理解?
token:令牌,用户(登录成功)以后,用户身份唯一标识!
理解: 学生牌 - token 学校:服务器
token过期如何处理:从新登录、从新获取!!!!
6.登录成功以后,获取用户的个人信息在头部展示?
获取用户信息这个请求,在哪里发?home
获取用户信息接口:/user/passport/auth/getUserInfo
GET
携带公共参数:token
day 09
任务
1.完成登录注册的业务
2.导航守卫使用
3.交易模块的业务
知识点
1.退出登录业务
前端:清空 vuex 小仓库
1.1 用户为什么一刷新就没了?!!!!
vuex , 存储数据利用的js对象,刷新就消失了!!!
1.2 为啥用户刷新用户信息消息?
第一步:vuex->state={token:‘’,nickName:‘’}
第二步:vuex->state={token:‘xxxx’,nickName:‘’}
第三步:vuex根据token获取用户信息->state={token:‘xxx’,nickName:‘1111’}
第四步:刷新清空state={token:‘’,nickName:‘’},首页发请求获取用户信息,但是token没了,nickName不会再次赋值
1.3本地存储持久化存储token?
请求头携带token,vuex仓库对象!!!
第一步:vuex->state = {token:null,nickName:‘’};
第二步:vuex->state = {token:‘xxx’,nickName:‘’}; —本地存储持久化存储token
第三步:刷新 state={token:‘本地存储’,nickName:‘xxxx’}
2.登录存在其它问题?
问题1:用户名字nickName->首页刷新存在,其他模块,刷新消失? —>vuex用的是js对象,刷新数据消失?
全部页面:只要挂载从新发请求获取用户信息赋值,不是最好可以解决问题!!!!
第一步:开始登录->vuex:state={nickName:‘’};
第二步:登录成功,进入到home首页,发请求(token),获取用户信息,给nickName进行二次赋值!!!
问题2:用户登录成功,还可以回到登录页面?********
3.导航守卫
导航:路由发生跳转->路由切换
守卫:保安
全局守卫:项目中任何路由跳转守卫都可以检测(盘问)
全局前置守卫:
全局后置守卫:
5.1全局守卫判断
路由:login|register|home|search|detail|addcartsuccess|shopcart
用户未登录:七个路由全部放行
用户登录成功:login不能访问,其余放行
6.完成用户交易页的业务?务必保证用户登录状态?
账号:13700000000 密码:111111
7.项目中万一没有vuex,该如何书写请求!!!
给Vue的原型上加上一个对象,这个对象包括所有的 api
核心操作
1.premission 文件,存放导航守卫
2.auto-token 文件,存放 localStorage 中存放的 token 文件
3.处理 token 过期的逻辑,执行退出登录的 api,并清除 vuex 仓库的 token 和 localstorage 中的 token 和 nickName,跳转到 登陆页面
4.token 在vuex仓库发请求时第一次通过 commit 存放在 vuex 仓库,同时存放在localStorage 中,下一次读取就可以直接从 localStorage 中读取到
5.导航守卫中,编写逻辑实现没有 nickName 时,会重新发请求(实现页面刷新,昵称不会消失)
day 10
新安装的依赖
vue-lazyload@1
任务
1.前台项目收尾
2.个人中心业务
3.路由懒加载
4.图片懒加载
5.表单验证业务
知识点
1.得到二维码,在 img 标签填入,需要在 / 之前加一个空格
2.用户支付结果的判断, 如果用户支付成功, 进入支付成功页面。如果支付失败,停留在当前页面,定时器+接口: 长轮询询问服务器支付结果!
3.全局守卫的判断之骚操作?
整个项目路由:
未登录:login|register|home|search|detail|addcartsuccess 放行
未登录:|shopcart|trade|pay|paysuccess|center(myorder|teamorder) 放行登录页
4.路由独享守卫与组件内守卫—了解
其实他们两者功能是一样的:仅仅是负责某一个路由的守卫功能!!!
第一个:用户登录成功,直接访问交易页面(不合理:购物车至少买点东西)
第二个:用户登录成功,直接访问支付页面(不合理:至少从交易页而来,携带订单号获取支付信息)
第三个:用户登录成功,直接访问支付成功(不合理:从支付页而来)
路由独享守卫:1
beforeEnter
全局守卫:2
beforeEach
afterEach
组件内守卫:3
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
5.图片懒加载(vue-lazyload) | 路由懒加载(import 传入一个函数,函数返回值为组件)
总结
一、组件通信手段有哪些?*****
插件:nprogress|swiper|lodash|qrcode|vue-lazyload|uuid|
props:父子|子父通信
自定义事件:子父
全局事件总线:兄弟组件通信[万能]
vuex:集中式管理状态容器[万能]
插槽:默认插槽|具名插槽|作用域插槽,父子通信传递结构
ref|在父组件内部获取子组件属性或者方法
二、vuex?
vuex核心概念:state=>mutations=>actions=>getters=>modules
vuex缺点:vuex存储数据利用js对象,存储并非持久化
三、项目性能优化手段?
v-if|v-show选择
请求次数优化
按需引入
防抖与节流
事件委派
图片懒加载
路由懒加载…
四、vue-router面试题?
路由模式:hash|history #
router|route:
router路由器,管理多个路由,编程式导航进行路由跳转
route路由,管理query|params|meta|name
五、axios您是否有进行过二次封装?
1:使用请求与响应拦截器
2:请求拦截器,请求头携带公共参数token
3:响应拦截器简化数据|统一处理错误
3:配置基本路由与超时时间
六、您在项目当中是否封装过通用组件?
分页器
七、本地存储与会话存储
区别:本地存储持久化 会话存储:会话结束存储消息
缺点:存储数据是有上限的不同浏览器大于5M
八、http协议常见状态码?
200
304
404
500
九、购物车实现原理?
根据用户身份标识获取用户购物车数据
十:token是什么?
token:用户登录成功以后,用户唯一标识
token过期:退出登录再次获取
十一、闭包?
闭包:…
缺点:内存泄漏
闭包应用场景:防抖与节流
十二:如何是一个盒子水平垂直居中?
flex布局
十三:H5新增特?
语义化标签
多媒体
CS3
本地存储…
十四:ES6
let
const
箭头函数
解构
拓展运算符
类
继承
set
map
symbol
Promise:手写Promise
everyday important
February 2
- vue提供内置过渡动画
- 自定义事件
- 全局事件总线
February 3
- github 用户搜索案例
- element-ui
- 插槽 slot
- vuex 类似于 redux
February 5
- vue-router 路由
February 6
- axios 中的请求拦截器 | 响应拦截器
- proxy 解决跨域问题
February 7
- axios的使用 (二次封装)
- vuex
- 首页三级分类的业务
- 封装 api
February 8
- mock 数据
- swiper 轮播图
- 解决编程式导航问题
- 过渡动画在项目当中使用
February 10
- 搜索页面部分业务
- 请求次数优化
February 11
- 搜索模块结束 [封装分页器]
- 商品详情页
February 13
- vueRouter 设置滚动条行为
February 17
- 登陆注册的业务
- 导航守卫
- 交易模块的业务