[toc]
### 一、实现退出登录功能
1.1 设置退出登录接口
```
export function logout() {
return request({
url: '/admin/user/logout',
method: 'post'
})
}
```
### 二、实现注册页面布局
2.1 删除登录布局默认提示的一些内容
2.2 创建注册按钮
```
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
<div>
<el-button type="default" style="width:100%;margin-bottom:30px;">
切换为注册
</el-button>
</div>
```
2.3 修改登录布局文字
```
<div class="title-container">
<h3 class="title">登录</h3>
</div>
placeholder="请输入用户名"
placeholder="请输入密码"
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">登录</el-button>
```
2.4 实现注册布局和登录注册切换
```
<template>
<div class="login-container">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
<div class="title-container">
<h3 class="title">{{inputType == "login" ? "登录" : "注册"}}</h3>
</div>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input
ref="username"
v-model="loginForm.username"
placeholder="请输入用户名"
name="username"
type="text"
tabindex="1"
autocomplete="on"
/>
</el-form-item>
<el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
:type="passwordType"
placeholder="请输入密码"
name="password"
tabindex="2"
autocomplete="on"
@keyup.native="checkCapslock"
@blur="capsTooltip = false"
@keyup.enter.native="handleLogin"
/>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
</el-form-item>
</el-tooltip>
<el-tooltip v-if="inputType == 'reg'" v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
<el-form-item prop="repassword">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input
:key="repasswordType"
ref="repassword"
v-model="loginForm.repassword"
:type="repasswordType"
placeholder="请输入确认密码"
name="repassword"
tabindex="2"
autocomplete="on"
@keyup.enter.native="handleLogin"
/>
<span class="show-pwd" @click="showRePwd">
<svg-icon :icon-class="repasswordType === 'password' ? 'eye' : 'eye-open'" />
</span>
</el-form-item>
</el-tooltip>
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">
{{inputType == "login" ? "登录" : "注册"}}
</el-button>
<div>
<el-button type="default" @click="inputType = inputType == 'login' ? 'reg' : 'login'" style="width:100%;margin-bottom:30px;">
{{inputType == "login" ? "切换为注册" : "切换为登录"}}
</el-button>
</div>
</el-form>
</div>
</template>
<script>
import { validUsername } from '@/utils/validate'
export default {
name: 'Login',
data() {
// const validateUsername = (rule, value, callback) => {
// if (!validUsername(value)) {
// callback(new Error('Please enter the correct user name'))
// } else {
// callback()
// }
// }
// const validatePassword = (rule, value, callback) => {
// if (value.length < 6) {
// callback(new Error('The password can not be less than 6 digits'))
// } else {
// callback()
// }
// }
return {
inputType : "login",
loginForm: {
username: '',
password: '',
repassword : ""
},
passwordType: 'password',
repasswordType: 'password',
capsTooltip: false,
loading: false,
showDialog: false,
redirect: undefined,
otherQuery: {}
}
},
computed: {
loginRules(){
let rules = {
username: [{ required: true, trigger: 'blur', }],
password: [{ required: true, trigger: 'blur', }]
}
if(this.inputType == "reg"){
rules.repassword = [{ required: true, trigger: 'blur', }]
}
return rules;
}
},
watch: {
$route: {
handler: function(route) {
const query = route.query
if (query) {
this.redirect = query.redirect
this.otherQuery = this.getOtherQuery(query)
}
},
immediate: true
}
},
created() {
// window.addEventListener('storage', this.afterQRScan)
},
mounted() {
if (this.loginForm.username === '') {
this.$refs.username.focus()
} else if (this.loginForm.password === '') {
this.$refs.password.focus()
}
},
destroyed() {
// window.removeEventListener('storage', this.afterQRScan)
},
methods: {
checkCapslock(e) {
const { key } = e
this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
},
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus()
})
},
showRePwd() {
if (this.repasswordType === 'password') {
this.repasswordType = ''
} else {
this.repasswordType = 'password'
}
this.$nextTick(() => {
this.$refs.repassword.focus()
})
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push({ path: "/" })
this.loading = false
})
.catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
},
getOtherQuery(query) {
return Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
}
return acc
}, {})
}
// afterQRScan() {
// if (e.key === 'x-admin-oauth-code') {
// const code = getQueryObject(e.newValue)
// const codeMap = {
// wechat: 'code',
// tencent: 'code'
// }
// const type = codeMap[this.auth_type]
// const codeName = code[type]
// if (codeName) {
// this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
// this.$router.push({ path: this.redirect || '/' })
// })
// } else {
// alert('第三方登录失败')
// }
// }
// }
}
}
</script>
```
2.5 实现注册功能
2.5.1 配置注册接口
```
export function reg(data) {
return request({
url: '/user/reg',
method: 'post',
data
})
}
```
2.5.2 实现注册功能
```
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
if(this.inputType == "reg"){
reg(this.loginForm).then(response=>{
this.loading = false;
this.$message.success("注册成功")
this.inputType = "login"
this.loginForm = {
username : "",
password : "",
repassword : ""
}
}).catch(error=>{
this.loading = false;
})
return
}
this.$store.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push({ path: "/" })
this.loading = false
})
.catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
},
```
- 第一章 项目介绍
- 1.1 项目介绍
- 第二章 创建项目和基础部分
- 2.1 安装创建Vue项目和配置
- 2.2 配置开发工具和高效代码块
- 2.3 创建路由菜单和页面(一)
- 2.4 创建路由菜单和页面(二)
- 第三章 课程模块开发
- 3.1 图文列表页开发 (一)
- 3.2 图文列表页开发 (二)
- 3.3 新增api和mock使用 (一)
- 3.4 新增api和mock使用 (二)
- 3.5 新增api和mock使用 (三)
- 3.6 删除图文功能
- 3.7 新增图文功能 (一)
- 3.8 新增图文功能 (二)
- 3.9 完善图文管理细节
- 3.10 音频列表管理功能
- 3.11 音频新增编辑功能
- 3.12 管理视频功能开发
- 3.13 专栏列表功能
- 3.14 专栏详情功能实现(一) - 创建跳转
- 3.15 专栏详情功能实现(二) - 传参和布局
- 3.16 专栏详情功能实现(三) - 获取详情
- 3.17 专栏目录管理搭建
- 3.18 专栏目录拖拽排序实现
- 3.19 弹出课程选择框开发 (一) 0 布局1
- 3.20 弹出课程选择框开发 (二) - 布局2
- 3.21 弹出课程选择框开发 (三) - 功能
- 3.22 弹出课程选择框卡挨罚 (四) - 完善
- 第四章 用户模块开发
- 4.1 用户管理列表开发 (一)
- 4.2 用户管理列表开发 (二)
- 4.3 查看用户相关详情 (一)
- 4.4 查看用户相关详情 (二)
- 4.5 查看用户相关详情 (三) - 动态表格1
- 4.6 查看用户相关详情 (四) - 动态表格2
- 4.7 查看用户相关详情 (五) - 动态表格3
- 4.8 批量禁止评论和访问
- 第五章 交易模块开发
- 5.1 订单管理开发 (一)
- 5.2 订单管理开发 (二) - 列表渲染
- 5.3 订单管理开发 (三) - 导出excel
- 5.4 订单管理开发 (四) - 删除订单
- 5.5 资产管理开发 (一)
- 5.6 资产管理开发 (二)
- 5.7 资产管理开发 (三) - 提现1
- 5.8 资产管理开发 (四) - 提现2
- 5.9 支付设置开发 (一)
- 5.10 支付设置开发 (二) - 地区选择器
- 5.11 支付设置开发 (三)
- 第六章 可视化拖拽管理多端(移动端)
- 6.1 可视化布局 (一)
- 6.2 可视化布局 (二) - 移动端列表1
- 6.3 可视化布局 (三) - 移动端列表2
- 6.4 可视化布局 (四) - 移动端组件列表
- 6.5 可视化布局 (五) - 移动端组件布局1
- 6.6 可视化布局 (六) - 移动端组件布局2
- 第七章 可视化拖拽管理多端(pc端)
- 7.1 可视化 - PC端列表
- 7.2 可视化 - PC端组件布局 (一)
- 7.3 可视化 - PC端组件布局 (二)
- 7.4 可视化 - PC端导航布局
- 7.5 可视化 - PC端轮播图模块
- 7.6 可视化 - PC端图标分类模块
- 7.7 可视化 - PC端列表模块
- 7.8 可视化 - PC端底部布局
- 第八章 营销模块开发
- 8.1 拼团模块 - 列表 (一)
- 8.2 拼团模块 - 列表和下架 (二)
- 8.3 拼团模块 - 列表和下架 (三)
- 8.4 拼团模块 - 创建和修改 (一)
- 8.5 拼团模块 - 创建和修改 (二)
- 8.6 拼团模块 - 创建和修改 (三)
- 8.7 秒杀模块开发
- 8.8 优惠卷模块开发 (一)
- 8.9 优惠卷模块开发 (三)
- 第九章 问答和题库模块开发
- 9.1 题库模块 - 列表和删除 (一)
- 9.2 题库模块 - 列表和删除 (二)
- 9.3 题库模块 - 自定义编辑器组件 (一)
- 9.4 题库模块 - 自定义编辑组件 (二)
- 9.5 题库模块 - 关联类型和答案 (一)
- 9.6 题库模块 - 关联类型和答案 (二)
- 9.7 题库模块 - 关联类型和答案 (三)
- 9.8 试卷模块 - 列表管理 (一)
- 9.9 试卷模块 - 列表管理 (二)
- 9.10 试卷模块 - 手动组卷 (一)
- 9.11 试卷模块 - 手动组卷 (二)
- 9.12 试卷模块 - 手动组卷 (三)
- 9.13 试卷模块 - 手动组卷 (四)
- 9.14 试卷模块 - 手动组卷 (五)
- 9.15 试卷模块 - 编辑试卷
- 第十章 角色权限和员工模块开发
- 10.1 店铺设置页面
- 10.2 网校员工管理 (一)
- 10.3 网校员工管理 (二)
- 10.4 网校角色管理
- 10.5 我的网校管理 (一)
- 10.6 我的网校管理 (二)
- 第十一章 前后端交互实现(对接真是api接口)
- 11.1 登录功能交互实现(1)
- 11.2 登录功能交互实现(2)
- 11.3 注册功能交互实现
- 第十二章 项目部署上线
