700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 前端开发Vue项目实战:电商后台管理系统(二)-- 登录退出功能 --主页界面

前端开发Vue项目实战:电商后台管理系统(二)-- 登录退出功能 --主页界面

时间:2018-10-03 22:08:00

相关推荐

前端开发Vue项目实战:电商后台管理系统(二)-- 登录退出功能 --主页界面

目录

1. 登录/退出功能1.1 登录概述1.2 token 原理分析1.3 登录功能实现1.3.1 Git 创建分支1.3.2 渲染Login组件并实现路由重定向1.3.3 设置背景颜色并在屏幕中央绘制登录盒子1.3.4 绘制默认头像1.3.5 绘制登录表单区域1.3.6 绘制带icon的input输入框1.3.7 实现表单的数据绑定1.3.8 实现表单的数据验证1.3.9 实现表单的重置功能1.3.10 实现登录前表单数据的预验证,配置axios发起登录请求1.3.11 路由导航守卫控制页面访问权限 1.4 退出功能实现1.5 将本地代码提交到码云Gitee中 2. 主页布局2.1 整体布局2.2 主页Header区域2.2 主页Header区域2.3 左侧菜单布局2.4 通过接口获取菜单数据2.5 获取左侧菜单数据2.6 通过双层for循环渲染左侧菜单2.7 为选中项设置字体颜色并添加分类图标2.8 每次只能打开一个菜单项并解决边框问题2.9 实现侧边栏的折叠与展开效果2.10 首页路由重定向2.11 左侧菜单改造为路由链接

项目地址 /zy4018/vue_zy

1. 登录/退出功能

1.1 登录概述

登录业务流程

在登录页面输入用户名和密码调用后台接口进行验证通过验证之后,根据后台的响应状态跳转到项目主页

登录业务的相关技术点

http是无状态的通过 cookie 在客户端记录状态(无跨域)通过 session 在服务器端记录状态(无跨域)通过 token 方式维持状态(跨域)

1.2 token 原理分析

1.3 登录功能实现

登录页面的布局

通过 Element-UI 组件实现布局

el-formel-form-itemel-inputel-button字体图标

1.3.1 Git 创建分支

这里是打开project里面的vue_shop,在终端中运行以下命令

// 创建分支git checkout -b login// 查看分支,带星号表示当前分支git branch

1.3.2 渲染Login组件并实现路由重定向
清空 App.vue模板 和 router.js 里面不必要的内容删除 ./views 和 ./components/HelloWorld.vue创建组件 ./components/login.vue添加路由规则 router.js 设置默认页面重定向到login

import Login from './components/Login.vue'const routes = [{path: '/', redirect: '/login' },{path: '/login', component: Login },]

App.vue 添加路由占位符

<template><div id="app">App根组件<!-- 路由占位符 --><router-view></router-view></div></template>

1.3.3 设置背景颜色并在屏幕中央绘制登录盒子
在可视化工具中安装 开发依赖 less 和 less-loader安装过依赖后要重新编译

设置全局样式 ./assets/css/global.css入口文件导入全局css文件 ./main.js

// global.css文件/* 全局样式表 */html,body,#app {height: 100%;margin: 0;padding: 0;}// main.js//导入全局样式表import './assets/css/global.css'

设置背景颜色并在屏幕中央绘制登录盒子 Login.vue

// login.vue文件内容<div class="login_container"><div class="login_box"></div></div><style lang="less" scoped>.login_container {background-color: #2b4b6b;height: 100%;}.login_box {width: 450px;height: 300px;background-color: #fff;border-radius:5px ;position:absolute;left:50%;top: 50%;transform: translate(-50%,-50%);}</style>

1.3.4 绘制默认头像

// login.vue文件内容<!-- 头像区域 --><div class="avatar_box"><img src="../assets/logo.png" alt=""></div>.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;//less的嵌套语法img {width: 100%;height: 100%;border-radius: 50%;background-color: #eee;}}

1.3.5 绘制登录表单区域

Element-UI官网

/#/zh-CN

按需导入用到的element组件 ./plugins/element.js

import Vue from 'vue'import {Button,Form, FormItem,Input } from 'element-ui'Vue.use(Button)Vue.use(Form)Vue.use(FormItem)Vue.use(Input)

页面使用引入的组件标签

// Login.vue文件内容<!-- 登录表单区域 --><el-form label-width="0px" class="login_form"><!-- 用户名 --><el-form-item ><el-input></el-input></el-form-item><!-- 密码 --><el-form-item ><el-input></el-input></el-form-item><!-- 按钮区域 --><el-form-item class="btns"><el-button type="primary">登录</el-button><el-button type="info">重置</el-button></el-form-item></el-form>.login_form {width: 100%;position: absolute;bottom: 0;padding: 0 20px;//默认form的box-sizing:content-boxbox-sizing:border-box ;}.btns {display: flex;justify-content: flex-end;}

1.3.6 绘制带icon的input输入框

/#/zh-CN/component/input

/#/zh-CN/component/icon

<!-- 用户名 --><el-form-item ><el-input prefix-icon="el-icon-s-custom"></el-input></el-form-item><!-- 密码 --><el-form-item ><el-input prefix-icon="el-icon-lock"></el-input></el-form-item>

阿里字体图标库的使用

下载选好的阿里字体图标demo_fontclass.html查看图标名称fonts文件放入assets文件夹中main.js 中引入iconfont.css样式表 import ‘./assets/fonts/iconfont.css’标签添加类名 class=“iconfont icon-xxx”

1.3.7 实现表单的数据绑定

希望把用户名和密码对应的值可以自动绑定到数据源上

// 1. 为el-form添加:model属性绑定,指向一个数据对象// 2. 为每一个表单项通过v-model绑定到数据对象中对应的属性<el-form :model="loginForm"><el-input v-model="loginForm.username"></el-input><el-input v-model="loginForm.password" type="password"></el-input></el-form>export default {data () {return {// 登录表单的数据绑定对象loginForm: {username: 'admin',password: '123456'}}}}

1.3.8 实现表单的数据验证

/#/zh-CN/component/form

//1.为el-form属性绑定一个校验规则对象loginFormRules//2.在校验规则对象之中定义属性username 和 password//3.在表单item项中通过prop指定校验规则属性export default {data() {return {// 表单验证规则对象loginFormRules: {//验证用户名是否合法username: [{required: true, message: '请输入登录名称', trigger: 'blur' },{min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' },],// 验证密码是否合法password: [{required: true, message: '请输入登录密码', trigger: 'blur' },{min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' },],},}},}

1.3.9 实现表单的重置功能
添加引用ref获取表单实例对象(通过 ref 标注 DOM 元素)重置按钮绑定单击事件定义重置方法(通过 $refs 获取 DOM 元素)

methods: {// 点击重置按钮,重置登录表单resetLoginForm () {// console.log(this) // VueComponentthis.$refs.loginFormRef.resetFields()}}

1.3.10 实现登录前表单数据的预验证,配置axios发起登录请求
在发起请求之前运行mySql数据库运行 app.js导入axios包main.js,配置axios

import axios from 'axios'// 配置请求的根路径axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'Vue.prototype.$http = axios

登录按钮添加点击事件

<el-button type="primary" @click="login">登录</el-button>

导入弹框提示组件element.js

/#/zh-CN/component/message

import {Message } from 'element-ui'Vue.prototype.$message = Message // 弹框提示组件挂在在Vue原型上

编写login方法

login() {// valid是一个布尔值,如果表单格式验证合法就为true//先判断valid是否为true,如果不等于true就直接返回,等于true发起请求this.$refs.loginFormRef.validate(async (valid) => {if (!valid) return// 发起请求,方式是post,并且携带参数// data属性结构赋值,重命名为resconst {data: res } = await this.$http.post('login', this.loginForm)if (res.meta.status != 200) return this.$message.error('登陆失败')this.$message.success('登陆成功')// 将登录成功之后的token保存到客户端的sessionStorage中(会话期间的存储机制)(所以不放在localStorage)// 项目中除了登录之外的其他API接口,必须在登录之后才能访问window.sessionStorage.setItem('token',res.data.token)// 通过编程式导航跳转到后台主页,路由地址是/homethis.$router.push('/home')})},

router.js 并导入路由规则

import Home from './components/Home.vue'const routes = [ {path: '/home', component: Home, }]

1.3.11 路由导航守卫控制页面访问权限

如果用户没有登录,但是直接通过URL访问有特定权限的页面,需要重新导航到登录页面

// 挂载路由导航守卫router.beforeEach((to, from, next) => {// to 将要访问的路径// from 代表从哪个路径跳转而来// next 是一个函数, 表示放行 next()放行 next('/login')强制跳转if (to.path === '/login') return next() // 用户访问登录页,直接放行// 获取tokenconst tokenStr = window.sessionStorage.getItem('token')if (!tokenStr) return next('/login') // 没有token, 强制跳转到登录页next() // 否则(有token)直接放行})

登录效果展示

1.4 退出功能实现

退出功能实现原理

基于token的方式实现退出比较简单,只需要销毁本地的token即可。

这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才可以访问页面

//清空tokenwindow.sessionStorage.clear()//跳转到登录页this.$router.push('/login')

具体操作 Home.vue

<template><div><el-button type="info" @click="goout">退出</el-button></div></template>export default {methods:{goout(){window.sessionStorage.clear()this.$router.push('/login')}}}

1.5 将本地代码提交到码云Gitee中

git status //查看文件状态git add . //代码添加到缓存区git commit -m "完成了登录功能" //提交到本地库git branch //查看分支git checkout master //切换分支到主分支上git merge login //在主分支上合并login分支的代码git push //推送到码云中// 将login分支也推送到码云中git checkout login //先切换到login分支git push -u origin login //推送

如果推送失败,没反应,可以先把仓库和项目再关联一下

git remote add origin /****/vue_zy.git

2. 主页布局

2.1 整体布局

/#/zh-CN/component/container

要先在 .plugins/element.js中引入样式

import {Container,Header,Aside,Main } from 'element-ui'Vue.use(Container)Vue.use(Header)Vue.use(Aside)Vue.use(Main)

Home.vue内容

<template><el-container class="home-container">//头部区域 //每一个element-UI中提供的组件名称就是类名,即el-header就是类名 <el-header>Header <el-button type="info" @click="goout">退出</el-button></el-header>//页面主体区域<el-container>// 侧边栏 <el-aside width="200px">Aside</el-aside>// 右侧内容主体 <el-main>Main</el-main></el-container></el-container></template><style lang="less" scoped>.home-container {height: 100%;}.el-header {background-color: #373D41;}.el-aside {background-color: #333744;}.el-main {background-color: #eaedf1;}</style>

2.2 主页Header区域

```html```cpp```css<!-- 头部区域 --><el-header><div><img src="../assets/heima.png" alt=""><span>电商后台管理系统</span></div><el-button type="info" @click="goout">退出</el-button></el-header>.el-header {background-color: #373D41;display: flex;//左右贴边对齐justify-content: space-between;//上下居中align-items: center;//字体color:#fff;font-size: 20px;//嵌套子选择器> div {display: flex;align-items: center;span {margin-left: 15px;}}

2.2 主页Header区域

//头部区域 <el-header><div><img src="../assets/heima.png" alt=""><span>电商后台管理系统</span></div><el-button type="info" @click="goout">退出</el-button></el-header>.el-header {background-color: #373D41;display: flex;//flex布局左右贴边对齐justify-content: space-between;//flex布局上下居中align-items: center;//字体color:#fff;font-size: 20px;//嵌套子选择器> div {display: flex;align-items: center;span {margin-left: 15px;}}}

2.3 左侧菜单布局

/#/zh-CN/component/menu

// 侧边栏菜单区域 <el-menu background-color="#333744" text-color="#fff" active-text-color="#ffd04b">//一级菜单<el-submenu index="1">//一级菜单的模板区域<template slot="title">//图标<i class="el-icon-location"></i>//文本<span>一级菜单</span></template>//二级菜单<el-menu-item index="1-4-1"><template slot="title"><i class="el-icon-location"></i><span>二级菜单</span></template></el-menu-item></el-submenu></el-menu>

2.4 通过接口获取菜单数据

通过axios请求拦截器添加token验证,保证拥有获取数据的权限;

需要授权的 API ,必须在请求头中使用 Authorization字段提供 token 令牌;

后台除了登录接口之外,都需要token权限验证,我们可以通过添加axios请求拦截器来添加token,以保证拥有获取数据的权限;

在main.js中添加代码,在将axios挂载到vue原型之前添加下面的代码

2.5 获取左侧菜单数据

上面是console.log(result)的左侧菜单的数据,可以看到打印出来是一个对象;

meta显示获取菜单列表成功;data是所有数据,总共5个一级菜单,第一个一级菜单通过children属性嵌套了自己的二级菜单

data() {return {//拿到数据之后,为了在页面中渲染出来,应该把获取到的数据立即挂载到data里面//左侧菜单数据menulist: [],}},//页面加载之前就要获取数据,定义生命周期函数created() {this.getMenuList()},methods: {//获取所有菜单async getMenuList() {const {data: result } = await this.$http.get('menus')//如果获取数据失败,就弹出错误消息,并且错误消息是保存在result.meta.msg里面的if (result.meta.status !== 200) return this.$message.error(result.meta.msg)//如果成功就赋值this.menulist = result.dataconsole.log(result)},},

2.6 通过双层for循环渲染左侧菜单

//一级菜单 <el-submenu :index="item.id + ''" v-for="item in menulist" :key="item.id">//一级菜单的模板区域<template slot="title"><i class="el-icon-location"></i><span>{{item.authName}}</span></template> <!-- 二级菜单 --><el-menu-item :index="subItem.id + '' " v-for="subItem in item.children" :key="subItem.id"><template slot="title"><i class="el-icon-location"></i><span>{{subItem.authName}}</span></template></el-menu-item></el-submenu>

2.7 为选中项设置字体颜色并添加分类图标

通过更改el-menu的active-text-color属性可以设置侧边栏菜单中点击的激活项的文字颜色

<el-menu background-color="#333744" text-color="#fff" active-text-color="#409EFF">

在data中添加一个iconsObj,然后将图标类名进行双向数据绑定

iconsObj: {125: 'el-icon-s-custom',103: 'el-icon-s-check',101: 'el-icon-s-goods',102: 'el-icon-s-order',145: 'el-icon-s-marketing',},

一级菜单图标绑定iconsObj中的数据:

<i :class="iconsObj[item.id]"></i>

2.8 每次只能打开一个菜单项并解决边框问题

为了保持左侧菜单每次只能打开一个,显示其中的子菜单,我们可以在el-menu中添加一个属性unique-opened

<el-menu unique-opened>

或者也可以数据绑定进行设置(此时true认为是一个bool值,而不是字符串)

:unique-opened=“true”

解决边框不对齐问题

.el-menu {border-right: none;}

2.9 实现侧边栏的折叠与展开效果

//三元运算,当isCollapse 变成true,折叠起来的时候,侧边栏宽度变成60px<el-aside :width="isCollapse ? '60px':'200px'"><div class="toggle-button" @click ="toggleCollapse"> ||| </div>// 侧边栏菜单区域// collapse是否水平折叠收起菜单,默认是false,不折叠// collapse-transition 是否开启折叠动画,默认是true开启,要关闭<el-menu :collapse="isCollapse" :collapse-transition='false'>//点击按钮,切换菜单的折叠与展开data() {return {isCollapse:false //不折叠}},methods: {toggleCollapse(){this.isCollapse=!this.isCollapse //取反}}.toggle-button {background-color: #4A5064;font-size: 10px;line-height: 24px;color: #fff;text-align: center;letter-spacing: 0.2em;cursor: pointer;}

2.10 首页路由重定向

新增子级路由组件 ./components/Welcome.vue在router.js中导入子级路由组件,并设置路由规则以及子级路由的默认重定向

import Welcome from '../components/Welcome.vue'const routes = [{path: '/home',component: Home,redirect: '/welcome',children: [{path: '/welcome', component: Welcome }]}]

打开Home.vue,在main的主体结构中添加一个路由占位符

<!-- 右侧内容主体 --><el-main><router-view></router-view></el-main>

2.11 左侧菜单改造为路由链接

需要将所有的侧边栏二级菜单都改造成子级路由链接,我们只需要将el-menu的router属性设置为true就可以了,此时当我们点击二级菜单的时候,就会根据菜单的index属性进行路由跳转,如: /110

<!-- 侧边栏菜单区域 --><el-menu background-color="#333744" text-color="#fff" active-text-color="#409EFF" unique-opened :collapse="isCollapse" :collapse-transition='false' :router="true">

使用index id来作为跳转路径不合适,我们可以重新绑定index的值为 :index=“’/’+subItem.path”

<!-- 二级菜单 --><el-menu-item :index=" '/'+ subItem.path " v-for="subItem in item.children" :key="subItem.id">

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。