(1)退出功能实现
在NavHeader.vue中:
<div class="topbar-user">
<a href="javascript:;" v-if="username">{{username}}</a>
<a href="javascript:;" v-if="!username" @click="login">登录</a>
<a href="javascript:;" v-if="username" @click="logout">登录</a>
<a href="javascript:;" v-if="username">我的订单</a>
<a href="javascript:;" class="my-cart">
<span class="icon-cart" @click="goToCart"></span> 购物车({{cartCount}})
</a>
</div>
<script>
export default {
methods: {
logout() {
this.axios.post('/user/logout').then(() => {
this.$message.success("退出成功");
this.$cookie.set('userId', '', {expires: '-1'}); //清空cookie中的信息
this.$store.dispatch('saveUserName', '') //清除页面中的用户名
this.$store.dispatch('saveCartCount', '0') // 清空购物车数量
})
},
}
}
</script>
(2)解决一个问题:
-
问题:在退出后,再次登录后,发现购物车数量为0,不是用户购物车中该有的数量。
-
原因:虽然之前在App.vue中写过代码:
<script> export default { mounted() { this.getUser(); this.getCartCount(); }, methods: { getUser() { this.axios.get('/user').then((res = {}) => { this.$store.dispatch('saveUserName', res.username); }) }, getCartCount() { this.axios.get('/carts/products/sum').then((res = 0) => { this.$store.dispatch('saveCartCount', res); }) } } } </script>
但当时这么写的原因:Vuex是在内存中存储数据的,但我们页面刷新时,内存中数据会自动消失,为保持数据一致性,所以需要重新获取数据,并存储在Vuex中。
但在单页面应用中,但我们重新退出再登录时,页面并没有重新刷新,所以这个过程中并没有重新调用App.vue。(App.vue只在第一次进入时调用,在之前页面跳转时不会调用)
-
解决方法:我们需要在NavHeader.vue中再次获取购物车数量:
<script> export default { mounted() { this.getCartCount(); }, methods: { getCartCount() { this.axios.get('/carts/products/sum').then((res = 0) => { this.$store.dispatch('saveCartCount', res); }) } } } </script>
(3)然而,上面的解决方法还会存在一个问题:
-
问题:如果我们刷新后,会重复两次获取购物车数量,存在资源浪费。
-
解决方法:在NavHeader.vue中做个判断:只有从登陆页面中跳转过来的才获取购物车数量。
如何判断是从登陆跳转过来的呢?可以通过导航守卫。或在登陆页面中做参数跳转。
下面用在登陆页面中做参数跳转来解决问题:
在登陆页面做参数跳转方式有很多:query传参、parmas传参或直接在路由上通过?拼接,加入参数。
下面在NavHeader.vue通过parmas传参:
<script> export default { mounted() { this.getProductList(); let params = this.$router.push.params; if (params && params.from == 'login') { this.getCartCount() } } } </script>
(4)接口优化
解决了上面的问题,但是有个问题:如果用户没有登录的话,那在App.vue中就没必要去获取购物车的值。所以在App.vue中做个优化:屏蔽不需要调用的接口。
<script>
export default {
mounted() {
if (this.$cookie.get('userId')) {
this.getUser();
this.getCartCount();
}
}
}
</script>
在login.vue中把cookie改成会话级别的:(会话级别的意思是当浏览器退出后,会话才消失)
<script>
export default {
methods: {
login() {
let {username, password} = this;
this.axios.post('/user/login', {
username,
password
}).then((res) => {
this.$cookie.set('userId', res.id, {expires:'Session'}); //更改为Session
this.$store.dispatch('saveUserName', res.username);
this.$router.push('/index')
})
}
}
}
</script>