uniapp 用户登录
文章目录一、登录基础1. 登录组件2. 页面引用组件3. 明确登录的实现思路4. 封装 action 调用登录接口5. 保存用户登录状态6. 成已登录的用户视图6. 现退出登录功能一、登录基础1. 登录组件对于 登录 功能来说提供了两个登录的入口。那么大家想一下,现在我们已经在 我的 这个 tab页 中实现了 登录的 UI,难道我还需要在另外一个页面中再去实现一遍吗?这个肯定是不需要的对不对。所以
·
一、登录基础
1. 登录组件
对于 登录 功能来说提供了两个登录的入口。
那么大家想一下,现在我们已经在 我的 这个 tab页
中实现了 登录的 UI
,难道我还需要在另外一个页面中再去实现一遍吗?
这个肯定是不需要的对不对。所以我们希望可以复用登录的 UI
,而复用的方式则可以把 登录的 UI
封装称为一个 组件
创建登录组件 my-login
登录页面基本样式
<template>
<view class="my-container">
<!-- 用户未登录 -->
<block>
<image class="avatar avatar-img" src="/static/images/default-avatar.png" mode="scaleToFill" />
<view class="login-desc">登录后可同步数据</view>
<button class="login-btn" type="primary" @click="getUserInfo">微信用户一键登录</button>
</block>
</view>
</template>
<script>
export default {
name: 'my-login',
data() {
return {};
}
};
</script>
<style lang="scss" scoped>
.my-container {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 25%;
.avatar-img {
width: 78px;
height: 78px;
}
.login-desc {
color: $uni-text-color-grey;
font-size: $uni-font-size-base;
margin-top: $uni-spacing-col-big;
}
.login-btn {
margin-top: $uni-spacing-col-big;
width: 85%;
}
}
</style>
2. 页面引用组件
me.vue
<template>
<my-login />
</template>
<script>
export default {
name: 'login'
};
</script>
3. 明确登录的实现思路
微信小程序:
- 想要实现登录功能,那么我们需要调用登录接口来进行实现,而登录接口所需要的参数,我们可以直接通过
getUserProfile
方法进行获取。 - 调用登录接口成功,服务端会返回用户的
token
,这个token
为当前的用户身份令牌。(拥有 token) 则表示用户已经登录了。 - 而此处的
token
,我们需要在多个组件中进行使用,所以token
需要被保存到全局状态管理工具 - vuex
中,同时需要保存的还有通过getUserProfile
获取到的用户基本信息。 - 而当前的用户登录状态,我们希望可以一直保存(PS:不需要每次都进行登录)。所以在登录完成后,我们需要把
token
&&userinfo
保存到 本地存储中 - 最后,为了实现 数据与组件的分离,我们需要把与 与登录相关的逻辑 都封装在
vuex
中进行。
这些业务是 前端用户登录的标准逻辑,大家在以后的前端登录业务处理中,也可以按照此逻辑进行。
4. 封装 action 调用登录接口
首先我们需要先获取到用户的信息,用作登录时的请求参数:
my-login
<script>
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions('user', ['login']),
/**
* 获取用户信息
*/
getUserInfo() {
// 展示加载框
uni.showLoading({
title: '加载中'
});
uni.getUserProfile({
desc: '登录后可同步数据',
success: async (obj) => {
// 调用 action ,请求登录接口
await this.login(obj);
},
fail: () => {
uni.showToast({
title: '授权已取消',
icon: 'error',
mask: true
});
},
complete: () => {
// 隐藏loading
uni.hideLoading();
}
});
}
}
};
</script>
api/user.js
import request from '../utils/request';
/**
* 获取用户基本信息
*/
export function login(data) {
return request({
url: '/sys/login',
method: 'POST',
data,
});
}
/**
* 微信用户授权登录,携带appid和code参数,调用后端接口获取Openid
*/
export function loginAuth(data) {
return request({
url: '/wx/user/' + data.appid + '/login/',
data: {
code: data.code,
},
});
}
store/user.js
import { login } from 'api/user';
export default {
namespaced: true,
state: () => {
return {};
},
actions: {
/**
* 完成登录
*/
async login(context, userProfile) {
console.log(userProfile);
// 用户数据
const rawData = userProfile.userInfo;
// 调用登录接口
const { data: res } = await login({
signature: userProfile.signature,
iv: userProfile.iv,
nickName: rawData.nickName,
gender: rawData.gender,
city: rawData.city,
province: rawData.province,
avatarUrl: rawData.avatarUrl
});
// TODO: 登录逻辑
console.log(res);
}
}
};
store/index.js
import user from './modules/user';
const store = new Vuex.Store({
modules: {
user
}
});
5. 保存用户登录状态
用户的登录状态需要被保存到 vuex
中,同时需要进行 本地存储。
store/user.js
import { login } from 'api/user';
const STORAGE_KEY = 'user-info';
const TOKEN_KEY = 'token';
export default {
namespaced: true,
state: () => {
return {
// 用户 token
token: uni.getStorageSync(TOKEN_KEY) || '',
// 用户信息
userInfo: uni.getStorageSync(STORAGE_KEY) || {}
};
},
mutations: {
/**
* 保存 token 到 vuex
*/
setToken(state, token) {
state.token = token;
this.commit('user/saveToken');
},
/**
* 保存 token 到 本地存储
*/
saveToken(state) {
uni.setStorage({
key: TOKEN_KEY,
data: state.token
});
},
/**
* 保存 用户信息 到 vuex
*/
setUserInfo(state, userInfo) {
state.userInfo = userInfo;
this.commit('user/saveUserInfo');
},
/**
* 保存 用户信息 到 本地存储
*/
saveUserInfo(state) {
uni.setStorage({
key: STORAGE_KEY,
data: state.userInfo
});
}
},
actions: {
/**
* 完成登录
*/
async login(context, userProfile) {
...
// 登录逻辑
this.commit('user/setToken', res.token);
this.commit('user/setUserInfo', JSON.parse(userProfile.rawData));
}
}
};
6. 成已登录的用户视图
当 token
存在时,表示用户已经登录了,此时需要 展示用户登录完成的视图:
my-login
<template>
<view class="my-container">
<!-- 用户未登录 -->
<block v-if="!token">
...
</block>
<!-- 已登录 -->
<block v-else>
<image class="avatar avatar-img" :src="userInfo.avatarUrl" mode="scaleToFill" />
<view class="login-desc">{{ userInfo.nickName }}</view>
<button class="login-btn" type="default" @click="onLogoutClick">退出登录</button>
</block>
</view>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
name: 'my-login',
data() {
return {};
},
computed: {
...mapState('user', ['token', 'userInfo'])
},
};
</script>
6. 现退出登录功能
store/user
export default {
...
mutations: {
...
/**
* 删除 token
*/
removeToken(state) {
state.token = '';
this.commit('user/saveToken');
},
...
/**
* 删除用户信息
*/
removeUserInfo(state) {
state.userInfo = {};
this.commit('user/saveUserInfo');
}
},
actions: {
...
/**
* 退出登录
*/
logout(context) {
this.commit('user/removeToken');
this.commit('user/removeUserInfo');
}
}
};
my-login
<template>
<view class="my-container">
...
<!-- 已登录 -->
<block v-else>
...
<button class="login-btn" type="default" @click="onLogoutClick">退出登录</button>
</block>
</view>
</template>
<script>
export default {
...
methods: {
...mapActions('user', ['login', 'logout']),
...
/**
* 退出登录
*/
onLogoutClick() {
uni.showModal({
title: '提示',
content: '退出登录将无法同步数据哦~',
success: ({ confirm, cancel }) => {
if (confirm) {
this.logout();
}
}
});
}
}
};
</script>
更多推荐
已为社区贡献3条内容
所有评论(0)