1.思路:
1.login.vue
2.api=>login.js
3.router=>index.js
4.store=>index.js
5.utils=>rquest.js和storage.js和utils.js
6.退出设置
2.login.vue
/*
登录页面
*/
<template>
<div class="loginMain">
<!-- 导航栏 -->
<van-nav-bar title="登录" left-text="返回" left-arrow @click-left="$router.back()" />
<!-- 登录表单 -->
<van-form ref="loginForm" @submit="handleSubmit()">
<van-field v-model="username" name="用户名" label="用户名" placeholder="用户名" :rules="rulesFrom.username" />
<van-field v-model="password" type="password" name="密码" label="密码" placeholder="密码"
:rules="rulesFrom.password" />
<van-field v-model="mobile" type="number" name="mobile" maxlength="11" placeholder="手机号"
:rules="rulesFrom.mobile">
<!-- <template #left-icon>
<i class="iconfont icon-shouji"></i>
</template> -->
<i slot="left-icon" class="iconfont icon-shouji"></i>
</van-field>
<van-field v-model="code" name="code" placeholder="验证码" :rules="rulesFrom.code" left-icon="closed-eye">
<template #button>
<van-count-down :time="1000 * 10" format="ss 秒/s" v-if="isCountDownShow"
@finish="isCountDownShow = false" />
<van-button v-else type="primary" size="small" @click="handleGetCode()">获取验证码</van-button>
</template>
</van-field>
<div style="margin: 16px;">
<van-button block type="info" @click="handleSubmit()">登录</van-button>
</div>
</van-form>
</div>
</template>
<script>
import { loginAPI } from '@/api/login'
export default {
data() {
return {
username: '',
password: '',
mobile: '',
code: '',
rulesFrom: {
username: [{ required: true, message: '请填写用户名' }],
password: [{ required: true, message: '请填写密码' }],
mobile: [{ required: true, message: '请填写手机号' }, { pattern: /1[3|5|7|8]\d{9}/, message: '手机号格式输入错误' }],
code: [{ required: true, message: '请填写验证码' }, { pattern: /^\d{6}$/, message: '验证码格式输入错误' }],
},
isCountDownShow: false,
}
},
methods: {
// 获取验证码
async handleGetCode() {
const that = this
// 1、验证手机号
try {
await that.$refs.loginForm.validate('mobile')
} catch (error) {
return console.log('验证失败', error)
}
// 2、验证通过,显示倒计时
that.isCountDownShow = true
// 3、请求发送验证码
},
// 登录按钮
async handleSubmit() {
const that = this
that.$toast.loading({
message: '登录中...',
forbidClick: true,//禁止背景点击
duration: 0, // 持续展示,默认2000
})
let param = {
username: that.username,
password: that.password
}
const res = await loginAPI(param)
if (res.data.code == 0) {
// 处理Token
that.$store.commit('setUser', res.data.data)
// 登录成功
that.$toast.success('登录成功')
// 跳转页面
that.$router.back()
that.$router.push({ path: '/home' }).catch(() => { });
} else if (res.data.code == 400) {
that.$toast.fail('验证码过期,请稍后重试')
} else {
// 登录失败
that.$toast.fail('登录失败,请稍后重试')
}
},
}
}
</script>
<style scoped lang="less">
.loginMain {
width: 100%;
height: 100%;
}
</style>
3.api=>login.js
import request from '@/utils/request';
// 登录
export function loginAPI(obj) {
return request({
url: '/api/user/login',
methods: 'post',
data:obj
})
};
4.router=>index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
redirect: '/login'
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ '@/views/login')
},
{
path: '/',
name: 'layout',
component: () => import(/* webpackChunkName: "layout" */ '@/views/layout'),
children: [
{
path: '/home',
name: 'home',
component: () => import(/* webpackChunkName: "home" */ '@/views/home')
}, {
path: '/message',
name: 'message',
component: () => import(/* webpackChunkName: "message" */ '@/views/message')
}, {
path: '/video',
name: 'video',
component: () => import(/* webpackChunkName: "video" */ '@/views/video')
}, {
path: '/mine',
name: 'mine',
component: () => import(/* webpackChunkName: "mine" */ '@/views/mine')
}
]
},
{
path: '/search',
name: 'search',
component: () => import(/* webpackChunkName: "search" */ '@/views/search')
}
]
const router = new VueRouter({
routes
})
export default router
5.store=>index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { getItem, setItem } from '@/utils/storage'
Vue.use(Vuex)
const TOKEN_KEY = 'Token' //设置Token本地存储名称为常量
export default new Vuex.Store({
state: {
// user: null,//一个对象,存储当前用户登录信息(Token等数据)
// user: JSON.parse(window.localStorage.getItem(TOKEN_KEY))
user: getItem(TOKEN_KEY)
},
mutations: {
setUser(state, data) {
state.user = data
// 防止刷新丢失
// window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user))
setItem(TOKEN_KEY, state.user)
}
},
actions: {
//系统登出
LogOut({ commit, reject }) {
return new Promise((resolve) => {
commit('setUser', null);
resolve();
}).catch(error => {
reject(error)
})
},
},
modules: {
}
})
6.utils=>rquest.js和storage.js和utils.js
/*
请求模块配置文件
*/
import axios from "axios";
import store from '@/store/index'
import {Message, MessageBox} from 'element-ui'
const request = axios.create({
baseURL: 'http://192.168.8.237:8002/',
timeout: 2000,
})
// 请求拦截器
request.interceptors.request.use(function (config) {
const { user } = store.state
if (user && user.token) {
config.headers['token'] = user.token
// config.headers.Authorization = `Bearer ${user.token}`
}
return config
}, function (error) {
return Promise.reject(error)
})
//响应拦截器
request.interceptors.response.use(response => {
const res = response.data;
if (res.code && res.code == 500) {
Message({
message: res.msg || res.message,
type: 'error'
})
} else if (res.state && res.state == 500) {
Message({
message: res.msg || res.message,
type: 'error'
})
} else if (res.msg && res.msg.indexOf('过期') != -1) {
MessageBox.confirm('登录已过期 请重新登录', '提示', {
confirmButtonText: '重新登录',
type: 'warning'
}).then(() => {
store.dispatch('LogOut').then(() => {
location.href = '/login'; //跳转到登录页面
})
})
}
return Promise.resolve(response)
}, error => {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
})
export default request
// 封装本地存储操操作模块
// 存储数据
export const setItem = (key, value) => {
// 将数组、对象类型的数据转换为 JSON 格式字符串进行存储
if (typeof value === 'object') {
value = JSON.stringify(value)
}
window.localStorage.setItem(key, value)
}
// 获取数据
export const getItem = key => {
const data = window.localStorage.getItem(key)
try {
return JSON.parse(data)
} catch (err) {
return data
}
}
// 删除数据
export const removeItem = key => {
window.localStorage.removeItem(key)
}
6.退出时和使用存储当前用户登录信息:
/*
我的页面
*/
<template>
<div class="mineMain">
<header>
<!-- 登录 -->
<div class="Login" v-if="user">
<div class="loginTop">
<div class="loginInfo">
<van-image class="avator" round fit="cover" src="https://img01.yzcdn.cn/vant/cat.jpeg" />
<span>SunPeng</span>
</div>
<van-button type="default">编辑资料</van-button>
</div>
<div class="loginBottom">
<div class="ebox">
<span>8</span>
<span>收藏</span>
</div>
<div class="ebox">
<span>8</span>
<span>收藏</span>
</div>
<div class="ebox">
<span>8</span>
<span>收藏</span>
</div>
<div class="ebox">
<span>8</span>
<span>收藏</span>
</div>
</div>
</div>
<!-- 未登录 -->
<div class="noLogin" @click="$router.push('/login')" v-else>
<img src="" alt="">
<span><i>登录</i>/<i>注册</i></span>
</div>
</header>
<section>
<van-grid :column-num="2" class="gridNav" clickable>
<van-grid-item dot>
<i slot="icon" class="iconfont icon-shoucang"></i>
<span slot="text">收藏</span>
</van-grid-item>
<van-grid-item icon="photo-o" text="历史" badge="99+" />
</van-grid>
<van-cell title="设置" label="描述信息" clickable />
<van-cell title="消息通知" icon="location-o" value="内容" is-link arrow-direction="down" />
<van-cell is-link>
<template #title>
<span class="custom-title">小智同学</span>
<van-tag type="danger">标签</van-tag>
</template>
<template #right-icon>
<van-icon name="search" class="search-icon" />
</template>
</van-cell>
<van-button v-if="user" type="primary" block @click="handleLoginOut()">退出登录</van-button>
</section>
</div>
</template>
<script>
import { mapState } from 'vuex';//获取用户信息,判断是否登录
export default {
name: 'Mine',
data() {
return {
}
},
computed: {
...mapState(['user'])
},
created() {
},
methods: {
// 退出登录
handleLoginOut() {
const that = this
this.$dialog.confirm({
message: '确认退出登录吗?'
}).then(() => {
// on confirm 清除登录状态(容器+本地)
that.$store.commit('setUser', null)
}).catch(() => {
// on cancel
console.log('取消登录')
})
},
}
}
</script>
版权声明:本文为weixin_53791978原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。