vue3 vant3推广活动项目-实现验证码登录功能

发布于:2022-11-27 ⋅ 阅读:(481) ⋅ 点赞:(0)

vue3.0活动推广项目:测一测船舶价值

技术选型:Vue3Vant3移动端ui框架

推广活动功能需求:

  • 用户使用验证码登录,登录成功之后跳转船值计算页;
  • 填写船名、吨位等信息利用计算公式测一测船舶价值,获取船舶价值计算结果;
  • 实现船值价值排行榜
  • 实现船值计算结果可生成图片长按保存到手机相册、生成二维码直接访问活动功能;

功能介绍:

1.vant3配置手机端适配,采用Rem 布局适配,官网有文档可查看

需要使用 rem 单位进行适配,推荐使用以下两个工具:

2.微信浏览器访问页面,实现使用验证码登录

  • 登录成功之后,会使用cookie存储信息,采用插件js-cookie保存实现,这里会判断用户是否是第二次或者当前信息是否过期,如果过期获取再次访问则重新登录,会跳过船值计算页,直接跳转到船值结果页。

3.船值计算页

  • 通过输入自己名下船名、吨位、生产年月、船舶类型信息通过公式计算得出船值价值

4.船值结果页

  • 船值价值排行榜
  • 船值计算结果可生成图片长按保存到手机相册、生成二维码直接访问活动功能

实现效果预览

 代码实现:验证码登录功能

 注意事项:

v-throttle自定义指令,自定义延迟事件,起到按钮多次、连续点击防抖作用,当前登录、获取验证码按钮已添加自定义指令

1.页面结构 

<template>
  <div class="loginContent">
      <img src="../assets/logo.png" class="logo"/>
      <img src="../assets/ceyice.png" class="ceyice"/>
      <van-form class="vanform">
        <van-cell-group class="formItem" :border="false" >
          <van-field type="number" autocomplete="off" v-model.trim="logonForm.loginPhone" clearable placeholder="请输入手机号" class="addbg">
            <template #left-icon>
              <img :src="loginPhoneIcon" class="loginPhoneIcon">
            </template>
          </van-field>
        </van-cell-group>
        <van-cell-group class="formItem mt25" :border="false">
          <van-field type="number" autocomplete="off" v-model.trim="logonForm.loginCode" maxlength="6" clearable placeholder="请输入验证码" class="addbg">
            <template #left-icon>
              <img :src="loginCodeIcon" class="loginCodeIcon">
            </template>
          </van-field>
          <!-- <div @click="sendCode" class="codeBtn" v-throttle>{{ buttonText }}</div> -->
          <van-button type="info" @click="sendCode" color="#024EE0" :disabled="isDisabled" class="codeBtn" v-throttle>{{ buttonText }}</van-button>
        </van-cell-group>
        <div style="margin: 30px 0 0px">
          <van-button type="primary" color="#3EA3FF" class="sub-btn" block @click="submitApply">登录</van-button>
        </div>
      </van-form>
  </div>
</template>

2.页面样式

less预编译语言

<style lang="less" scoped>
.loginContent{
  width: 100%;
  height: 100%;
  background: url("../assets/bg3.jpg") no-repeat;
  background-size:100%;
  box-sizing: border-box;
  .logo{
    display: block;
    width: 213px;
    height: 73px;
    margin:0 auto;
    padding-top:30px;
  }
  .ceyice{
    display: block;
    width: 642px;
    height: 256px;
    margin:0 auto;
    margin-top:50px;
  }
}
.vanform{
  width: 80%;
  margin:30px auto 0;
  padding:20px;
  border: 2px solid #6283ff;
  border-radius: 4px;
  background: #13115C;
}
.addbg{
  height: 96px;
  background: #2B3591;
  border-radius: 10px;
  border: 1px #6283ff solid;
}
.van-cell:after{
  border:0;
}
.formItem {
  position: relative;
  background: none;
}
.codeBtn {
  position: absolute;
  top: 4px;
  right: 100px;
  border-radius:10px;
  z-index: 100;
  font-size: 28px;
  font-weight: 600;
  color: #3EA3FF !important;
  background: none !important;
  border:0;
}
.sub-btn{
  height:96px;
  border-radius: 10px;
  font-size: 34px;
}
</style>
<style>
  .van-field__control{
    color:#fff;
  }
</style>

3.vue3.0模块引入

<script setup>
    import Cookies from 'js-cookie'
    import { Toast } from 'vant'//弹窗
    import { ref, reactive ,onMounted,onUnmounted} from "vue"
    import {useStore} from 'vuex'
    const store = useStore()
    import { useRouter } from "vue-router"
    import {
        login,//登录接口
        smsCode,//获取验证码接口
        checkUser//检查用户是否注册计算过船舶价值
    } from "../api/userMG"
    const $router = useRouter();
    const loginCodeIcon = ref(require("../assets/loginCode.png"))
    const loginPhoneIcon = ref(require("../assets/loginPhone.png"))
    // 定义表单的数据
    const logonForm = reactive({
        loginPhone: "",
        loginCode: ""
    })

    ..........
    .........
    .........
</script>

4.获取验证码功能

手机号正则验证;验证码接口调用smsCode;

const buttonText = ref("获取验证码");
const isDisabled = ref(false);
const times = ref(60)
const timer = ref(null)
const flag = ref(true)
// 获取验证码
const sendCode = () =>{
  // 验证手机号
  let reg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
  if(logonForm.loginPhone==""){
    Toast("手机号不能为空");
    return;
  }else if (!reg.test(logonForm.loginPhone)) {
    Toast("手机号格式不正确");
    return;
  }else{
    let params = {
      phone: logonForm.loginPhone
    };
    smsCode(params).then(res => {
      // console.log(res, "发送验证码请求接口");
      if (res.code == 200) {
        // 成功的弹框
        Toast.success({
          message: "验证码发送成功,请注意查收,5分钟之内有效",
          forbidClick:true,
          onClose: () => {
            buttonText.value = "已发送至手机";
            isDisabled.value = true;
            let time = times.value;
            // 定时器获取剩余时间
            if (flag.value) {
              flag.value = false;
              timer.value = setInterval(() => {
                time--;
                buttonText.value = "剩余" + time + " 秒";
                if (time === 0) {
                  clearInterval(timer.value);
                  timer.value = null;
                  buttonText.value = "重新获取";
                  isDisabled.value = false;
                  times.value = 60;
                  flag.value = true;
                }
              }, 1000);
            }
          }
        });
      } else {
        Toast("获取验证码超过次数,一小时10次,一天20次");
      }
    });
  }

}

5.登录功能

js-cookie存储信息:

//保存帐号到cookie,有效期1天

Cookies.set('phone', logonForm.loginPhone, { expires: 1 });

const submitApply = () =>{
  // 验证手机号
  let reg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
  if(logonForm.loginPhone==""){
    Toast("手机号不能为空");
    return;
  }else if (!reg.test(logonForm.loginPhone)) {
    Toast("手机号格式不正确");
    return;
  }else if(logonForm.loginCode==""){
    Toast("验证码不能为空");
    return;
  }else{

    // 登录
    store.commit('showLoading');//显示loading
    let params = {
      code:logonForm.loginCode,
      phone:logonForm.loginPhone
    }
    console.log(params,"登录")
    login(params).then(res=>{
      if(res.code == 200){
        clearInterval(timer.value);
        timer.value = null;

        //保存帐号到cookie,有效期1天
        Cookies.set('phone', logonForm.loginPhone, { expires: 1 });

        store.commit('hideLoading');//隐藏loading
        Toast({
          message:"登录成功",
          forbidClick:true,
          onClose:()=>{
            checkUser({phone:logonForm.loginPhone}).then(res=>{
              if(res.code == 200){
                if(res.data){
                  // 已注册手机号
                  $router.push({path:"/ship",query:{phone:logonForm.loginPhone}})
                }else{
                  // 未注册
                  $router.push({path: '/home',query:{phone:logonForm.loginPhone}});
                }
              }
            })

          }
        });
        
      }else{
        store.commit('hideLoading');//隐藏loading
        Toast(res.msg);
      }
    }).catch(()=>{
      store.commit('hideLoading');//隐藏loading
      Toast("请求错误");
    })
    
  }
  
}

6.页面加载完成onMounted

Cookies.get("phone")  获取cookie

这里需要判断cookie是否存在phone字段设置的时间不过期,并且当前用户是否参与活动,如果参与过则直接跳转船值结果页

onMounted(() => {
  console.log(Cookies.get("phone"))
  // 如果设置的时间过期,重新登录
  // console.log($router.currentRoute.value.path)
  // 用户活动参与校验
  if(Cookies.get("phone")){
    checkUser({phone:Cookies.get("phone")}).then(res=>{
      if(res.code == 200){
        console.log(res)
        if(res.data){
          $router.push({path:"/ship",query:{phone:Cookies.get("phone")}})
        }
      }
    })
  }

})

7.页面卸载

初始化值

onUnmounted(()=>{
    flag.value = true;
    buttonText.value = "发送验证码";
    isDisabled.value = false;
    times.value = 60;
    clearInterval(timer.value);
    timer.value = null;
})

⭐️⭐️⭐️  作者:船长在船上
🚩🚩🚩  主页:来访地址船长在船上的博客
🔨🔨🔨  简介:CSDN前端领域优质创作者,资深前端开发工程师,专注web前端领域开发,在CSDN分享工作中遇到的问题以及问题解决方法和对项目开发的实际案例总结以及新技术的认识。

 👉👉👉  欢迎来访船长在船上的博客,文章持续更新;项目功能持续迭代,项目开发测试完成会把完整代码上传码云,请及时收藏关注,方便查看。 发文不易,点赞 收藏 评论 关注一下!   

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到