Vue管理系统前端系列三登录页和首页及`vuex`管理登录状态

vue

目录

  • 登录页面设计

    • vuex 对应 用户模块
    • 丰富界面

  • 首页相关代码


登录页面设计

该节记录了登录界面的设计,以及 vuex 的简单实用,然后将首页简单搭建完成。

先看最终效果图

先在 views 文件夹下 新建 login/index.vue 文件。用于登录首页

vuex 对应 用户模块

vuex 相关介绍可参考另一篇博文,链接

新建 store/modules/user.js,将登录状态及内容保存到状态管理器中,内容如下:

import router from '@/router'

export default {

state: {

userInfo: null, //用户信息

token: null,

},

getters: {

userInfo: (state) => {

if (state.userInfo == null) {

let sessionUser = sessionStorage.getItem('user')

if (sessionUser != null) {

state.userInfo = JSON.parse(sessionUser)

return sessionUser

} else {

let localeUser = localStorage.getItem('user')

if (localeUser != null) {

state.userInfo = JSON.parse(localeUser)

}

return localeUser

}

}

return state.userInfo

},

token: (state) => {

if (state.token == null) {

let sessionToken = sessionStorage.getItem('token')

if (sessionToken != null) {

state.token = sessionToken

return sessionToken

} else {

let localeToken = localStorage.getItem('token')

state.token = localeToken

return localeToken

}

}

return state.token

},

},

mutations: {

setToken(state, token, flag = true) {

if (flag) {

localStorage.setItem('token', token)

} else {

sessionStorage.setItem('token', token)

}

},

setUserInfo(state, userInfo, flag = true) {

state.userInfo = userInfo

state.token = userInfo.token

if (flag) {

localStorage.setItem('user', JSON.stringify(userInfo))

} else {

sessionStorage.setItem('user', JSON.stringify(userInfo))

}

this.commit('setToken', userInfo.token, flag)

},

logout(state) {

state.userInfo = null

state.token = null

localStorage.removeItem('token')

localStorage.removeItem('user')

sessionStorage.removeItem('token')

sessionStorage.removeItem('user')

router.push('/login')

},

},

actions: {},

}

然后再在 store/index.js 中将 user 模块引入进来,代码如下:

import Vue from 'vue'

import Vuex from 'vuex'

Vue.use(Vuex)

import user from './modules/user'

const store = new Vuex.Store({

modules: {

user: user,

},

})

export default store

丰富界面

使用 element 的 from 组件,进行设计登录界面。界面代码如下:

<template>

<div class="loginContain">

<div class="loginBox">

<h2 class="loginH2"><span>Vue</span> 后台管理系统</h2>

<el-form :model="loginForm" :rules="loginFormRules" ref="loginForm" label-position="left" label-width="0px" class="login-form">

<el-form-item prop="username">

<el-input type="text" v-model="loginForm.username" auto-complete="off" placeholder="请输入账号">

<i slot="prefix" class="el-input__icon el-icon-user-solid"></i>

</el-input>

</el-form-item>

<el-form-item prop="password">

<el-input type="password" v-model="loginForm.password" auto-complete="off" placeholder="密码">

<i slot="prefix" class="el-input__icon el-icon-lock"></i>

</el-input>

</el-form-item>

<el-form-item style="width:100%;">

<el-button type="primary" style=" width: 100%; background: #19b9e7;" @click.native.prevent="login" :loading="logining">登 录</el-button>

</el-form-item>

</el-form>

</div>

</div>

</template>

登录相关 脚本 代码如下:

<script>

export default {

data() {

return {

logining: false,

loginForm: {

username: 'admin',

password: '123456',

},

notifyObj: null,

loginFormRules: {

username: [{ required: true, message: '请输入账号', trigger: 'blur' }],

password: [{ required: true, message: '请输入密码', trigger: 'blur' }],

},

}

},

//引入组件

components: {},

// 方法

methods: {

login() {

this.logining = true

let userInfo = { username: this.loginForm.username, password: this.loginForm.password }

this.$api.login(userInfo).then((res) => {

if (res.success) {

this.$store.commit('setUserInfo', res.data)

this.$message({

type: 'success',

message: '登录成功',

duration: 800,

})

let redirect = '/'

if (this.$route.query.redirect !== undefined) {

redirect = this.$route.query.redirect

}

setTimeout(() => {

this.logining = false

this.$router.push(redirect)

if (this.notifyObj) {

this.notifyObj.close()

}

this.notifyObj = null

}, 800)

} else {

this.logining = false

this.$message({

type: 'error',

message: '账号或密码错误',

})

}

})

},

},

// 计算属性

computed: {},

//未挂载DOM,不能访问ref为空数组

//可在这结束loading,还做一些初始化,实现函数自执行,

//可以对data数据进行操作,可进行一些请求,请求不易过多,避免白屏时间太长。

created() {},

//可在这发起后端请求,拿回数据,配合路由钩子做一些事情;可对DOM 进行操作

mounted() {

this.notifyObj = this.$notify({

title: '提示',

message: '管理员,账号分别为:admin,密码都为:123456',

duration: 4000,

iconClass: 'el-icon-s-opportunity',

})

},

}

</script>

对界面进行 简单的样式调整,设置背景等,代码如下:

<style lang="scss" scoped>

$inputHeight: 48px;

.loginContain {

height: 100%;

width: 100%;

background: url(../../assets/img/loginbg.jpg) no-repeat center center;

background-size: 100% 100%;

overflow: hidden;

}

.loginBox {

height: 455px;

width: 550px;

margin: 0 auto;

position: relative;

top: 20%;

}

.loginH2 {

font-size: 28px;

color: #fff;

text-align: center;

}

.el-input {

background-color: transparent;

border-radius: 20px;

height: $inputHeight;

color: #ffffff !important;

border: rgba(255, 255, 255, 0.2) 2px solid !important;

}

::v-deep .el-input__inner {

padding-left: 30px;

background-color: transparent !important;

border: none !important;

height: $inputHeight !important;

color: #ffffff !important;

}

.login-form {

-webkit-border-radius: 5px;

border-radius: 5px;

-moz-border-radius: 5px;

background-clip: padding-box;

margin: 10px auto;

width: 380px;

padding: 35px 35px 15px 35px;

}

</style>

相关接口上一篇文章中有写,这里就不再赘述了。

mock 接口截图如下,

既然涉及到登录,那肯定需要进行权限判断,所以我们使用 路由前置守卫进行控制,

  • 若在调试控制台有报 跳转错误等,可参考 跳转错误处理

const WhiteListRouter = ['/login', '/notfound'] // 路由白名单

//导航守卫 路由开始前

router.beforeEach((to, from, next) => {

let user = store.getters.userInfo

let token = store.getters.token

var hasAuth = user !== null && token !== null && user !== undefined && token !== undefined

if (to.path == '/login') {

if (hasAuth) {

next({ path: '/' })

} else {

next()

}

} else {

if (!hasAuth) {

//没登录的情况下 访问的是否是白名单

if (WhiteListRouter.indexOf(to.path) !== -1) {

next()

} else {

next({

path: '/login',

})

}

} else {

next()

}

}

})

路由相关代码

const routes = [

{

path: '/',

name: 'home',

component: () => import('@/views/home'),

children: [

{

path: '',

name: '首页',

component: () => import('@/views/home/defaultPage'),

},

],

},

{

path: '/login',

name: 'login',

component: login,

},

{

path: '/notfound',

name: 'notfound',

component: () => import('@/views/notfound'),

},

{

path: '*',

redirect: '/notfound',

name: 'notfound',

component: () => import('@/views/notfound'),

},

]

其中涉及到的相关页面,就只有自己建了。

首页相关代码

完整代码:

<!-- 首页 -->

<template>

<el-container>

<el-header class="header">

<!-- logo -->

<div class="logo" :class="isCollapse ? 'logo-collapse-width' : 'logo-width'">

<img v-if="isCollapse" src="@assets/logo6065.png" />

<img v-else src="@assets/logo.png" />

</div>

<!-- 折叠按钮 -->

<div class="tools" @click.prevent="collapse">

<i class="el-icon-menu"></i>

</div>

<!-- 头部导航栏 -->

<div class="heardNavBar">

<el-menu default-active="1" class="el-menu-demo" background-color="#4b5f6e" text-color="#fff" active-text-color="#ffd04b" mode="horizontal">

<el-menu-item index="1" @click="$router.push('/')">首页</el-menu-item>

<el-menu-item index="2" @click="openUrl('#')">使用文档</el-menu-item>

<el-menu-item index="3" @click="openUrl('https://github.com/levy-w-wang/lion-ui')">GitHub</el-menu-item>

</el-menu>

</div>

<!-- 右侧信息 -->

<div style="float:right">

<!-- 全屏 -->

<div style="float:left;line-height: 60px; padding: 0 10px;">

<i class="el-icon-full-screen" @click="toggleFull"></i>

</div>

<!-- 个人信息 -->

<div class="userinfo">

<el-dropdown trigger="hover">

<span class="el-dropdown-link userinfo-inner">

<img src="@assets/img/user.jpg" />

{{ userName }}<i class="el-icon-caret-bottom"></i>

</span>

<el-dropdown-menu slot="dropdown">

<el-dropdown-item>

<router-link to="/"><i class="el-icon-s-home"></i>首页</router-link>

</el-dropdown-item>

<el-dropdown-item>

<router-link to="/"><i class="el-icon-s-custom"></i>我的主页</router-link>

</el-dropdown-item>

<el-dropdown-item divided>

<a @click="loginOut()"><i class="el-icon-switch-button"></i>登出</a>

</el-dropdown-item>

</el-dropdown-menu>

</el-dropdown>

</div>

</div>

</el-header>

<el-container>

<el-aside class="aside">

<!--导航菜单 default-active="1-1"-->

<el-menu class="el-menu-vertical-demo" :collapse="isCollapse">

<el-submenu index="1">

<template slot="title">

<i class="el-icon-setting"></i>

<span slot="title">系统管理</span>

</template>

<el-menu-item index="1-1" @click="$router.push('usermanage')">用户管理</el-menu-item>

<el-menu-item index="1-2" @click="$router.push('menumanage')">菜单管理</el-menu-item>

</el-submenu>

<el-menu-item index="2" disabled>

<i class="el-icon-magic-stick"></i>

<span slot="title">导航一</span>

</el-menu-item>

<el-menu-item index="3" disabled>

<i class="el-icon-reading"></i>

<span slot="title">导航二</span>

</el-menu-item>

</el-menu>

</el-aside>

<el-main>

<router-view></router-view>

</el-main>

</el-container>

</el-container>

</template>

<script>

import screenfull from 'screenfull'

export default {

data() {

return {

isCollapse: false,

userName: 'Levy',

}

},

//引入组件

components: {},

// 方法

methods: {

openUrl(url) {

window.open(url)

},

//折叠导航栏

collapse: function() {

this.isCollapse = !this.isCollapse

},

loginOut() {

this.$confirm('确认退出吗?', '提示', {

type: 'warning',

})

.then(() => {

this.$store.commit('logout')

})

.catch(() => {})

},

toggleFull() {

if (!screenfull.isEnabled) {

this.$message({

type: 'warning',

message: 'you browser can not work',

})

return false

}

screenfull.toggle()

},

},

// 计算属性

computed: {},

//未挂载DOM,不能访问ref为空数组

//可在这结束loading,还做一些初始化,实现函数自执行,

//可以对data数据进行操作,可进行一些请求,请求不易过多,避免白屏时间太长。

created() {},

//可在这发起后端请求,拿回数据,配合路由钩子做一些事情;可对DOM 进行操作

mounted() {},

}

</script>

<style lang="scss" scoped>

.aside {

flex: 0 0 230px;

height: 100%;

.el-menu {

height: 100%;

text-align: left;

}

}

.header {

padding-left: 0px !important;

height: 60px;

line-height: 60px;

width: 100%;

background: #4b5f6e;

color: #fff;

.logo {

float: left;

height: 60px;

padding: 0;

margin: 0;

}

.logo-width {

width: 230px;

}

.logo-collapse-width {

width: 65px;

}

.tools {

padding-left: 10px;

padding-right: 10px;

text-align: center;

width: 40px;

height: 60px;

line-height: 60px;

float: left;

cursor: pointer;

}

.heardNavBar {

float: left;

background: #4b5f6e;

padding: 0px 0px;

height: 60px;

line-height: 60px;

font-size: 28px;

cursor: pointer;

}

.userinfo {

text-align: right;

padding-right: 24px;

float: right;

padding: 0 10px;

.userinfo-inner {

font-size: 20px;

cursor: pointer;

color: #fff;

img {

width: 40px;

height: 40px;

border-radius: 10px;

margin: 10px 0px 10px 10px;

float: right;

}

}

}

}

</style>

其中设计到了 全屏按钮 的使用,

需要执行以下安装命令:

npm install sreenfull --save

原文地址:http://book.levy.net.cn/doc/frontend/uiframe/login_home.html

以上是 Vue管理系统前端系列三登录页和首页及`vuex`管理登录状态 的全部内容, 来源链接: utcz.com/z/378241.html

回到顶部