我的 (登录页面:找回密码) 前后端一起搞

517 阅读2分钟

思路: 注意:这里的路由采用(子路由跳转)

前端:

  1. 点击找回密码 , 根据设置路由(采用了子路由方法跳转)跳转到对应的页面

  2. 校验手机号和 手机验证码 输入正确

    2.1 手机号校验:前端校验完之后 发送请求给后端验证

    2.2 验证码校验:前端校验完之后 发送请求给后端验证

  3. 发送请求给后端之后,获取到返回的内容,继续发送后端请求 :完成修改密码,路由跳转到 手机号和密码登录页面

后端:

  1. 写一个接口,接收前端传递过来的手机号, 进行数据库查询
  2. 如果找到手机号,返回信息给前端就进入对应的修改密码页面,写修改sql语句(根据电话号码 和 数据库id 修改)
  3. 如果手机号不存在 没有注册过 后端返回提示信息给前端,前端直接return false

页面一:对应代码:前后端 第一部分(就是对手机号进行 前后端校验 RetrieveIndex.vue)

image.png

页面二:开始真正的修改密码 (在另一个RetrieveBtn.vue组件进行)

image.png

一 前端 部分()

<template>
  <div class="retrieveIndex">
    <header>
      <Header>
        <template #tab></template>
        <template #middle>
          <div class="middle">找回密码</div>
        </template>
        <template #login>
          <div></div>
        </template>
      </Header>
    </header>
    <section>
      <div class="section">
        <ul>
          <li class="tels">
            <input type="tel" class="tel" placeholder="请输入手机号" v-model="tel" />
          </li>
          <li class="codes">
            <input type="tel" class="code" placeholder="请输入短信验证码" v-model="code" />
            <button class="btnCode" @click="getCode" :disabled="disableds">{{btnText}}</button>
          </li>
          <li class="retrieveIndex" @click="goRetrieveIndex">
            <button>下一步</button>
          </li>
        </ul>
      </div>
    </section>
    <Tabber></Tabber>
  </div>
</template>

<script>
import Tabber from "@/components/common/Tabbar.vue";
import Header from "@/components/my/Header.vue";
import { Toast } from "mint-ui";
// 引入封装好的 require
import http from "@/common/api/request.js";
export default {
  components: {
    Header,
    Tabber,
  },
  data() {
    return {
      // 用户输入的登录信息
      tel: "",
      disableds: false,
      code: "",
      sendCode: "",
      btnText: "获取短信验证码",
      btnTime: 6,
      rules: {
        //  手机号校验规则
        tel: {
          rule: /^1[3589]\d{9}$/,
          msg: "手机号不能为空,并以13 15 18 19开头的11位数字",
        },
        code: {
          rule: /\d{4}$/,
          msg: "验证码不能为空 并且为4位数字",
        },
      },
    };
  },

  methods: {
    // 获取短信验证码
    async getCode() {
      //前端 校验手机号
      if (!this.validate("tel")) return;
      // 向后端发送请求
      let res = await http.$axios({
        url: "/api/code",
        method: "POST",
        data: {
          tel: this.tel,
        },
      });
      console.log(res);
      this.sendCode = res.data;
      console.log(this.sendCode);
      // 开启定时器
      let time = setInterval(() => {
        // 校验通过后:让按钮不可继续点击
        this.disableds = true;
        this.btnTime--;
        this.btnText = `重新发送(${this.btnTime})`;
        if (this.btnTime <= 0) {
          clearInterval(time);
          this.btnTime = 6;
          this.btnText = "获取短信验证码";
          this.disableds = false;
        }
      }, 1000);
    },

    //   判断如果输入的短信验证码 和 后端返回的 短信验证码一致 点击下一步 进入到重新输入密码页面
    async goRetrieveIndex() {
      console.log(this.code.length);
      if (this.validate("tel")) {
        console.log(111);
        if (!this.validate("code")) return;
        console.log(222);
        // if (this.code.length > 0 && this.code == this.sendCode) {
        if (!this.code == this.sendCode) {
          return Toast("验证码不正确");
        } else {
          //   发送登录请求;
          console.log(333);
          // 发送登录请求
          await http
            .$axios({
              url: "/api/retrieve",
              method: "POST",
              data: {
                tel: this.tel,
              },
            })
            .then((res) => {
              if (!res.success) {
                Toast(res.msg);
                return;
              } else {
                //   跳转页面
                this.$router.push({
                  name: "btn",
                  query: { tel: this.tel },
                });
              }
              console.log(res);
              console.log(res.success);
            });
        }
      }
    },

    validate(key) {
      let bool = true;
      if (!this.rules[key].rule.test(this[key])) {
        Toast(this.rules[key].msg);
        bool = false;
        return false;
      }
      return bool;
    },
  },
};
</script>

<style lang="less" scoped>
.retrieveIndex {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
}
.middle {
  font-size: 0.48rem;
}
section {
  flex: 1;
  background-color: #f5f5f5;
  box-sizing: border-box;

  .section {
    margin: 0.533333rem 0.8rem;
  }
}

ul {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  width: 100%;
  li {
    width: 100%;
    margin-bottom: 0.4rem;
  }
  input {
    padding-left: 0.266667rem;
    border-radius: 0.133333rem;
    border: 0;
    outline: none;
    border: 1px solid #ccc;
    box-sizing: border-box;
  }
  .tels {
    .tel {
      width: 100%;
      height: 0.96rem;
    }
  }
  .codes {
    display: flex;
    justify-content: space-between;
    width: 100%;
    .code {
      width: 60%;
      height: 0.96rem;
      border-right: none;
      border-radius: 0.133333rem 0 0 0.133333rem;
    }
    .btnCode {
      width: 40%;
      background-color: #13acf3;
      outline: 0;
      border: none;
      border-radius: 0 0.133333rem 0.133333rem 0;
      color: #f5f5f5;
    }
  }
  .retrieveIndex {
    width: 100%;
    height: 0.96rem;
    text-align: center;

    button {
      height: 0.96rem;
      background-color: #13acf3;
      outline: 0;
      border: none;
      border-radius: 0.133333rem;
      color: #f5f5f5;
    }
  }
}
</style>

后断部分:

// 找回密码 判断手机号是否已注册,如果已注册 返回数据给前端,前端来操作跳转到重置密码页面
router.post('/api/retrieve', function (req, res, next) {
  // 前端传递过来的手机号
  let params = {
    tel: req.body.tel,
  }
  connection.query(user.queuryTel(params), function (e, r) {
    // 手机号存在
    if (r.length > 0) {
      res.send({
        code: 200,
        data: {
          success: true,
        }
      })
    } else {
      // 手机号不存在
      res.send({
        code: 0,
        data: {
          success: false,
          msg: "手机号不存在"
        }
      })
    }
  })
})

二 前端

<template>
  <div class="retrieveBtn">
    <header>
      <Header>
        <template #tab></template>
        <template #middle>
          <div class="middle">密码重置</div>
        </template>
        <template #login>
          <div></div>
        </template>
      </Header>
    </header>
    <section>
      <div class="section">
        <ul>
          <li class="tels">
            <input type="tel" class="tel" placeholder="请输入新密码" v-model="pwd" />
          </li>
          <li class="tels">
            <input type="tel" class="tel" placeholder="确认你的新密码" v-model="newPwd" />
          </li>

          <li class="retrieveBtn" @click="goRetrieveIndex">
            <button>完成</button>
          </li>
        </ul>
      </div>
    </section>
    <Tabber></Tabber>
  </div>
</template>

<script>
import Tabber from "@/components/common/Tabbar.vue";
import Header from "@/components/my/Header.vue";
import { Toast } from "mint-ui";
// 引入封装好的 require
import http from "@/common/api/request.js";
export default {
  components: {
    Header,
    Tabber,
  },
  data() {
    return {
      // 用户输入的登录信息
      pwd: "",
      newPwd: "",
      disableds: false,
      btnText: "获取短信验证码",
      btnTime: 6,
      rules: {
        //  密码校验规则
        pwd: {
          rule: /\w{6,12}$/,
          msg: "密码不能为空 长度为6-12位",
        },
        newPwd: {
          rule: /\w{6,12}$/,
          msg: "密码不能为空 长度为6-12位",
        },
      },
    };
  },

  methods: {
    //   判断如果输入的短信验证码 和 后端返回的 短信验证码一致 点击下一步 进入到重新输入密码页面
    // async goRetrieveIndex() {
    async goRetrieveIndex() {
      // 判断密码输入是否符合校验规则
      if (!this.validate("pwd") || !this.validate("newPwd")) return;
      // 判断两次输入的密码是否一致
      if (this.pwd != this.newPwd) {
        return Toast("两次输入密码不一致");
      }

      // 前端校验通过 向后端发送请求,携带手机号 和新密码 然后执行sql更新语句
      await http
        .$axios({
          url: "/api/updatePwd",
          method: "POST",
          data: {
            tel: this.$route.query.tel,
            pwd: this.pwd,
          },
        })
        .then((res) => {
          if (!res.success) {
            return Toast("密码更新失败!");
          }
          Toast(res.msg);
          this.$router.push("/userLogin");
          console.log(res);
        });
    },

    validate(key) {
      let bool = true;
      if (!this.rules[key].rule.test(this[key])) {
        Toast(this.rules[key].msg);
        bool = false;
        return false;
      }
      return bool;
    },
  },
};
</script>

<style lang="less" scoped>
.retrieveBtn {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
}
.middle {
  font-size: 0.48rem;
}
section {
  flex: 1;
  background-color: #f5f5f5;
  box-sizing: border-box;

  .section {
    margin: 0.533333rem 0.8rem;
  }
}

ul {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  width: 100%;
  li {
    width: 100%;
    margin-bottom: 0.4rem;
  }
  input {
    padding-left: 0.266667rem;
    border-radius: 0.133333rem;
    border: 0;
    outline: none;
    border: 1px solid #ccc;
    box-sizing: border-box;
  }
  .tels {
    .tel {
      width: 100%;
      height: 0.96rem;
    }
  }

  .retrieveBtn {
    width: 100%;
    height: 0.96rem;
    text-align: center;

    button {
      height: 0.96rem;
      background-color: #13acf3;
      outline: 0;
      border: none;
      border-radius: 0.133333rem;
      color: #f5f5f5;
    }
  }
}
</style>

二 后端

 // 重置密码:
router.post('/api/updatePwd', function (req, res, next) {
  // 前端传递过来的手机号
  let params = {
    tel: req.body.tel,
    pwd: req.body.pwd
  }
  // 更新操作 :先去查询这个手机号在不在,如果存在,把数据库保存的id获取下来
  connection.query(user.queuryTel(params), function (e, r) {
    let id = r[0].id
    console.log(id);
    connection.query(`update user set pwd = "${params.pwd}" where id = "${id}"`, function (e, r) {
      // console.log(r, 'ssss');
      // console.log(r, 'aaaa');
      res.send({
        code: 200,
        data: {
          success: true,
          msg: "密码更新成功"
        }
      })
    })
  })
})