1 异步发送短信
# 原来的发送短信,是同步
-前端输入手机号---》点击发送短信---》前端发送ajax请求----》到咱们后端接口---》取出手机号----》调用 腾讯发送短信---》腾讯去发短信---》发完后----》回复给我们后端发送成功---》我们后端收到发送成功---》给我们前端返回发送成功
# 把腾讯发送短信的过程,变成异步
-前端输入手机号---》点击发送短信---》前端发送ajax请求----》到咱们后端接口---》取出手机号----》开启线程,去调用腾讯短信发送(异步)---》我们后端继续往后走----》直接返回给前端,告诉前端短信已发送
-另一条发短信线程线程会去发送短信,至于是否成功,我们不管了
1.1 视图类
@action(methods=['GET'], detail=False)
def send_sms(self, request, *args, **kwargs):
mobile = request.query_params.get('mobile', None)
code = get_code() # 把code存起来,放到缓存中,目前在内存,后期换别的
cache.set('send_sms_code_%s' % mobile, code)
if mobile:
# 开启一个线程,执行发送短信
t = Thread(target=send_sms_by_mobile, args=[mobile, code])
t.start()
return APIResponse(msg='短信已发送')
raise APIException('手机号没有携带')
1.2 序列化类加入万能验证码
def _get_user(self, attrs):
# attrs 中又手机号和验证码
mobile = attrs.get('mobile')
code = attrs.get('code')
# 验证验证码是否正确
old_code = cache.get('send_sms_code_%s' % mobile)
# 如果是 debug模式,有个万能验证码,这样就不用真正发送短信了
if code == old_code or (settings.DEBUG and code == '8888'):
# 验证码正确,查user
user = User.objects.filter(mobile=mobile).first()
if user:
return user
else:
raise APIException('手机号没注册')
else:
raise APIException('验证码错误')
2 注册功能
# 前端传入的数据
{手机号,验证码,密码}
# 后端要验证数据---》序列化类
#遇到的错误
1 注册使用哪个序列化了:get_serializer_class
2 配置文件中debug必须是True,因为咱们有万能验证码---》正常流程这个不需要
3 把code,弹出来,加入用户名,你可以随机生成用户名
4 重写create(可以不重写,把密码设为加密的密码),create_user
5 如果你继承了CreateModelMixin,一定要注意,它会走序列化,所以code字段是只写的
3.1 视图类
class UserView(GenericViewSet, CreateModelMixin):
serializer_class = LoginUserSerializer
def get_serializer_class(self):
if self.action == 'sms_login':
return LoginUserSMSSerializer
elif self.action == 'register' or self.action == 'create':
return UserRegisterSerializer
else:
# return super().get_serializer_class()
return self.serializer_class
# 自己写的 访问:127.0.0.1:8000/api/v1/user/userinfo/register/ --->post请求即可
@action(methods=['POST'], detail=False)
def register(self, request, *args, **kwargs):
ser = self.get_serializer(data=request.data)
ser.is_valid(raise_exception=True)
ser.save()
# super().create(request, *args, **kwargs) # 只要这样写,又会走序列化
return APIResponse(msg='注册成功')
# 不自己写了,只要继承CreateModelMixin,访问:127.0.0.1:8000/api/v1/user/userinfo --->post请求即可
# 这个我们不用写,它有 只要post请求过来,就会执行create
# def create(self, request, *args, **kwargs):
# serializer = self.get_serializer(data=request.data) # 第一个错误 UserRegisterSerializer
# serializer.is_valid(raise_exception=True) #执行三个校验:字段自己,局部钩子,全局
# self.perform_create(serializer)
# # 序列化要调用它,只要调用serializer.data ,就会走序列化,只要走序列化,会把create返回的user对象 来使用UserRegisterSerializer类做序列化
# return APIResponse(msg='注册成功') #不走序列化了,序列类中得write_only 也就不用了
3.2 序列化类
# 注册:1 校验数据 2 保存 3 序列化用不要?存疑
class UserRegisterSerializer(serializers.ModelSerializer):
code = serializers.CharField(max_length=4, min_length=4,write_only=True)
class Meta:
model = User
fields = ['mobile', 'password', 'code'] # code 不是数据库的字段,需要重写
# 如果要限制密码强度,需要写个局部钩子
def _check_code(self, attrs):
mobile = attrs.get('mobile')
code = attrs.get('code')
old_code = cache.get('send_sms_code_%s' % mobile)
if not (code == old_code or (settings.DEBUG and code == '8888')): # 第二个错误:debug忘了设为True
raise APIException("验证码错误")
def _pre_save(self, attrs): # {mobile:122222,code:8888,password:123}
attrs.pop('code')
attrs['username'] = attrs.get('mobile') # 默认用户名就是手机号 可以随机生成用户名 随机生成有意义的名字( Faker)
def validate(self, attrs):
# 写逻辑
# 1 校验验证码是否正确
self._check_code(attrs)
# 2 入口前准备 ---》code不是数据库字段,不能入库,username是数据库字段必填,这里没有,写成默认
self._pre_save(attrs)
return attrs
def create(self, validated_data): # {mobile:122222,password:123,username:名字}
# 为什么要重写create? 因为密码人家是加密的,如果不写用的是
# User.objects.create(**validated_data) # 密码是铭文,必须重写
user = User.objects.create_user(**validated_data) # 保存成功,密码就是加密的
return user
补充
#1 为什么要写这个media才能访问
-django 默认是不允许前端直接访问项目某个文件夹的
-有个static文件夹例外,需要额外配置
-如果想让用户访问,必须配置路由,使用serve函数放开
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT})
-浏览器中访问 meida/icon/1.png--->能把settings.MEDIA_ROOT对应的文件夹下的icon/1.png返回给前端
path('lqz/<path:path>', serve, {'document_root':os.path.join(BASE_DIR, 'lqz')})
浏览器中访问 lqz/a.txt----->能把项目根路径下lqz对应的文件夹下的a.txt返回给前端
# 2 配置文件中 debug作用
-开发阶段,都是debug为True,信息显示更丰富
-你访问的路由如果不存在,会把所有能访问到的路由都显示出来
-程序出了异常,错误信息直接显示在浏览器上
-自动重启,只要改了代码,会自动重启
-上线阶段,肯定要改成False
#3 ALLOWED_HOSTS 的作用
-只有debug 为Flase时,这个必须填
-限制后端项目(django项目 )能够部署在哪个ip的机器上,写个 * 表示所有地址都可以
#4 咱们的项目中,为了知道是在调试模式还是在上线模式,所以才用的debug这个字段
-判断,如果是开发阶段,可以有个万能验证码
# 5 短信登录或注册接口
-app 只需要输入手机号和验证码,如果账号不存在,直接注册成功,并且登录成功,如果账号存在,就是登录
-前端传入:{mobiel,code}--->验证验证码是否正确---》拿着mobile去数据库查询,如果能查到,说明它注册过了,直接签发token返回----》如果查不到,没有注册过---》走注册逻辑完成注册---》再签发token,返回给前端
-这个接口,随机生成一个6位密码,以短信形式通知用户
-这个接口,密码为空,下次他用账号密码登录,不允许登录
3 前端注册页面分析
# 登录,注册,都写成组件----》在任意页面中,都能点击显示登录模态框
# 写好的组件,应该放在那个组件中----》不是页面组件(小组件)
# 点击登录按钮,把Login.vue 通过定位,占满全屏,透明度设为 0.5 ,纯黑色悲剧,覆盖在组件上
# 在Login.vue点关闭,要把Login.vue隐藏起来,父子通信之子传父,自定义事件
3.1 Header.vue
## 页面中
<span @click="go_login">登录</span>
<Login v-if="login_show" @close_login="close_login"></Login>
## data
login_show: false
### methods
go_login() {
this.login_show = true
},
close_login() {
this.login_show = false
}
3.2 Login.vue
<template>
<div class="login">
<span @click="close">X</span>
</div>
</template>
<script>
export default {
name: "Login",
methods: {
close() {
this.$emit('close_login')
}
}
}
</script>
<style scoped>
.login {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.5);
}
</style>
4 前端登录注册页面复制
4.1 Login.vue
<template>
<div class="login">
<div class="box">
<i class="el-icon-close" @click="close_login"></i>
<div class="content">
<div class="nav">
<span :class="{active: login_method === 'is_pwd'}" @click="change_login_method('is_pwd')">密码登录</span>
<span :class="{active: login_method === 'is_sms'}" @click="change_login_method('is_sms')">短信登录</span>
</div>
<el-form v-if="login_method === 'is_pwd'">
<el-input
placeholder="用户名/手机号/邮箱"
prefix-icon="el-icon-user"
v-model="username"
clearable>
</el-input>
<el-input
placeholder="密码"
prefix-icon="el-icon-key"
v-model="password"
clearable
show-password>
</el-input>
<el-button type="primary">登录</el-button>
</el-form>
<el-form v-if="login_method === 'is_sms'">
<el-input
placeholder="手机号"
prefix-icon="el-icon-phone-outline"
v-model="mobile"
clearable
@blur="check_mobile">
</el-input>
<el-input
placeholder="验证码"
prefix-icon="el-icon-chat-line-round"
v-model="sms"
clearable>
<template slot="append">
<span class="sms" @click="send_sms">{{ sms_interval }}</span>
</template>
</el-input>
<el-button type="primary">登录</el-button>
</el-form>
<div class="foot">
<span @click="go_register">立即注册</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
username: '',
password: '',
mobile: '',
sms: '',
login_method: 'is_pwd',
sms_interval: '获取验证码',
is_send: false,
}
},
methods: {
close_login() {
this.$emit('close')
},
go_register() {
this.$emit('go')
},
change_login_method(method) {
this.login_method = method;
},
check_mobile() {
if (!this.mobile) return;
if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
this.$message({
message: '手机号有误',
type: 'warning',
duration: 1000,
onClose: () => {
this.mobile = '';
}
});
return false;
}
this.is_send = true;
},
send_sms() {
if (!this.is_send) return;
this.is_send = false;
let sms_interval_time = 60;
this.sms_interval = "发送中...";
let timer = setInterval(() => {
if (sms_interval_time <= 1) {
clearInterval(timer);
this.sms_interval = "获取验证码";
this.is_send = true; // 重新回复点击发送功能的条件
} else {
sms_interval_time -= 1;
this.sms_interval = `${sms_interval_time}秒后再发`;
}
}, 1000);
}
}
}
</script>
<style scoped>
.login {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.5);
}
.box {
width: 400px;
height: 420px;
background-color: white;
border-radius: 10px;
position: relative;
top: calc(50vh - 210px);
left: calc(50vw - 200px);
}
.el-icon-close {
position: absolute;
font-weight: bold;
font-size: 20px;
top: 10px;
right: 10px;
cursor: pointer;
}
.el-icon-close:hover {
color: darkred;
}
.content {
position: absolute;
top: 40px;
width: 280px;
left: 60px;
}
.nav {
font-size: 20px;
height: 38px;
border-bottom: 2px solid darkgrey;
}
.nav > span {
margin: 0 20px 0 35px;
color: darkgrey;
user-select: none;
cursor: pointer;
padding-bottom: 10px;
border-bottom: 2px solid darkgrey;
}
.nav > span.active {
color: black;
border-bottom: 3px solid black;
padding-bottom: 9px;
}
.el-input, .el-button {
margin-top: 40px;
}
.el-button {
width: 100%;
font-size: 18px;
}
.foot > span {
float: right;
margin-top: 20px;
color: orange;
cursor: pointer;
}
.sms {
color: orange;
cursor: pointer;
display: inline-block;
width: 70px;
text-align: center;
user-select: none;
}
</style>
4.2 Register.vue
<template>
<div class="register">
<div class="box">
<i class="el-icon-close" @click="close_register"></i>
<div class="content">
<div class="nav">
<span class="active">新用户注册</span>
</div>
<el-form>
<el-input
placeholder="手机号"
prefix-icon="el-icon-phone-outline"
v-model="mobile"
clearable
@blur="check_mobile">
</el-input>
<el-input
placeholder="密码"
prefix-icon="el-icon-key"
v-model="password"
clearable
show-password>
</el-input>
<el-input
placeholder="验证码"
prefix-icon="el-icon-chat-line-round"
v-model="sms"
clearable>
<template slot="append">
<span class="sms" @click="send_sms">{{ sms_interval }}</span>
</template>
</el-input>
<el-button type="primary">注册</el-button>
</el-form>
<div class="foot">
<span @click="go_login">立即登录</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Register",
data() {
return {
mobile: '',
password: '',
sms: '',
sms_interval: '获取验证码',
is_send: false,
}
},
methods: {
close_register() {
this.$emit('close', false)
},
go_login() {
this.$emit('go')
},
check_mobile() {
if (!this.mobile) return;
if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
this.$message({
message: '手机号有误',
type: 'warning',
duration: 1000,
onClose: () => {
this.mobile = '';
}
});
return false;
}
this.is_send = true;
},
send_sms() {
if (!this.is_send) return;
this.is_send = false;
let sms_interval_time = 60;
this.sms_interval = "发送中...";
let timer = setInterval(() => {
if (sms_interval_time <= 1) {
clearInterval(timer);
this.sms_interval = "获取验证码";
this.is_send = true; // 重新回复点击发送功能的条件
} else {
sms_interval_time -= 1;
this.sms_interval = `${sms_interval_time}秒后再发`;
}
}, 1000);
}
}
}
</script>
<style scoped>
.register {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
}
.box {
width: 400px;
height: 480px;
background-color: white;
border-radius: 10px;
position: relative;
top: calc(50vh - 240px);
left: calc(50vw - 200px);
}
.el-icon-close {
position: absolute;
font-weight: bold;
font-size: 20px;
top: 10px;
right: 10px;
cursor: pointer;
}
.el-icon-close:hover {
color: darkred;
}
.content {
position: absolute;
top: 40px;
width: 280px;
left: 60px;
}
.nav {
font-size: 20px;
height: 38px;
border-bottom: 2px solid darkgrey;
}
.nav > span {
margin-left: 90px;
color: darkgrey;
user-select: none;
cursor: pointer;
padding-bottom: 10px;
border-bottom: 2px solid darkgrey;
}
.nav > span.active {
color: black;
border-bottom: 3px solid black;
padding-bottom: 9px;
}
.el-input, .el-button {
margin-top: 40px;
}
.el-button {
width: 100%;
font-size: 18px;
}
.foot > span {
float: right;
margin-top: 20px;
color: orange;
cursor: pointer;
}
.sms {
color: orange;
cursor: pointer;
display: inline-block;
width: 70px;
text-align: center;
user-select: none;
}
</style>
4.3 Header.vue
<div class="right-part">
<div>
<span @click="put_login">登录</span>
<span class="line">|</span>
<span @click="put_register">注册</span>
</div>
<Login v-if="is_login" @close="close_login" @go="put_register"/>
<Register v-if="is_register" @close="close_register" @go="put_login"/>
</div>
## data
is_login: false,
is_register: false,
# methods
put_login() {
this.is_login = true;
this.is_register = false;
},
put_register() {
this.is_login = false;
this.is_register = true;
},
close_login() {
this.is_login = false;
},
close_register() {
this.is_register = false;
}
5 前端登录功能
# 1 多方式登录的axios请求,保存cookie---》Header.vue中要写created 生命周期,取出当前登录用户--》close_login取出当前登录用户
# 2 手机号验证码登录,axios请求,保存cookie
# 3 发送短信验证码
<template>
<div class="login">
<div class="box">
<i class="el-icon-close" @click="close_login"></i>
<div class="content">
<div class="nav">
<span :class="{active: login_method === 'is_pwd'}" @click="change_login_method('is_pwd')">密码登录</span>
<span :class="{active: login_method === 'is_sms'}" @click="change_login_method('is_sms')">短信登录</span>
</div>
<el-form v-if="login_method === 'is_pwd'">
<el-input
placeholder="用户名/手机号/邮箱"
prefix-icon="el-icon-user"
v-model="username"
clearable>
</el-input>
<el-input
placeholder="密码"
prefix-icon="el-icon-key"
v-model="password"
clearable
show-password>
</el-input>
<el-button type="primary" @click="handleLogin">登录</el-button>
</el-form>
<el-form v-if="login_method === 'is_sms'">
<el-input
placeholder="手机号"
prefix-icon="el-icon-phone-outline"
v-model="mobile"
clearable
@blur="check_mobile">
</el-input>
<el-input
placeholder="验证码"
prefix-icon="el-icon-chat-line-round"
v-model="sms"
clearable>
<template slot="append">
<span class="sms" @click="send_sms">{{ sms_interval }}</span>
</template>
</el-input>
<el-button type="primary" @click="handleSmSLogin">登录</el-button>
</el-form>
<div class="foot">
<span @click="go_register">立即注册</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
username: '',
password: '',
mobile: '',
sms: '',
login_method: 'is_pwd',
sms_interval: '获取验证码',
is_send: false, // 如果是true,就是能发送验证码,是false就不能发送验证码
}
},
methods: {
close_login() {
this.$emit('close')
},
go_register() {
this.$emit('go')
},
change_login_method(method) {
this.login_method = method;
},
check_mobile() {
if (!this.mobile) return;
if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
this.$message({
message: '手机号有误',
type: 'warning',
duration: 1000,
onClose: () => {
this.mobile = '';
}
});
return false;
}
// 跟后端交互,查询该手机号是否注册过,如果注册过,才能发送
this.$axios.get(`${this.$settings.BASE_URL}user/userinfo/check_mobile/?mobile=${this.mobile}`).then(res => {
if (res.data.code != 100) {
// 提示该手机号未注册
this.$message({
message: '该手机号未注册,请先注册',
type: 'success'
});
// 把手机号清空
this.mobile = ''
} else {
this.is_send = true; // 可以发送验证码
}
})
},
// 发送手机验证码
send_sms() {
if (!this.is_send) return; // 如果是false,不能点击发送
this.is_send = false; // 点了一次,不能再点了,1 m,定时器执行完 后才能再点
let sms_interval_time = 60;
this.sms_interval = "发送中...";
let timer = setInterval(() => {
if (sms_interval_time <= 1) {
clearInterval(timer);
this.sms_interval = "获取验证码";
this.is_send = true; // 是true表示,能够点击发送验证码按钮
} else {
sms_interval_time -= 1;
this.sms_interval = `${sms_interval_time}秒后再发`;
}
}, 1000);
// 调用接口发送验证码
this.$axios.get(`${this.$settings.BASE_URL}user/userinfo/send_sms/?mobile=${this.mobile}`).then(res => {
this.$message({
message: res.data.msg,
type: 'success'
});
})
},
// 用户名密码登录
handleLogin() {
if (this.username && this.password) {
this.$axios.post(`${this.$settings.BASE_URL}user/userinfo/mul_login/`, {
username: this.username,
password: this.password
}).then(res => {
if (res.data.code == 100) {
// 登录成功 返回了token,用户名,头像--->把他们存到cookie中
this.$cookies.set('token', res.data.token, '7d')
this.$cookies.set('username', res.data.username, '7d')
this.$cookies.set('icon', res.data.icon, '7d')
// 页面关闭,子传父,调用 自定义事件close,就会触发父组件中的close_login方法
this.$emit('close')
} else {
this.$message({
message: res.data.msg,
type: 'warning'
});
}
})
} else {
this.$message({
message: '用户名或密码不能为空',
type: 'warning'
});
}
},
// 验证码登录
handleSmSLogin() {
if (this.mobile && this.sms) {
this.$axios.post(`${this.$settings.BASE_URL}user/userinfo/sms_login/`, {
mobile: this.mobile,
code: this.sms
}).then(res => {
if (res.data.code == 100) {
this.$cookies.set('token', res.data.token, '7d')
this.$cookies.set('username', res.data.username, '7d')
this.$cookies.set('icon', res.data.icon, '7d')
this.$emit('close')
} else {
this.$message({
message: res.data.msg,
type: 'warning'
});
}
})
} else {
this.$message({
message: '用户名或密码不能为空',
type: 'warning'
});
}
}
}
}
</script>
<style scoped>
.login {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.5);
}
.box {
width: 400px;
height: 420px;
background-color: white;
border-radius: 10px;
position: relative;
top: calc(50vh - 210px);
left: calc(50vw - 200px);
}
.el-icon-close {
position: absolute;
font-weight: bold;
font-size: 20px;
top: 10px;
right: 10px;
cursor: pointer;
}
.el-icon-close:hover {
color: darkred;
}
.content {
position: absolute;
top: 40px;
width: 280px;
left: 60px;
}
.nav {
font-size: 20px;
height: 38px;
border-bottom: 2px solid darkgrey;
}
.nav > span {
margin: 0 20px 0 35px;
color: darkgrey;
user-select: none;
cursor: pointer;
padding-bottom: 10px;
border-bottom: 2px solid darkgrey;
}
.nav > span.active {
color: black;
border-bottom: 3px solid black;
padding-bottom: 9px;
}
.el-input, .el-button {
margin-top: 40px;
}
.el-button {
width: 100%;
font-size: 18px;
}
.foot > span {
float: right;
margin-top: 20px;
color: orange;
cursor: pointer;
}
.sms {
color: orange;
cursor: pointer;
display: inline-block;
width: 70px;
text-align: center;
user-select: none;
}
</style>
6 前端注册功能
# 1 校验手机号是否存在的axios
-如果存在,直接跳转到登录---》小bug
# 2 发送验证码axios
# 3 注册的axios
-注册成功,跳转到登录页面
<template>
<div class="register">
<div class="box">
<i class="el-icon-close" @click="close_register"></i>
<div class="content">
<div class="nav">
<span class="active">新用户注册</span>
</div>
<el-form>
<el-input
placeholder="手机号"
prefix-icon="el-icon-phone-outline"
v-model="mobile"
clearable
@blur="check_mobile">
</el-input>
<el-input
placeholder="密码"
prefix-icon="el-icon-key"
v-model="password"
clearable
show-password>
</el-input>
<el-input
placeholder="验证码"
prefix-icon="el-icon-chat-line-round"
v-model="sms"
clearable>
<template slot="append">
<span class="sms" @click="send_sms">{{ sms_interval }}</span>
</template>
</el-input>
<el-button type="primary" @click="handleRegister">注册</el-button>
</el-form>
<div class="foot">
<span @click="go_login">立即登录</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Register",
data() {
return {
mobile: '',
password: '',
sms: '',
sms_interval: '获取验证码',
is_send: false,
}
},
methods: {
close_register() {
this.$emit('close', false)
},
go_login() {
this.$emit('go')
},
check_mobile() {
if (!this.mobile) return;
if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
this.$message({
message: '手机号有误',
type: 'warning',
duration: 1000,
onClose: () => {
this.mobile = '';
}
});
return false;
}
// 校验手机号是否能发验证码---》只有没注册过的,才能发
this.$axios.get(`${this.$settings.BASE_URL}user/userinfo/check_mobile/?mobile=${this.mobile}`).then(res => {
if (res.data.code != 100) {
// 提示该手机号未注册
this.$message({
message: '该手机号未注册,可以发送短信',
type: 'success'
});
this.is_send = true; // 可以发送验证码
} else {
// 手机号注册过了,不用注册了,直接登录即可
this.$message({
message: '该手机号已经注册过,可以直接登录',
type: 'success',
onClose: () => {
// 跳转到登录页面
this.$emit('go')
}
});
}
})
},
send_sms() {
if (!this.is_send) return;
this.is_send = false;
let sms_interval_time = 60;
this.sms_interval = "发送中...";
let timer = setInterval(() => {
if (sms_interval_time <= 1) {
clearInterval(timer);
this.sms_interval = "获取验证码";
this.is_send = true; // 重新回复点击发送功能的条件
} else {
sms_interval_time -= 1;
this.sms_interval = `${sms_interval_time}秒后再发`;
}
}, 1000);
// 调用接口发送验证码
this.$axios.get(`${this.$settings.BASE_URL}user/userinfo/send_sms/?mobile=${this.mobile}`).then(res => {
this.$message({
message: res.data.msg,
type: 'success'
});
})
},
handleRegister() {
if (this.mobile && this.sms && this.password) {
this.$axios.post(`${this.$settings.BASE_URL}user/userinfo/register/`, {
mobile: this.mobile,
code: this.sms,
password: this.password
}).then(res => {
if (res.data.code == 100) {
// 注册成功
this.$message({
message: res.data.msg,
type: 'success'
});
// 跳转到登录--->写自定义事件的名字
this.$emit('go')
}
})
} else {
this.$message({
message: '手机号,验证码,密码不能为空',
type: 'success'
});
}
}
}
}
</script>
<style scoped>
.register {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
}
.box {
width: 400px;
height: 480px;
background-color: white;
border-radius: 10px;
position: relative;
top: calc(50vh - 240px);
left: calc(50vw - 200px);
}
.el-icon-close {
position: absolute;
font-weight: bold;
font-size: 20px;
top: 10px;
right: 10px;
cursor: pointer;
}
.el-icon-close:hover {
color: darkred;
}
.content {
position: absolute;
top: 40px;
width: 280px;
left: 60px;
}
.nav {
font-size: 20px;
height: 38px;
border-bottom: 2px solid darkgrey;
}
.nav > span {
margin-left: 90px;
color: darkgrey;
user-select: none;
cursor: pointer;
padding-bottom: 10px;
border-bottom: 2px solid darkgrey;
}
.nav > span.active {
color: black;
border-bottom: 3px solid black;
padding-bottom: 9px;
}
.el-input, .el-button {
margin-top: 40px;
}
.el-button {
width: 100%;
font-size: 18px;
}
.foot > span {
float: right;
margin-top: 20px;
color: orange;
cursor: pointer;
}
.sms {
color: orange;
cursor: pointer;
display: inline-block;
width: 70px;
text-align: center;
user-select: none;
}
</style>
标签:code,mobile,media,08,sms,注册,message,data,login
From: https://www.cnblogs.com/whxx/p/17506749.html