提交 73a25e8e authored 作者: 王鹏飞's avatar 王鹏飞

init

上级 7663cce5
.github
.DS_Store
.browserslistrc
.babelrc
.editorconfig
.eslintrc.js
.eslintignore
.prettierrc
.gitignore
examples/
public/
src/
node_modules
babel.config.js
vue.config.js
npm-debug.log
package-lock.json
yarn.json
\ No newline at end of file
# Changelog
### 0.1.2(2019-12-24)
- 初始化
# vue-login # vue-passport
## 安装
## Project setup
``` ```
yarn install npm install @ezijing/vue-passport --save
``` ```
### Compiles and hot-reloads for development
``` ```
yarn serve yarn add @ezijing/vue-passport --save
``` ```
### Compiles and minifies for production ## 使用
### 全局使用
``` ```
yarn build import VueForm from 'vue-passport'
Vue.use(VueForm)
``` ```
### Lints and fixes files ### 组件中使用
```javascript
<template>
<vue-passport :options="options" @ready="onReady" />
</template>
<script>
import VueForm from 'vue-passport'
export default {
components: { VueForm },
data() {
return {
formModel: {
name: ''
},
formItems: [
{
type: 'input',
model: 'name',
placeholder: '请输入昵称'
}
]
}
}
}
</script>
``` ```
yarn lint
## 属性
```javascript
options: {
// 注册
register: {
url: '',
headers: {},
data: {},
onSuccess: function() {},
onError: function() {}
},
// 登录
login: {
account: {
url: '',
headers: {},
data: {},
onSuccess: function() {},
onError: function() {}
},
phone: {
url: '',
headers: {},
data: {},
onSuccess: function() {},
onError: function() {}
}
},
// 找回密码
password: {
url: '',
headers: {},
data: {},
onSuccess: function() {},
onError: function() {}
}
}
``` ```
### Customize configuration ## 方法
See [Configuration Reference](https://cli.vuejs.org/config/).
| 事件名 | 说明 | 返回值 |
| ------------------ | ---------------- | -------------------------- |
| `register` | 显示注册界面 | |
| `login` | 显示登录界面 | |
| `password` | 显示找回密码界面 | |
| `logout` | 退出登录 | |
| `checkLoginStatus` | 检测登录状态 | function(isLogin, user) {} |
## 事件
| 事件名 | 返回值 | 说明 |
| ------- | -------------------------- | ---------- |
| `ready` | function(isLogin, user) {} | 组件初始化 |
<template> <template>
<div id="app"> <div id="app">
<vue-login></vue-login> <el-button @click="register">注册</el-button>
<el-button @click="login">登录</el-button>
<el-button @click="logout">登出</el-button>
<el-button @click="password">找回密码</el-button>
<el-button @click="checkLoginStatus">检测登录状态</el-button>
<vue-login ref="passport" :options="options" @ready="onReady"></vue-login>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: 'app', name: 'app',
components: {} components: {},
data() {
return {
options: {
register: {
url: ''
},
login: {
account: {
data: { service: 'uwla.ezijing.com' }
},
phone: {
data: { service: 'uwla.ezijing.com' }
}
},
password: {
data: { service: 'uwla.ezijing.com' }
}
}
}
},
computed: {
passport() {
return this.$refs['passport']
}
},
methods: {
register() {
this.passport.register()
},
login() {
this.passport.login()
},
logout() {
this.passport.logout()
},
password() {
this.passport.password()
},
checkLoginStatus() {
this.passport.checkLoginStatus((flag, user) => {
console.log(flag, user)
})
},
onReady(isLogin, user) {
console.log(isLogin, user)
if (isLogin) {
console.log(user)
}
}
}
} }
</script> </script>
<style lang="scss">
* {
margin: 0;
padding: 0;
}
</style>
\ No newline at end of file
{ {
"name": "vue-login", "name": "@ezijing/vue-passport",
"version": "0.1.0", "version": "0.1.0",
"private": true, "description": "基于Vue Element-UI的登录注册",
"main": "dist/vue-form.umd.min.js",
"keywords": [
"element-ui",
"vue",
"vue-passport"
],
"private": false,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "lint": "vue-cli-service lint",
"lint": "vue-cli-service lint" "build": "vue-cli-service build --target lib --name vue-form ./src/index.js"
}, },
"files": [
"dist/",
"package.json",
"README.md"
],
"dependencies": { "dependencies": {
"@babel/preset-env": "^7.7.7", "axios": "^0.19.0",
"@ezijing/vue-form": "^0.1.5",
"core-js": "^3.4.3",
"element-ui": "^2.13.0", "element-ui": "^2.13.0",
"vue": "^2.6.10" "md5": "^2.2.1"
}, },
"devDependencies": { "devDependencies": {
"core-js": "^3.4.3",
"vue": "^2.6.10",
"@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-eslint": "^4.1.0", "@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-service": "^4.1.0", "@vue/cli-service": "^4.1.0",
......
<template> <template>
<div class="ezijing-component-wrapper"> <el-dialog class="ezijing-dialog" width="420px" :visible.sync="dialogVisible" :show-close="false">
<el-dialog <components
class="ezijing-dialog" :is="activeComponent"
:visible.sync="dialogVisible" v-bind="componentProps"
:show-close="false" @login="login"
:close-on-click-modal="false" @register="register"
> @password="password"
<components :is="activeComponent" @onLogin="login" @onRegister="register"></components> @success="dialogVisible = false"
</el-dialog> ></components>
</div> </el-dialog>
</template> </template>
<script> <script>
import Login from './Login' import axios from '@/utils/axios'
import Register from './Register' import Register from './Register'
import Login from './Login'
import Password from './Password'
import * as defaultProps from '@/assets/props'
export default { export default {
name: 'VueLogin', name: 'VueLogin',
components: { Login, Register }, components: { Register, Login, Password },
props: {
options: {
type: Object,
default() {
return {}
}
}
},
data() { data() {
return { return {
dialogVisible: true, dialogVisible: false,
openType: 1 openType: 1
} }
}, },
computed: { computed: {
activeComponent() { activeComponent() {
return this.openType ? 'login' : 'register' const data = {
0: 'register',
1: 'login',
2: 'password'
}
return data[this.openType] || 'login'
},
componentProps() {
const { register, login, password } = defaultProps
let result = null
if (this.openType === 0) {
result = Object.assign({}, register, this.options.register)
}
if (this.openType === 1) {
result = {
account: Object.assign(
{},
login.account,
this.options.login ? this.options.login.account : {}
),
phone: Object.assign(
{},
login.phone,
this.options.login ? this.options.login.phone : {}
)
}
}
if (this.openType === 2) {
result = Object.assign({}, password, this.options.password)
}
return result
} }
}, },
methods: { methods: {
// 注册
register() {
this.openType = 0
this.dialogVisible = true
},
// 登录
login() { login() {
this.openType = 1 this.openType = 1
this.dialogVisible = true
}, },
register() { // 找回密码
this.openType = 0 password() {
this.openType = 2
this.dialogVisible = true
}, },
async logout() {} // 登出
logout() {
const options = Object.assign(
{},
defaultProps.logout,
this.options.logout
)
this.handleRequest(options)
},
// 检测登录状态
checkLoginStatus(callback) {
this.getUser()
.then(response => {
callback && callback(true, response.data)
})
.catch(() => {
callback && callback(false)
})
},
// 获取用户信息
getUser() {
const options = Object.assign({}, defaultProps.user, this.options.user)
return this.handleRequest(options)
},
// 接口请求
handleRequest(options) {
const { url, headers, data = {}, onSuccess, onError } = options
return axios
.post(url, data, { headers })
.then(response => {
onSuccess && onSuccess(response.data)
return Promise.resolve(response)
})
.catch(error => {
if (error.response) {
onError && onError(error.response.data)
}
return Promise.reject(error)
})
},
ready() {
this.getUser()
.then(response => {
this.$emit('ready', true, response.data)
})
.catch(() => {
this.$emit('ready', false)
})
}
},
beforeMount() {
this.ready()
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.ezijing-component-wrapper { .ezijing-component-wrapper {
max-width: 480px; max-width: 420px;
margin: 0 auto; margin: 0 auto;
background-color: #fff; background-color: #fff;
} }
.ezijing-dialog { .ezijing-dialog {
::v-deep.el-dialog__header { .el-dialog__header {
display: none; display: none;
} }
::v-deep.el-dialog__body { .el-dialog__body {
padding: 0; padding: 0;
} }
} }
.ezj-title {
margin-bottom: 10px;
font-size: 20px;
text-align: center;
}
.ezj-form {
padding: 50px 40px 30px;
.submit-button {
width: 100%;
display: block;
margin-bottom: 10px;
}
}
</style> </style>
\ No newline at end of file
...@@ -13,13 +13,19 @@ ...@@ -13,13 +13,19 @@
</ul> </ul>
</div> </div>
<div class="ezj-login-bd"> <div class="ezj-login-bd">
<component :is="currentComponent"></component> <div class="ezj-form">
<el-button>登录</el-button> <template v-if="loginType === 0">
<el-checkbox v-model="isRemember">记住我</el-checkbox> <account-login v-bind="account" v-on="$listeners" ref="loginForm"></account-login>
<p> </template>
没有账号? <template v-else>
<el-button type="text" @click="$emit('onRegister')">立即注册</el-button> <phone-login v-bind="phone" v-on="$listeners" ref="loginForm"></phone-login>
</p> </template>
<el-checkbox v-model="isRemember">记住我</el-checkbox>
<p>
没有账号?
<el-button type="text" @click="$emit('register')">立即注册</el-button>
</p>
</div>
</div> </div>
<div class="ezj-login-ft"> <div class="ezj-login-ft">
<p>其他登录方式</p> <p>其他登录方式</p>
...@@ -34,7 +40,20 @@ import PhoneLogin from '@/components/PhoneLogin' ...@@ -34,7 +40,20 @@ import PhoneLogin from '@/components/PhoneLogin'
export default { export default {
name: 'ezj-login', name: 'ezj-login',
components: { AccountLogin, PhoneLogin }, components: { AccountLogin, PhoneLogin },
props: {}, props: {
account: {
type: Object,
default() {
return {}
}
},
phone: {
type: Object,
default() {
return {}
}
}
},
data() { data() {
return { return {
isRemember: false, isRemember: false,
...@@ -48,14 +67,13 @@ export default { ...@@ -48,14 +67,13 @@ export default {
}, },
methods: { methods: {
handleChangeLogin(loginType) { handleChangeLogin(loginType) {
console.log(loginType)
this.loginType = loginType this.loginType = loginType
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.ezj-login-hd { .ezj-login-hd {
border-bottom: 1px solid #f1f1f1; border-bottom: 1px solid #f1f1f1;
} }
...@@ -81,9 +99,6 @@ export default { ...@@ -81,9 +99,6 @@ export default {
text-decoration: underline; text-decoration: underline;
} }
} }
.ezj-login-bd {
padding: 50px 0;
}
.ezj-login-ft { .ezj-login-ft {
border-top: 1px solid #d8dce6; border-top: 1px solid #d8dce6;
......
<template>
<div class="ezj-password">
<div class="ezj-form">
<h1 class="ezj-title">找回密码</h1>
<el-form ref="form" :model="ruleForm" :rules="rules">
<el-form-item prop="contact" :error="contactError">
<el-input v-model="ruleForm.contact" placeholder="请输入手机号">
<i slot="prefix" class="el-input__icon el-icon-mobile-phone"></i>
</el-input>
</el-form-item>
<el-form-item prop="code" :error="codeError">
<el-input v-model="ruleForm.code" placeholder="请输入验证码">
<i slot="prefix" class="el-input__icon el-icon-lock"></i>
<template slot="append">
<countdown-button @click.native="handleSendCode" ref="countdown"></countdown-button>
</template>
</el-input>
</el-form-item>
<el-form-item prop="new_password" :error="passwordError">
<el-input type="password" v-model="ruleForm.new_password" placeholder="请输入密码">
<i slot="prefix" class="el-input__icon el-icon-lock"></i>
</el-input>
</el-form-item>
<el-form-item prop="primary_password">
<el-input type="password" v-model="ruleForm.primary_password" placeholder="请输入确认密码">
<i slot="prefix" class="el-input__icon el-icon-lock"></i>
</el-input>
</el-form-item>
<el-button type="primary" class="submit-button" @click="handleResetPassword">找回密码</el-button>
<p>
<el-button type="text" @click="$emit('login')">返回登录</el-button>
</p>
</el-form>
</div>
</div>
</template>
<script>
import axios from '@/utils/axios'
import CountdownButton from '@/components/CountdownButton'
export default {
name: 'Password',
components: { CountdownButton },
props: {
url: String,
codeUrl: String,
headers: Object,
data: Object,
beforeLogin: Function,
onSuccess: Function,
onError: Function
},
data() {
const validatePass = (rule, value, callback) => {
if (value !== this.ruleForm.new_password) {
callback(new Error('两次输入密码不一致'))
} else {
callback()
}
}
return {
ruleForm: {
contact: '',
code: '',
new_password: '',
primary_password: ''
},
contactError: '',
codeError: '',
passwordError: '',
rules: {
contact: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
new_password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
],
primary_password: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ validator: validatePass, trigger: 'blur' }
]
}
}
},
computed: {
form() {
return this.$refs['form']
}
},
methods: {
// 提交
handleResetPassword() {
this.contactError = ''
this.codeError = ''
this.passwordError = ''
this.form.validate().then(() => {
this.handleResetPasswordRequest()
})
},
// 发送验证码
handleSendCode() {
this.contactError = ''
this.form.validateField('contact', response => {
if (!response) {
// 开始倒计时
this.$refs['countdown'].start()
this.handleCodeRequest()
}
})
},
// 验证码
handleCodeRequest() {
axios
.post(
this.codeUrl,
Object.assign(
{},
{ contact: this.ruleForm.contact, source_type: 3 },
this.data
),
{ headers: this.headers }
)
.then(() => {
this.$message({ type: 'success', message: '验证码发送成功' })
})
.catch(error => {
// 停止计时
this.$refs['countdown'].stop()
error.response && this.handleError(error.response.data)
})
},
// 重置密码
handleResetPasswordRequest() {
axios
.post(this.url, Object.assign({}, this.ruleForm, this.data), {
headers: this.headers
})
.then(response => {
this.onSuccess && this.onSuccess(response.data)
this.$emit('success', response.data)
})
.catch(error => {
error.response && this.handleError(error.response.data)
})
},
// 错误处理
handleError(data) {
const { code, message } = data
if (code === 80103) {
this.contactError = message
}
if (code === 80110) {
this.codeError = message
}
if (code === 80102) {
this.passwordError = message
}
this.onError && this.onError(data)
this.$emit('error', data)
}
}
}
</script>Í
\ No newline at end of file
<template> <template>
<div class="register"> <div class="ezj-register">
<el-form ref="form" :model="form"> <div class="ezj-form">
<el-form-item> <h1 class="ezj-title">账号注册</h1>
<el-input <el-form ref="form" :model="form">
v-model="form.account" <el-form-item>
placeholder="2-30个字符,支持中英文、数字" <el-input
minlength="2" v-model="form.account"
maxlength="30" placeholder="2-30个字符,支持中英文、数字"
> minlength="2"
<i slot="prefix" class="input-prefix">昵称</i> maxlength="30"
</el-input> >
</el-form-item> <i slot="prefix" class="input-prefix">昵称</i>
<el-form-item> </el-input>
<el-input </el-form-item>
type="password" <el-form-item>
v-model="form.password" <el-input
placeholder="6-20个字符,只能数字、字母、标点符号" type="password"
minlength="6" v-model="form.password"
maxlength="20" placeholder="6-20个字符,只能数字、字母、标点符号"
> minlength="6"
<i slot="prefix" class="input-prefix">密码</i> maxlength="20"
</el-input> >
</el-form-item> <i slot="prefix" class="input-prefix">密码</i>
</el-form> </el-input>
<el-button>注册</el-button> </el-form-item>
<p> </el-form>
已账号? <el-button type="primary" class="submit-button">注册</el-button>
<el-button type="text" @click="$emit('onLogin')">请登录</el-button> <p>
</p> 已有账号?
<el-button type="text" @click="$emit('login')">去登录</el-button>
</p>
</div>
</div> </div>
</template> </template>
...@@ -43,13 +46,19 @@ export default { ...@@ -43,13 +46,19 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.register { .ezj-register {
::v-deep.el-input--prefix .el-input__inner { .el-input--prefix .el-input__inner {
padding-left: 40px; padding-left: 40px;
} }
.input-prefix { .input-prefix {
font-style: normal; font-style: normal;
} }
.submit-button {
width: 100%;
display: block;
margin-bottom: 10px;
}
} }
</style> </style>
\ No newline at end of file
export const register = {
url: ''
}
export const login = {
account: {
url: '/api/user_center/login',
data: { service: 'sofia.ezijing.com' }
},
phone: {
url: '/api/user_center/code_login',
codeUrl: '/api/user_center/send_login_code',
data: { service: 'sofia.ezijing.com' }
}
}
export const password = {
url: '/api/user_center/reset_password',
codeUrl: '/api/user_center/send_reset_password_code',
data: { service: 'sofia.ezijing.com' }
}
export const logout = {
url: '/api/user_center/logout'
}
export const user = {
url: '/api/user_center/get_user_info'
}
<template> <template>
<div class="account-login"> <div class="account-login">
<el-form ref="form" :model="ruleForm" :rules="rules"> <el-form ref="form" :model="ruleForm" :rules="rules">
<el-form-item> <el-form-item prop="login_name" :error="nameError">
<el-input v-model="ruleForm.login_name" placeholder="请输入邮箱或用户名"> <el-input v-model="ruleForm.login_name" placeholder="请输入邮箱或用户名">
<i slot="prefix" class="el-input__icon el-icon-mobile-phone"></i> <i slot="prefix" class="el-input__icon el-icon-mobile-phone"></i>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item prop="password" :error="passwordError">
<el-input type="password" v-model="ruleForm.password" placeholder="请输入密码"> <el-input
type="password"
v-model="ruleForm.password"
placeholder="请输入密码"
@keyup.enter.native="handleLogin"
>
<i slot="prefix" class="el-input__icon el-icon-lock"></i> <i slot="prefix" class="el-input__icon el-icon-lock"></i>
</el-input> </el-input>
<p class="forget_password" @click="$emit('password')">忘记密码?</p>
</el-form-item> </el-form-item>
<el-button type="primary" class="submit-button" @click="handleLogin">登录</el-button>
</el-form> </el-form>
</div> </div>
</template> </template>
<script> <script>
import axios from '@/utils/axios'
import md5 from 'md5'
export default { export default {
name: 'AccountLogin', name: 'AccountLogin',
props: {
url: String,
headers: Object,
data: Object,
beforeLogin: Function,
onSuccess: Function,
onError: Function
},
data() { data() {
return { return {
ruleForm: { ruleForm: {
login_name: '', login_name: '',
password: '' password: ''
}, },
nameError: '',
passwordError: '',
rules: { rules: {
login_name: [ login_name: [
{ required: true, message: '请输入邮箱或用户名', trigger: 'blur' } { required: true, message: '请输入邮箱或用户名', trigger: 'blur' }
...@@ -38,9 +57,61 @@ export default { ...@@ -38,9 +57,61 @@ export default {
} }
}, },
methods: { methods: {
validate(...arg) { // 提交
return this.form.validate(arg) handleLogin() {
this.nameError = ''
this.passwordError = ''
this.form.validate().then(() => {
this.handleLoginRequest()
})
},
// 登录
handleLoginRequest() {
let data = Object.assign({}, this.ruleForm, this.data)
data.password = md5(
'uokoaduw' +
data.password
.split('')
.reverse()
.join('') +
'auhgniq'
)
axios
.post(this.url, data, {
headers: this.headers
})
.then(response => {
this.onSuccess && this.onSuccess(response.data)
this.$emit('success', response.data)
})
.catch(error => {
error.response && this.handleError(error.response.data)
})
},
// 错误处理
handleError(data) {
const { code, message } = data
if (code === 80111) {
this.nameError = message
}
if (code === 80113) {
this.passwordError = message
}
this.onError && this.onError(data)
this.$emit('error', data)
} }
} }
} }
</script>Í </script>
\ No newline at end of file <style lang="scss">
.forget_password {
position: absolute;
right: 0;
line-height: 30px;
white-space: nowrap;
cursor: pointer;
}
.account-login .submit-button {
margin-top: 42px;
}
</style>
\ No newline at end of file
<template> <template>
<el-button :disabled="currentDisabled" @click="start">{{curretnValue}}</el-button> <el-button :disabled="currentDisabled" :loading="loading">{{curretnValue}}</el-button>
</template> </template>
...@@ -16,13 +16,16 @@ export default { ...@@ -16,13 +16,16 @@ export default {
return { return {
currentDisabled: false, currentDisabled: false,
currentSeconds: 0, currentSeconds: 0,
loading: false,
timer: null timer: null
} }
}, },
computed: { computed: {
curretnValue() { curretnValue() {
let longTime = this.seconds - this.currentSeconds let longTime = this.seconds - this.currentSeconds
return longTime < this.seconds ? `${longTime} S` : this.defaultValue return longTime < this.seconds
? `${longTime}S后重发`
: this.defaultValue
} }
}, },
methods: { methods: {
...@@ -36,6 +39,7 @@ export default { ...@@ -36,6 +39,7 @@ export default {
}, this.step) }, this.step)
}, },
start() { start() {
this.loading = false
this.currentDisabled = true this.currentDisabled = true
this.genTimer() this.genTimer()
}, },
......
<template> <template>
<div class="phone-login"> <div class="phone-login">
<el-form ref="form" :model="ruleForm" :rules="rules"> <el-form ref="form" :model="ruleForm" :rules="rules">
<el-form-item> <el-form-item prop="mobile" :error="mobileError">
<el-input v-model="ruleForm.login_name" placeholder="请输入手机号"> <el-input v-model="ruleForm.mobile" placeholder="请输入手机号">
<i slot="prefix" class="el-input__icon el-icon-mobile-phone"></i> <i slot="prefix" class="el-input__icon el-icon-mobile-phone"></i>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item prop="code" :error="codeError">
<el-input v-model="ruleForm.password" placeholder="请输入验证码"> <el-input v-model="ruleForm.code" placeholder="请输入验证码">
<i slot="prefix" class="el-input__icon el-icon-lock"></i> <i slot="prefix" class="el-input__icon el-icon-lock"></i>
<template slot="append"> <template slot="append">
<countdown-button></countdown-button> <countdown-button @click.native="handleSendCode" ref="countdown"></countdown-button>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item>
<el-button type="primary" class="submit-button" @click="handleLogin">登录</el-button>
</el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<script> <script>
import CountdownButton from './CountdownButton' import axios from '@/utils/axios'
import CountdownButton from '@/components/CountdownButton'
export default { export default {
name: 'PhoneLogin', name: 'PhoneLogin',
components: { CountdownButton }, components: { CountdownButton },
props: {
url: String,
codeUrl: String,
headers: Object,
data: Object,
beforeLogin: Function,
onSuccess: Function,
onError: Function
},
data() { data() {
return { return {
ruleForm: { ruleForm: {
login_name: '', mobile: '',
password: '' code: ''
}, },
mobileError: '',
codeError: '',
rules: { rules: {
login_name: [ mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
{ required: true, message: '请输入手机号', trigger: 'blur' } code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
],
password: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
} }
} }
}, },
...@@ -44,8 +57,67 @@ export default { ...@@ -44,8 +57,67 @@ export default {
} }
}, },
methods: { methods: {
validate(...arg) { // 提交
return this.form.validate(arg) handleLogin() {
this.mobileError = ''
this.codeError = ''
this.form.validate().then(() => {
this.handleLoginRequest()
})
},
// 发送验证码
handleSendCode() {
this.mobileError = ''
this.form.validateField('mobile', response => {
if (!response) {
// 开始倒计时
this.$refs['countdown'].start()
this.handleCodeRequest()
}
})
},
// 验证码
handleCodeRequest() {
axios
.post(
this.codeUrl,
Object.assign({}, { mobile: this.ruleForm.mobile }, this.data),
{ headers: this.headers }
)
.then(() => {
this.$message({ type: 'success', message: '验证码发送成功' })
})
.catch(error => {
// 停止计时
this.$refs['countdown'].stop()
error.response && this.handleError(error.response.data)
})
},
// 登录
handleLoginRequest() {
axios
.post(this.url, Object.assign({}, this.ruleForm, this.data), {
headers: this.headers
})
.then(response => {
this.onSuccess && this.onSuccess(response.data)
this.$emit('success', response.data)
})
.catch(error => {
error.response && this.handleError(error.response.data)
})
},
// 错误处理
handleError(data) {
const { code, message } = data
if (code === 80209) {
this.mobileError = message
}
if (code === 80110) {
this.codeError = message
}
this.onError && this.onError(data)
this.$emit('error', data)
} }
} }
} }
......
import { Input, Checkbox, Button, Form, FormItem, Dialog } from 'element-ui' import {
Input,
Checkbox,
Button,
Form,
FormItem,
Dialog,
Message
} from 'element-ui'
import Login from './Index.vue' import Login from './Index.vue'
...@@ -11,6 +19,7 @@ Login.install = function(Vue) { ...@@ -11,6 +19,7 @@ Login.install = function(Vue) {
Vue.use(Dialog) Vue.use(Dialog)
Vue.component(Login.name, Login) Vue.component(Login.name, Login)
Vue.prototype.$message = Message
} }
export default Login export default Login
import axios from 'axios'
const instance = axios.create({
timeout: 60000,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
instance.interceptors.request.use(
function(config) {
if (
config.headers['Content-Type'] === 'application/x-www-form-urlencoded'
) {
const formData = config.data
const params = new URLSearchParams()
for (const key in formData) {
const value = formData[key]
params.append(
key,
typeof value === 'object' ? JSON.stringify(value) : value
)
}
config.data = params
}
return config
},
function(error) {
// Do something with request error
return Promise.reject(error)
}
)
export default instance
...@@ -3,5 +3,9 @@ module.exports = { ...@@ -3,5 +3,9 @@ module.exports = {
index: { index: {
entry: 'examples/main.js' entry: 'examples/main.js'
} }
},
devServer: {
host: 'dev.ezijing.com',
proxy: 'http://dev.ezijing.com:3006'
} }
} }
...@@ -621,7 +621,7 @@ ...@@ -621,7 +621,7 @@
"@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-create-regexp-features-plugin" "^7.7.4"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/preset-env@^7.7.4", "@babel/preset-env@^7.7.7": "@babel/preset-env@^7.7.4":
version "7.7.7" version "7.7.7"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.7.tgz#c294167b91e53e7e36d820e943ece8d0c7fe46ac" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.7.tgz#c294167b91e53e7e36d820e943ece8d0c7fe46ac"
integrity sha512-pCu0hrSSDVI7kCVUOdcMNQEbOPJ52E+LrQ14sN8uL2ALfSqePZQlKrOy+tM4uhEdYlCHi4imr8Zz2cZe9oSdIg== integrity sha512-pCu0hrSSDVI7kCVUOdcMNQEbOPJ52E+LrQ14sN8uL2ALfSqePZQlKrOy+tM4uhEdYlCHi4imr8Zz2cZe9oSdIg==
...@@ -727,14 +727,6 @@ ...@@ -727,14 +727,6 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@ezijing/vue-form@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@ezijing/vue-form/-/vue-form-0.1.5.tgz#7ca0a2b60141aa9032e9c175269cc4008fabb542"
integrity sha512-/uwrm+wu1bGp8IPpLX9oE+gcyqa+l0xyzo2F/h2gnbs799pJnBdzveLNQdZAlO+5EJ5y6aY3Nm4KlWWT0JxKqg==
dependencies:
axios "^0.19.0"
element-ui "^2.13.0"
"@hapi/address@2.x.x": "@hapi/address@2.x.x":
version "2.1.4" version "2.1.4"
resolved "https://registry.npm.taobao.org/@hapi/address/download/@hapi/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" resolved "https://registry.npm.taobao.org/@hapi/address/download/@hapi/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
...@@ -2009,6 +2001,11 @@ chardet@^0.7.0: ...@@ -2009,6 +2001,11 @@ chardet@^0.7.0:
resolved "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" resolved "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha1-kAlISfCTfy7twkJdDSip5fDLrZ4= integrity sha1-kAlISfCTfy7twkJdDSip5fDLrZ4=
charenc@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
check-types@^8.0.3: check-types@^8.0.3:
version "8.0.3" version "8.0.3"
resolved "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" resolved "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552"
...@@ -2481,6 +2478,11 @@ cross-spawn@^7.0.0: ...@@ -2481,6 +2478,11 @@ cross-spawn@^7.0.0:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
crypto-browserify@^3.11.0: crypto-browserify@^3.11.0:
version "3.12.0" version "3.12.0"
resolved "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" resolved "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
...@@ -4372,7 +4374,7 @@ is-binary-path@~2.1.0: ...@@ -4372,7 +4374,7 @@ is-binary-path@~2.1.0:
dependencies: dependencies:
binary-extensions "^2.0.0" binary-extensions "^2.0.0"
is-buffer@^1.1.5: is-buffer@^1.1.5, is-buffer@~1.1.1:
version "1.1.6" version "1.1.6"
resolved "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz?cache=0&sync_timestamp=1569905599495&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" resolved "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz?cache=0&sync_timestamp=1569905599495&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha1-76ouqdqg16suoTqXsritUf776L4= integrity sha1-76ouqdqg16suoTqXsritUf776L4=
...@@ -4645,6 +4647,11 @@ js-levenshtein@^1.1.3: ...@@ -4645,6 +4647,11 @@ js-levenshtein@^1.1.3:
resolved "https://registry.npm.taobao.org/js-levenshtein/download/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" resolved "https://registry.npm.taobao.org/js-levenshtein/download/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
integrity sha1-xs7ljrNVA3LfjeuF+tXOZs4B1Z0= integrity sha1-xs7ljrNVA3LfjeuF+tXOZs4B1Z0=
js-md5@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/js-md5/-/js-md5-0.7.3.tgz#b4f2fbb0b327455f598d6727e38ec272cd09c3f2"
integrity sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==
js-message@1.0.5: js-message@1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15" resolved "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15"
...@@ -4984,6 +4991,15 @@ md5.js@^1.3.4: ...@@ -4984,6 +4991,15 @@ md5.js@^1.3.4:
inherits "^2.0.1" inherits "^2.0.1"
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
md5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
dependencies:
charenc "~0.0.1"
crypt "~0.0.1"
is-buffer "~1.1.1"
mdn-data@2.0.4: mdn-data@2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.4.tgz?cache=0&sync_timestamp=1573843533881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" resolved "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.4.tgz?cache=0&sync_timestamp=1573843533881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论