您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~
Xxmall商城项目迎来了第三天了,今天碰到的难题是登录注册方面的,将登陆成功的用户信息长久的保存在页面上,刷新后也不会重置。
如下是我实现登陆功能的整个思路,首先login登陆接口如下:
// 模拟一个登陆的接口
app.post('/api/login', (req, res) => {
console.log(req.body.user);
// 登录成功获取用户名
let username = req.body.user
//一系列的操作
res.json({
// 进行加密的方法
// sing 参数一:加密的对象 参数二:加密的规则 参数三:对象
token: jwt.sign({ username: username }, 'abcd', {
// 过期时间
expiresIn: "3000s"
}),
username,
state: 1,
file: '/static/images/1570600179870.png',
code: 200,
address: null,
balance: null,
description: null,
email: null,
message: null,
phone: null,
points: null,
sex: null,
id: 62
})
})
从表单提交获取用户名后设置了过期时间,并且登陆成功后会在localstorage本地存储中保存id、
username和生成的token,token就是每个用户的标识。
if (valid) {
// 获取用户名和密码
// let {user,pass} = this.ruleForm;
let res = await this.$http.post("/api/login", this.ruleForm);
if (res.data.code === 200) {
console.log(res.data)
let { username, token, id } = res.data;
// 持久化 存储
setStore("token", token);
setStore("id", id);
setStore("username", username);
this.$router.push('/')
}
这是请求访问login的代码,也就是表单submit按钮点击事件。
如下是设置获取和移除本地存储的三个已经封装好的方法,所以我是直接导入使用的。
export const setStore = (name, content) => {
if (!name) return;
if (typeof content !== 'string') {
content = JSON.stringify(content);
}
window.localStorage.setItem(name, content);
}
export const getStore = name => {
if (!name) return;
return window.localStorage.getItem(name);
}
export const removeStore = name => {
if(!name) return;
window.localStorage.removeItem(name);
}
另外我在main.js中设置了vuex拦截器,当路由跳转时判断本地存储中是否有takon,也就是判断是否为登录状态。如果发现用户登录,在request响应头部添加token。
//判断token是否存在
axios.interceptors.request.use(config=>{
const token = getStore('token');
//如果用户已经登录
if(token){
config.headers.common['Authorization'] = token;
}
return config;
},error=>{
console.log(error);
return Promise.reject(error);
})
接下来设置了登录组件的路由守卫,并且登陆成功后把用户信息传给vuex中,保存用户信息。
//登录路由守卫
router.beforeEach(async(to,from,next)=>{
const res = await axios.post('/api/validate');
let data = res.data;
console.log(data)
if(data.state !== 1){
//用户还没登陆
if(to.matched.some(record=>record.meta.auth)){
next({
path:'/login'
})
}else{
next();
}
}else{
//保存用户信息
store.commit('ISLOGIN',data);
if(to.path==='login'){
router.push({
path:'/'
})
}
next()
}
})
接下来,实现了添加到购物车卡片显示的列表渲染,效果如下:
由于这些数据在路由跳转的过程中应该保持,所以在vuex中定义操作是最合适不过的了,我的实现大体思路如下:在每一个商品详情路由中的加入购物车按钮定义点击事件,当第一次点击时创建一个对象,包含该商品的名称、单价、数量以及图片链接;而当第二次点击时则会将数量进行累加,保持一个对象。
let name = this.goodsName;
if(this.cardList.name){
this.cardList.num += this.goodsNum;
}else{
this.cardList = {
name:this.goodsName,
img:this.big,
num:this.goodsNum,
price:this.price
}
}
接下来就是vuex的操作了,每次把这个对象添加到vuex中的购物车数组中即可。
state: {
loginState:false, //登录状态
userInfo:null, //用户信息
cartList:[], //购物车列表
addCartList:{}, //待添加到购物车的订单
showCart:false
},
mutations: {
//购物车卡片显示
SHOWCART(state,{showCart}){
state.showCart = showCart
},
//添加商品至购物车
ADDCART(state,{addCartList}){
console.log(addCartList)
if(!state.cartList.find(item=>addCartList.name==item.name)){
state.cartList.push(addCartList);
}
console.log(state.cartList);
},
在组件中的调用:
//如果购物车中没有该商品
this.ADDCART({
addCartList:this.cardList
})
第三天结束,有点小难度…头晕