login.vue代码
<template>
<div class="login_container">
<div class="login_box">
<!-- 头像区域 -->
<div class="avatar_box">
<img src="../assets/logo.png" alt="">
</div>
<!-- 登录表单区域 -->
<el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
<!-- 用户名 -->
<el-form-item prop="username">
<el-input v-model="loginForm.username" prefix-icon="el-icon-user"></el-input>
</el-form-item>
<!-- 密码 -->
<el-form-item prop="password">
<el-input v-model="loginForm.password" prefix-icon="el-icon-wallet" type="password"></el-input>
</el-form-item>
<!-- 按钮区域 -->
<el-form-item class="btns">
<el-button type="primary" @click="login">登录</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// 这是登录表单的数据绑定对象
loginForm:{
username:'admin',
password:'123456'
},
// 这是表单的验证规则对象
loginFormRules:{
// 验证用户名是否合法
username:[
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
],
// 验证密码是否合法
password:[
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
]
}
}
},
methods:{
// 点击重置按钮,重置登录表单
resetLoginForm(){
this.$refs.loginFormRef.resetFields();
},
login(){
this.$refs.loginFormRef.validate(async valid=>{
if(!valid) return;
const {data: res} =await this.$http.post('login', this.loginForm)
if(res.meta.status !== 200) return this.$message.error('登录失败!')
this.$message.success('登录成功');
//将登录成功后的token保存到客户端的sessionStorage中
//项目中除了登录之外的其他API接口,必须在登录之后才能访问
//token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
window.sessionStorage.setItem('token',res.data.token);
//通过编程式导航跳转到后台页面,路由地址是/home
this.$router.push('/home')
})
}
}
}
</script>
<style scoped>
.login_container{
background-color:#2b4b6b;
height: 100%;
}
.login_box{
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.avatar_box{
height: 130px;
width: 130px;
border: 1px solid #eee;
border-radius: 50%;
padding: 10px;
box-shadow: 0 0 10px #ddd;
position: absolute;
left: 50%;
transform: translate(-50%,-50%);
background-color: #fff;
}
img {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #eee;
}
.btns{
display: flex;
justify-content: flex-end;
}
.login_form{
position: absolute;
bottom:0;
width: 100%;
padding: 0 20px;
box-sizing: border-box;
}
</style>
main.js代码
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
// 导入全局样式表
import './assets/css/global.css'
//引入axios
import axios from 'axios'
// 配置请求的根路径
axios.defaults.baseURL ='http://127.0.0.1:8888/api/private/v1/'
Vue.prototype.$http = axios
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
App.vue代码
<template>
<div id="app">
<!-- 路由站位符 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'app'
}
</script>
<style>
</style>
index.js代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
routes
})
export default router