**
Vue电商后台管理系统
**
前言
(二)登录和退出功能的实现
一、git操作
进入vscode,进入项目目录
1.检查git状态:git status
显示clean,则继续:
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
如果还有没被添加的文件:
% git add .
% git commit -m "add files"
2.添加分支
因为项目有很多功能,每个功能都在一个分支内完成,最后再合并到master上。
% git checkout -b login //创建一个登录分支
Switched to a new branch 'login'
% git branch //列出所有分支
* login // *表示正处于这个分支上
master
二、梳理项目结构
1.打开项目可视化管理界面
进入终端:
% vue ui
2.运行项目
进入任务,点击serve,点击运行,编译完成,点击启动app
3.重置页面布局
(1)打开vscode,src->main.js(打包的入口文件)
import Vue from 'vue'
import App from './App.vue' // 引入App.vue
import router from './router'
import './plugins/element.js'
import './assets/css/global.css'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App) // 把App渲染到根组件中
}).$mount('#app')
(2)src->App.vue
这是页面布局,要删除默认的布局
<template>
<div id="app">
App根组件
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
</style>
(3)src->router->index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
]
const router = new VueRouter({
routes
})
export default router
(4)删除views目录删除
(5)删除components->HelloWorld.vue
4.接下来可以基于干净的项目进行开发了
三、定义login组件
1.定义login单文件组件
(1)components->login.vue
单文件组件由三部分组成:结构,样式,行为
<template>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
// lang="less"表示在这个节点中支持less语法格式
// scoped是vue指令,用来控制组件样式生效区间_只在当前组件内生效
</style>
2.渲染login组件到页面
在router中,通过路由的形式把它渲染到App根组件中
(1)进入router->index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import login from '../components/login.vue'
Vue.use(VueRouter)
// 路由规则
const routes = [
// 只要用户访问了/根路径,就重定向到登录页面
{ path: '/', redirect: '/login' },
{ path: '/login', component: login }
]
const router = new VueRouter({
routes
})
export default router
(2)在App根组件中放一个路由占位符
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
</style>
四、完成login组件的布局
1.安装开发依赖
2.全局样式表
(1)在assets->css->创建global.css
html, body, #app {
height: 100%;
margin: 0;
padding: 0;
}
(2)让全局样式表生效
在main.js(入口文件中),导入全局样式表,让其生效
import './assets/css/global.css'
3.绘制登录盒子以及头像
打开login.vue
<template>
<div class="login_container">
<div class="login_box">
<!-- 头像盒子 -->
<div class="avatar_box">
<img src="../assets/logo.png" alt="">
</div>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
.login_container{
background-color: #2b4b6b;
height: 100%;
display: flex;
justify-content: center;
}
.login_box{
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px;
position: absolute;
top: 50%;
transform: translateY(-50%);
.avatar_box{
border: 1px solid #eee;
padding: 10px;
border-radius: 50%;
width: 130px;
height: 130px;
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;
}
}
}
</style>
4.绘制登录表单区域
用Element-UI组件实现布局:el-form,el-form-item,el-input,el-button,字体图标
(1)打开Element-UI的官网
点击form表单,找到典型表单,只需要粘贴一部分
在login.vue中的login_box中添加
<!-- 登录表单区域 -->
<el-form label-width="0px">
<el-form-item>
<el-input></el-input>
</el-form-item>
</el-form>
结果报错:Unknown custom element: …
是因为element-ui是按需导入的
需要在plugins->element.js中按需导入要使用的元素
import Vue from 'vue'
import { Button, Form, FormItem, Input } from 'element-ui'
// 使用Vue.use把它们注册为全局可用的组件
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
(2)表单布局和样式
布局:
<!-- 登录表单区域 -->
<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>
<el-button type="primary" plain>登录</el-button>
<el-button type="info" plain>重置</el-button>
</el-form-item>
</el-form>
样式:
.login_form{
width: 100%;
position: absolute;
bottom: 0px;
padding: 0 20px;
box-sizing: border-box;
}
(3)绘制带icon的输入框
进入element-ui官网,找到input输入框中的带 icon 的输入框
属性方式为input表单添加icon
在前面添加icon:prefix-icon=“XXX”
在网上下载图标
需要在main.js入口文件
// 导入字体图标:import ‘./assets/fonts/iconfont.css’
添加icon属性:prefix-icon=“iconfont icon-3702mima”
prefix-icon=“iconfont icon-user”
5.表单的数据绑定
(1)为el-form加上:model=""属性,指向一个数据对象
<el-form :model="loginForm" label-width="0px" class="login_form">
(2)为el-input加上v-model=""属性,绑定到数据对象的属性中
<el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input>
<el-input v-model="loginForm.password" prefix-icon="iconfont icon-3702mima"></el-input>
(3)数据对象
<script>
export default {
data () {
return {
loginForm: {
username: 'yyq',
password: '123456'
}
}
}
}
</script>
(4)细节:密码隐藏,为密码的input标签加上type属性 type=“password”
6.实现表单的数据验证
进入element-ui官网,找到form表单__表单验证__在防止用户犯错的前提下,尽可能让用户更早地发现并纠正错误。
(1)为el-form绑定rules属性,值为表单验证规则对象(在data数据里面定义)
(2)写具体的验证规则
loginFormRules: {
// 验证用户名是否合法
username: [
// required: true必填项
{ required: true, message: '请输入登录名称', trigger: 'blur' },
{ min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
],
// 验证密码是否合法
password: [
{ required: true, message: '请输入登录密码', trigger: 'blur' },
{ min: 6, max: 10, message: '长度在 6 到 10 个字符', trigger: 'blur' }
]
}
(3)让验证规则生效
为el-item添加props=“具体的规则”
<!-- 用户名 -->
<el-form-item prop="username">
<el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input>
</el-form-item>
<!-- 密码 -->
<el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" prefix-icon="iconfont icon-3702mima"></el-input>
</el-form-item>
7.实现表单的重置功能
在element-ui中找到form表单->form methods->resetFields(对整个表单进行重置,将所有字段值重置为初始值并移除校验结果)
拿到表单的实例对象,然后调用resetFields函数重置表单
(1)拿到表单实例对象
对el-form添加ref=“loginFormRef”
(2)为"重置"按钮绑定点击事件
<el-button type="info" plain v-on:click="resetLoginForm">重置</el-button>
(3)定义resetLoginForm方法
methods: {
resetLoginForm () {
this.$refs.loginFormRef.resetFields()
}
}
this->当前login.vue组件的实例对象
实例上有一个属性 $refs(与自定义的属性一致)
8.实现登录前表单数据的预验证
必须验证通过后,才可以发起登陆请求,否则应该直接提示用户输入不合法,怎么进行预验证呢?
点击登陆后,通过调用表单的某一个函数进行验证,那么是哪个函数呢?
validate——对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise
拿到表单的实例对象,然后调用resetFields函数重置表单(同上一步操作)
(1)拿到表单实例对象
对el-form添加ref=“loginFormRef”
(2)对登录按钮添加点击事件
<el-button type="primary" plain v-on:click="login">登录</el-button>
(3)写login方法
login () {
this.$refs.loginFormRef.validate((valid) => {
// true/false_验证结果
console.log(valid)
})
}
五、配置axios发起登陆请求
1.配置axios
在main.js入口文件中添加axios的配置
// 配置axios
import axios from 'axios'
Vue.prototype.$http = axios
// 配置请求的根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
2.发起登陆请求
(1)在login方法中 ,通过this访问原型上的$http这个成员,发起登录请求
login () {
this.$refs.loginFormRef.validate((valid) => {
// console.log(valid)
if (!valid) return
const result = this.$http.post('login', this.loginForm)
console.log(result)
})
}
(2)打开后台api接口和MySql
node app.js
(3)点击登录后
result是promise对象
可以用await/async来简化这次promise操作
login () {
this.$refs.loginFormRef.validate(async (valid) => {
// console.log(valid)
if (!valid) return
const result = await this.$http.post('login', this.loginForm)
console.log(result)
})
}
这次结果是:
这里只有data属性我们需要
解构赋值操作把真实数据提取出来
const { data: res } = await this.$http.post('login', this.loginForm)
console.log(res)
3.判断msg
if (res.meta.status !== 200) return console.log('登录失败')
六、配置message全局弹框组件
目前,登录成功/失败,是在console中显示,用户是看不到的,为了让用户明确知道自己登录是否成功,可以用element-ui中的Message消息提示
1.导入组件
在plugins->element.js中
import { Button, Form, FormItem, Input, Message } from 'element-ui'
// 把Message挂载到Vue的原型对象身上
Vue.prototype.$message = Message
2.使用弹框
if (res.meta.status !== 200) return this.$message.error('登录失败!')
this.$message.success('登录成功!')
七、完善登录成功后操作
1.将登录成功后的token,保存到客户端的 sessionStorage 中
1.1项目中出现了登录之外的其他API接口,必须在登录后才能访问
1.2token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
2.通过编程式导航跳转到后台主页,路由地址是/home
(1)获取token
res.data.token
(2)把token保存到sessionStorage中
window.sessionStorage.setItem('token', res.data.token)
(3)通过编程式导航跳转到后台主页,路由地址是/home
this.$router.push('/home')
3.写主页组件
(1)在components->创建Home.vue
<template>
<div>
Home 组件
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
(2)把home组件渲染到根组件
import home from '../components/home.vue'
// 添加路由规则
{ path: '/home', component: home }
4.路由导航守卫控制页面访问权限
必须在登录成功的情况下才能访问到home接口下的界面,但是把token清除之后,刷新页面,还是能访问__不满足需求
没有登录的情况下访问home界面,需要跳转到登录页面
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to将要访问的路径
// from代表从哪个路径跳转而来
// next是一个函数,表示放行
// next('/login') 强制跳转
// 如果直接访问的是登录页__直接放行
if (to.path === '/login') return next()
// 获取token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) {
// 如果没有token__表示未登录__强制跳转到登录页
return next('/login')
} else {
// 如果有token__表示登录成功__放行
next()
}
})
八、实现退出功能
1.实现原理
基于token的方式实现退出比较简单,只需要销毁本地的token即可。这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才可以访问。
2.实现步骤
(1)在home.vue写出一个退出按钮
<template>
<div>
<el-button type="info">退出</el-button>
Home 组件
</div>
</template>
(2)为退出按钮绑定一个单机事件
<el-button type="info" v-on:click="quit">退出</el-button>
methods: {
quit () {
// 清空token
window.sessionStorage.clear()
// 清空后重定向到登录界面
this.$router.push('/login')
}
}
九、处理项目中ESLint语法报错问题
1.在项目中新增一个配置.prettierrc文件,自动转化为ESLint格式
{
"semi": false,
"singleQuote": true
}
2.在.eslintrc.js中的rules新增
'space-before-function-paren': 0
十、上传到本地仓库,再同步到码云中
1.上传到本地仓库
(1)git status__显示已经修改和新增的文件
(2)把所有文件都添加到暂存区
git add .
git status // 所有文件都显示绿色__已经被添加到暂存区
(3)把这些文件提交一下
git commit -m "完成了登录功能"
git branch
* login
master
// 表示刚才commit提交的问件都被提交到了login分支里面进行保存
(4)把login分支合并到master主分支
切换到master主分支
git checkout master
基于master分支合并login分支
git merge login
(5)把本地仓库的master分支中最新代码推送到码云中
% git push
Enumerating objects: 53, done.
Counting objects: 100% (53/53), done.
Delta compression using up to 4 threads
Compressing objects: 100% (35/35), done.
Writing objects: 100% (42/42), 28.28 KiB | 1.09 MiB/s, done.
Total 42 (delta 12), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
To https://gitee.com/yyq326/vue_shop.git
cecd055..858a579 master -> master
2.把本地的login分支一并推送的码云中
qiaofang@qiaofangdeMacBook-Air vue_shop % git checkout login
Switched to branch 'login'
qiaofang@qiaofangdeMacBook-Air vue_shop % git branch
* login
master
qiaofang@qiaofangdeMacBook-Air vue_shop % git push -u origin login
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
remote: Create a pull request for 'login' on Gitee by visiting:
remote: https://gitee.com/yyq326/vue_shop/pull/new/yyq326:login...yyq326:master
To https://gitee.com/yyq326/vue_shop.git
* [new branch] login -> login
Branch 'login' set up to track remote branch 'login' from 'origin'.