一、登录后显示
1)Msite.vue头部登录后信息
<TopHeader :title='address.name'>
<!-- 【1】点图标跳转到搜索页 -->
<router-link to="/search" class="header_search" slot='left'>
<i class="iconfont icon-sousuo"></i>
</router-link>
<!-- 【3】状态中有用户id说明已登录,跳转到个人中心,否则跳转到登录页 -->
<router-link :to=" userInfo._id ? '/profile':'/login'" class="header_login" slot='right'>
<!-- 【4】未登录显示登录,否则显示个人中心小图标 -->
<span class="header_login_text" v-if="!userInfo._id">
登录|注册
</span>
<span class="header_login_text" v-else>
<i class="iconfont icon-person"></i>
</span>
</router-link>
</TopHeader>
import {mapState} from 'vuex' //1调用vuex管理的状态
computed:{
//把vuex管理的状态:地址/滑动导航分类解构到当前位置
/*mapState返回的值:函数(对象)参数来自store/state.js*/
// 【2】读取状态中的用户信息
...mapState(['address','categorys','userInfo']),
略过...
}
效果:http://localhost:8080/
左:跳转到搜索 右:由注册变图标,点跳转到个人中心
2)profile.vue登录后信息
<!-- 【2】如果已经登录,则跳转到个人资料,否则跳转到登录页面 -->
<router-link :to="userInfo._id ? '/user_info' : '/login'" class="profile-link">
<div class="profile_image">
<i class="iconfont icon-person"></i>
</div>
<div class="user-info">
<!-- 没有手机号则显示用户名或登录注册 -->
<p class="user-info-top" v-if="!userInfo.phone">{{userInfo.name || '登录/注册' }}</p>
<p>
<span class="user-icon">
<i class="iconfont icon-shouji icon-mobile"></i>
</span>
<span class="icon-mobile-number">{{userInfo.phone || '暂无绑定手机号'}}</span>
</p>
</div>
<span class="arrow">
<i class="iconfont icon-jiantou1"></i>
</span>
</router-link>
import {mapState} from 'vuex'
export default{
computed:{
//读取状态中的userInfo
...mapState(['userInfo'])
}
}
效果:http://localhost:8080/#/profile
二、保持登录状态
原理:cookie结合后端session保持登录
保持登录详:https://blog.csdn.net/a754895/article/details/82632747
a.根目录/app.js 使用session设置cookie的会话时间为一天
app.use(session({
secret: '12345',
//设置maxAge是80000ms,即80s后session和相应的cookie失效过期
cookie: {maxAge: 1000*60*60*24 },
resave: false,
saveUninitialized: true,
}));
b.routes/index.js
重点:从此处开始:UserModel.findOne(
/*
密码登陆
*/
router.post('/login_pwd', function (req, res) {
const name = req.body.name
const pwd = md5(req.body.pwd)
const captcha = req.body.captcha.toLowerCase()
console.log('/login_pwd', name, pwd, captcha, req.session)
// 可以对用户名/密码格式进行检查, 如果非法, 返回提示信息
if(captcha!==req.session.captcha) {
return res.send({code: 1, msg: '验证码不正确'})
}
// 删除保存的验证码
delete req.session.captcha
UserModel.findOne({name}, function (err, user) {
if (user) {
console.log('findUser', user)
if (user.pwd !== pwd) {
res.send({code: 1, msg: '用户名或密码不正确!'})
} else {
req.session.userid = user._id
res.send({code: 0, data: {_id: user._id, name: user.name, phone: user.phone}})
}
} else {
const userModel = new UserModel({name, pwd})
userModel.save(function (err, user) {
// 向浏览器端返回cookie(key=value)
// res.cookie('userid', user._id, {maxAge: 1000*60*60*24*7})
req.session.userid = user._id
const data = {_id: user._id, name: user.name}
// 3.2. 返回数据(新的user)
res.send({code: 0, data})
})
}
})
})
1)src/api/index.js
// 9、根据会话获取用户信息
export const reqUserInfo = () => ajax(BASE_URL+'/userinfo')
2)src/store/state.js
userInfo: {}, // 用户信息
3)mutation-types.js
export const RECEIVE_USER_INFO = 'receive_user_info' // 接收用户信息
4)mutations.js
import {RECEIVE_USER_INFO} from './mutation-types.js'
export default{
[RECEIVE_USER_INFO](state,{userInfo}){state.userInfo=userInfo},
}
5)src/store/actions.js
// 控制mutations
import {
...略过
RECEIVE_USER_INFO,
} from './mutation-types.js'
import {
...略过
reqUserInfo, //获取session的用户信息
} from '../api/index.js'
export default{
//异步获取自session中的用户信息
async getUserInfo({commit}){
const result=await reqUserInfo()
if(result.code===0){
const userInfo=result.data
commit(RECEIVE_USER_INFO,{userInfo})
}
},
}
6)app.vue
页面加载时,发起一次获取用户信息请求,实现登录保持
//【0】引入vuex的action
import {mapActions} from 'vuex'
export default{
mounted(){
/* 调用actions方法1:getAddress来源actions.js
this.$store.dispatch('getAddress')*/
// 【1】调用actions方法2:
this.getAddress()
this.getUserInfo()
},
methods:{
// 【2】调用actions方法2:把getAddress方法解构到当前位置
// mapActions() 返回的是一个对象,
// 用了 ... 扩展符后,才可以放进一个对象里,
// 和其他组件内定义的 method 在同一个 methods 对象。
// 参数来自:store/actions.js内的方法
...mapActions(['getAddress','getUserInfo'])
}
}