目录
功能介绍
vuex 本地缓存 对用户信息进行记入 请求封装 登入页面 个人页面展示
运行效果
未登入状态
点击头像部分即可跳登入页面
登入页面
进行登入完后
代码演示
功能结构
请求封装 详细文章
部分api.ts 关于 用户登入接口
//登入接口
interface LoginData {
userTelephone: string,
userPassword: string
}
export function login(data: LoginData) {
return request({
url: "/user/userLoginByPassword",
method: "post",
data
})
}
store index.ts
import { createStore } from 'vuex'
import user from '@/store/user.ts'
//创建store实例
const store = createStore({
//引入模块
modules:{
user
}
})
export default store
store user.ts
import {login} from '@/api/api.ts'
export default {
//开启命名空间后 访问所以属性都需要带模块名
namespaced:true,
state(){
return {
userInfo : null
}
},
mutations: {
initInfo(state,info){
state.userInfo=info
}
},
actions: {
userLogin(context,info){
login(info).then((res) => {
if(res){
context.commit('initInfo',res.data);
console.log(res.data);
//本地存储用户信息
uni.setStorage({
key:'userInfo',
data: res.data
})
//返回上一页
uni.navigateBack({
delta: 1
})
}
})
}
}
}
main.js
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
import useAPP from './App.vue'
//引入store
import store from './store'
export function createApp() {
const app = createSSRApp(useAPP)
app.use(store)
return {
app
}
}
App.vue
<script setup>
import { onLaunch } from '@dcloudio/uni-app';
import { useStore } from 'vuex';
onLaunch(()=>{
//本地缓存已存在登入信息 直接放入store中
try{
const store = useStore();
const user=uni.getStorageSync('userInfo');
if(user){
store.commit('user/initInfo',user)
}
}catch(e){
console.log('提取用户信息失败');
}
})
</script>
<style lang="scss">
/*每个页面公共css */
@import '@/uni_modules/uni-scss/index.scss';
/* #ifndef APP-NVUE */
@import '@/static/customicons.css';
// 设置整个项目的背景色
page {
background-color: #f5f5f5;
}
/* #endif */
.example-info {
font-size: 14px;
color: #333;
padding: 10px;
}
</style>
type login.ts
export interface LoginForm {
userTelephone: string
userPassword: string
}
export class LoginData{
ruleForm:LoginForm={
userTelephone: "",
userPassword:""
}
}
login.vue
<template>
<view class="content">
<view class="avatorWrapper">
<view class="avator"><image class="img" src="../../static/logo.png" mode="widthFix"></image></view>
</view>
<view class="form">
<view class="inputWrapper"><input v-model="data.ruleForm.userTelephone" class="input" type="text" value="" placeholder="请输入电话号码" /></view>
<view class="inputWrapper"><input v-model="data.ruleForm.userPassword" class="input" type="password" value="" placeholder="请输入密码" /></view>
<view class="loginBtn" @click="toLogin()"><text class="btnValue">登入</text></view>
<view class="forgotBtn"><text>找回密码</text></view>
</view>
</view>
</template>
<script setup lang="ts">
import { LoginData } from '@/type/login';
import { login } from '../../api/api.ts';
import { reactive } from 'vue';
import { useStore } from 'vuex';
//用户输入数据
const data = reactive(new LoginData());
const store = useStore();
const toLogin = () => {
//通过vuex 进行登入操作
store.dispatch('user/userLogin', data.ruleForm);
};
</script>
<style lang="scss">
.content {
background: #377eb4;
width: 100vw;
height: 100vh;
background-image: url(@/static/bt/bt-2.jpg);
}
.avatorWrapper {
height: 30vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: flex-end;
}
.avator {
width: 200upx;
height: 200upx;
overflow: hidden;
}
.avator .img {
width: 100%;
}
.form {
padding: 0 100upx;
margin-top: 80px;
}
.inputWrapper {
width: 100%;
height: 80upx;
background: white;
border-radius: 20px;
box-sizing: border-box;
padding: 0 20px;
margin-top: 25px;
}
.inputWrapper .input {
width: 100%;
height: 100%;
text-align: center;
font-size: 15px;
}
.loginBtn {
width: 100%;
height: 80upx;
background: #77b307;
border-radius: 50upx;
margin-top: 50px;
display: flex;
justify-content: center;
align-items: center;
}
.loginBtn .btnValue {
color: white;
}
.forgotBtn {
text-align: center;
color: #eaf6f9;
font-size: 15px;
margin-top: 20px;
}
</style>
user.vue
<template>
<view class="content">
<view class="userback" @click="toLogin(getUserName)">
<img :src="getUserImg">
<view class="userName">{{getUserName}}</view>
</view>
</view>
</template>
<script setup lang="ts">
import { computed ,ref} from 'vue'
import { useStore } from 'vuex';
//全局常量
import globalParam from '@/common/operate.ts'
const store = useStore();
//vuex 获取用户名称
const getUserName= computed({
get:()=>{
let {userInfo} = store.state.user;
let userName= userInfo ? userInfo.userName : '未登入'
return userName
}
})
//vuex 获取用户头像
const getUserImg= computed({
get:()=>{
let {userInfo} = store.state.user;
let userImg= userInfo ? globalParam.imgBaseURL+userInfo.picUrl : '../../static/user/user.png'
return userImg
}
})
// 点击头像 如果未登入状态 点击跳登入页面
const toLogin=(userName)=>{
if(userName === '未登入'){
uni.navigateTo({
url: '../login/login'
})
}
}
</script>
<style lang="scss">
.content {
width: 100vw;
height: 90vh;
background-image: url(@/static/bt/bt-2.jpg);
text-align: center
}
.userback img {
margin: auto;
border-radius: 50%;
margin-top: 21%;
width: 300upx;
height: 300upx;
}
.userName{
color: #111111;
font-size: 2rem;
}
</style>