vue.js project tiktok APP- eleventh: application of login and verification code

Posted by Mad_T on Tue, 08 Feb 2022 16:47:56 +0100

[warm tips]: if you want to know more about the actual combat content of this project, you can go to vue.js project tiktok APP- project planning Learn more about project planning.

[project address]
The project is managed by Git, and the final project will be released to GitHub. Interested partners can learn together to improve the project.
Project address: GitHub

Section 11: registration and verification code function

functional analysis

In order to realize the registration and login function in the app, the first question to think about is when you need to log in? Tiktok app knows that when we operate friends, news, and other functional pages, we need to log on to verify. So how do we achieve it?
Function realization steps:
1. Realization of page layout of registration, login and verification code
2. Login verification of binding related functions

Function realization

Registration page layout and button dynamic style

1. Structure

2. Page layout and style, code as follows:

<template>
  <div class="sign">
    <div class="sign-header">
      <span class="iconfont icon-guanbi" style="font-size: 20px" @click="back"></span>
      <span style="color: #6868 font size: 15px "> help</span>
    </div>
    <div class="sign-content">
      <div class="des">
        <h2>You can show yourself after logging in</h2>
        <p> Sign in and agree<a href="">Tiktok protocol</a>and<a>Privacy agreement</a></p>
      </div>
      <div class="sign-box">
        <div class="sele">
          <select class="sele-controll" v-model="telErea">
            <option value="">+86</option>
          </select>
        </div>
        <div class="inp">
          <input v-model="phone" @input="changeTel" type="tel" class="inp-controll"
                 placeholder="Please enter your mobile phone number">
        </div>
      </div>
      <div class="not-sign">
        <p>Unregistered mobile phone number will log in automatically after verification</p>
      </div>
      <div class="code-btn">
        <button :disabled="disabled" :class="[btnBg? 'active':'']" @click="getCode">Get SMS verification code</button>
      </div>
      <div class="other">
        <router-link href="" tag="a" to="/tpsign">Password login</router-link>
        <span @click="show">Login in other ways</span>
      </div>
    </div>
    <!--    <transition name="up">-->
    <div class="mask" v-if="showMask" @click="close">
        <div class="oauth">
          <ul>
            <li class="oauth-item">Today's headline login</li>
            <li class="oauth-item">QQ Sign in</li>
            <li class="oauth-item">Wechat login</li>
            <li class="oauth-item">Microblog login</li>
            <li class="oauth-item" @click="close">cancel</li>
          </ul>
        </div>
    </div>
    <!--    </transition>-->
  </div>
</template>
<style lang="less" scoped>
  .sign {
    padding: 30px;
    background-color: #fff;

    .sign-header {
      display: flex;
      justify-content: space-between;
    }

    .sign-content {
      padding: 40px 10px;
      .des{
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        margin: 60px 0;
      }
    }

    h2 {
      margin: 0;
      font-size: 24px;
      font-weight: bold;
    }

    p {
      line-height: 20px;
      color: #686868;
    }

    p a {
      color: #628DB8;
      padding: 0 5px;
    }

    .sign-box {
      display: flex;
      height: 50px;
      margin: 20px 0 0 0;
      align-items: center;
      background-color: #F9F9F9;

      .sele-controll {
        height: 36px;
        font-weight: bold;
        margin-left: 5px;
        border: none;
      }

      .inp-controll {
        height: 36px;
        background-color: #F9F9F9;
        width: 90%;
        margin-left: 10px;
      }

      input {
        caret-color: #FE2C55;
      }

      input::-webkit-input-placeholder {
        color: #686868;
      }
    }

    .not-sign {
      margin-top: 10px;
    }

    .not-sign p {
      color: #686868;
      font-size: 14px;

    }
    .code-btn{
        margin: 60px 0;
    }
    .code-btn button {
      margin: 10px 0;
      width: 100%;
      padding: 15px 0;
      border: none;
      letter-spacing: 5px;
      font-size: 15px;
    }

    .active {
      color: #ffffff;
      background-color: #FE2C55;
    }

    .other {
      display: flex;
      justify-content: space-between;
    }

    .other a {
      color: #628DB8;
    }
  }

  .mask {
    width: 100%;
    height: 100%;
    position: fixed;
    left: 0;
    top: 0;
    background-color: rgba(0, 0, 0, .4);

    .oauth {
      height: 48%;
      width: 100%;
      position: absolute;
      bottom: 0;
      border-top-left-radius: 10px;
      border-top-right-radius: 10px;
      background-color: #fff;
      text-align: center;

      .oauth-item {
        border-bottom: 1px solid #f5f5f5;
        line-height: 60px;
      }
    }
  }

</style>

3. Dynamic style
The core of realizing dynamic style in vue is to bind the target style with v-bind instruction, and then render according to different conditions. The code is as follows:
Button layout

	<div class="code-btn">
        <button :disabled="disabled" :class="[btnBg? 'active':'']" @click="getCode">Get SMS verification code</button>
    </div>

Dynamic implementation

<script>
export default {
  name: 'Register',
  data() {
    return {
      telErea: '',
      showMask: false,
      disabled: true,
      btnBg: false,// Button style default
      phone: '  ',
    };
  },
  methods: {
    getCode() {
      this.$router.push({ path: '/code' });
    },
    show() {
      this.showMask = true;
    },

    close() {
      this.showMask = false;
    },
    changeTel(e) {
      // eslint-disable-next-line no-useless-escape
      this.phone = e.target.value.replace(/\ +/g, '');
      const regTel = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
      if (regTel.test(this.phone)) {
        console.log('Echo regular expression');
        this.btnBg = true;
        this.disabled = false;
      } else {
        console.log('Regular expressions are not attached');
        this.btnBg = false;
        this.disabled = true;
      }
    },
    back() {
      this.$router.push({ path: '/index' });
    },
  },
};
</script>

[warm tip] here we use: class to define the dynamic style.

Login page layout and button dynamic style

1. Structure

2. Page layout and style, code as follows:

<template>
  <div class="sign">
    <div class="sign-header">
      <span class="iconfont icon-guanbi" style="font-size: 20px" @click="$router.back()"></span>
      <span style="color: #686868; font-size:16px;  "> help</span>
    </div>
    <div class="sign-content">
      <div class="des">
        <h2>Mobile number password login</h2>
      </div>
      <div class="sign-box">
        <div class="sele">
          <select class="sele-controll" v-model="telErea">
            <option value>+86</option>
          </select>
        </div>
        <div class="inp">
          <input
            type="tel"
            @keyup="loginAction"
            class="inp-controll"
            v-model="phone"
            @input="changePhone"
            placeholder="Please enter your mobile phone number"
          />
        </div>
      </div>
      <div class="sign-box">
        <div class="inp">
          <input
            type="tel"
            @keyup="loginAction"
            v-model="password"
            @input="changePass"
            class="inp-controll"
            placeholder="Please input a password"
          />
        </div>
      </div>
      <div class="not-sign">
        <p>
          Sign in and agree
          <a href>Tiktok protocol</a>and
          <a>Privacy agreement</a>
        </p>
      </div>
      <div class="code-btn">
        <button :disabled="disabled" :class="[btnBg? 'active':'']" @click="loginAction">Sign in</button>
      </div>
      <div class="other">
        <span>
          Forget about it?
          <a @click="resLogin">Mobile verification code login</a>
        </span>
      </div>
    </div>
    <div class="mask" v-if="showMask">
      <div class="oauth">
        <ul>
          <li class="oauth-item">Today's headline login</li>
          <li class="oauth-item">QQ Sign in</li>
          <li class="oauth-item">Wechat login</li>
          <li class="oauth-item">Microblog login</li>
          <li class="oauth-item" @click="close">cancel</li>
        </ul>
      </div>
    </div>
  </div>
</template>
<style lang="less" scoped>
.sign {
  padding: 30px;
  background-color: #fff;

  .sign-header {
    display: flex;
    justify-content: space-between;
  }

  .sign-content {
    padding: 100px 10px;
    .des{
        display: flex;
        justify-content: center;
        margin: 0 0 33px 0;
    }
    .code-btn{
        margin: 40px 0 75px 0;
    }
  }

  h2 {
    margin: 0;
    font-size: 24px;
    font-weight: bold;
  }

  p {
    line-height: 20px;
    color: #686868;
  }

  p a {
    color: #628db8;
    padding: 0 5px;
  }

  .sign-box {
    display: flex;
    height: 50px;
    margin: 20px 0 0 0;
    align-items: center;
    background-color: #f9f9f9;
    .sele-controll {
      height: 36px;
      font-weight: bold;
      margin-left: 5px;
      border: none;
    }
    .inp-controll {
      height: 36px;
      background-color: #f9f9f9;
      width: 90%;
      margin-left: 10px;
    }
    input {
      caret-color: #fe2c55;
    }
    input::-webkit-input-placeholder {
      color: #686868;
    }
  }

  .sign-box:nth-child(3) {
    margin-top: 0px;
    margin-top: 10px;
  }
  .not-sign {
    margin-top: 10px;
  }
  .not-sign p {
    color: #686868;
    font-size: 14px;
  }
  .code-btn button {
    margin: 10px 0;
    width: 100%;
    padding: 15px 0;
    border: none;
    font-size: 20px;
    letter-spacing: 5px;
    color: #ffffff;
  }

  .other {
    display: flex;
    justify-content: center;
    margin: 20px 0;
  }

  .other a {
    color: #628db8;
  }

  .active {
    color: #ffffff;
    background-color: #fe2c55;
  }

  .mask {
    width: 100%;
    height: 100%;
    position: fixed;
    left: 0;
    top: 0;
    background-color: rgba(0, 0, 0, 0.4);
    .oauth {
      height: 48%;
      width: 100%;
      position: absolute;
      bottom: 0;
      border-top-left-radius: 10px;
      border-top-right-radius: 10px;
      background-color: #fff;
      text-align: center;
      .oauth-item {
        border-bottom: 1px solid #f5f5f5;
        line-height: 63px;
      }
    }
  }
}
</style>

3. Dynamic style of button

<div class="code-btn">
   <button :disabled="disabled" :class="[btnBg? 'active':'']" @click="loginAction">Sign in</button>
</div>
<script>
export default {
  name: 'LogIn',
  data() {
    return {
      telErea: '',
      showMask: false,
      password: '',
      phone: '',
      disabled: true,
      btnBg: false,// Default button style status
    };
  },
  methods: {
    changePhone(e) {
      this.phone = e.target.value;
      const regTel = /^[1][3456789][0-9]{9}$/;
      if (!regTel.test(this.phone)) {
        console.log('Regular expressions are not attached');
        this.btnBg = false;
        this.disabled = true;
      }
    },
    changePass() {},
    loginAction() {
      // eslint-disable-next-line no-useless-escape
      const regTel = /^[1][3456789][0-9]{9}$/;
      if (this.phone === '') {
        console.log('Mobile phone number cannot be empty');
        this.disabled = true;
        this.btnBg = false;
      } else if (!regTel.test(this.phone)) {
        console.log('Please fill in the correct mobile phone number');
        this.disabled = true;
        this.btnBg = false;
      } else if (this.password === '') {
        console.log('Password cannot be empty');
        this.disabled = true;
        this.btnBg = false;
      } else {
        console.log('Request interface');
        this.disabled = false;
        this.btnBg = true;
      }
      this.$router.push({ path: '/me' });
    },
    show() {
      this.showMask = true;
    },
    close() {
      this.showMask = false;
    },
    // Mobile verification code login
    resLogin() {
      this.$router.push({ path: '/register' });
    },
  },
};
</script>

When the [style] button and the [style] button are used to update the dynamic password, enter the prompt.

Verification code page layout and button dynamic style

1. Structure

2. Page layout and style, code as follows:

<template>
  <div class="sign">
    <div class="sign-header">
      <span class="iconfont icon-back" style="font-size: 20px" @click="$router.back()"></span>
      <span style="color: #6868 "> help</span>
    </div>
    <div class="sign-content">
      <div class="des">
        <h2>Please enter the verification code</h2>
        <p>Verification code has been sent to via SMS+8615998362261</p>
      </div>
      <div class="sign-box">
        <div class="inp">
          <input
            @input="changeCode"
            type="tel"
            v-model="code "
            class="inp-controll"
            placeholder="Please enter the verification code "
          />
        </div>
        <div class="sele">{{time}}</div>
      </div>
      <div class="code-btn">
        <button :disabled="disabled" :class="[btnBg? 'active':'']" class="load-btn">
          <div v-if="loading" class="loads" @click="login"></div>Sign in
        </button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Code',
  data() {
    return {
      telErea: '',
      time: 60,
      disabled: true,
      btnBg: false,
      code: '',
      defaultCode: '2261',
      loading: false,
    };
  },
  created() {
    this.getCode();
  },
  methods: {
    getCode() {
      this.countDown();
    },
    changeCode(e) {
      // eslint-disable-next-line no-useless-escape
      this.code = e.target.value.replace(/\ +/g, '');
      if (this.code === this.defaultCode) {
        this.disabled = false;
        this.btnBg = true;
        this.loading = true;
      } else {
        console.log('Verification code input error');
      }
    },
    countDown() {
      if (this.time > 0) {
        // eslint-disable-next-line no-plusplus
        this.time--;
        setTimeout(this.countDown, 1000);
        // eslint-disable-next-line no-empty
      } else {
      }
    },
    login() {
      this.$router.push({ path: '/me' });
    },
  },
};
</script>

<style lang="less" scoped>
.sign {
  padding: 30px;
  background-color: #fff;

  .sign-header {
    display: flex;
    justify-content: space-between;
  }

  .sign-content {
    padding: 40px 10px;
  }

  h2 {
    margin: 0;
    font-size: 24px;
    font-weight: bold;
  }

  p {
    line-height: 20px;
    color: #686868;
  }

  p a {
    color: #628db8;
    padding: 0 5px;
  }

  .sign-box {
    display: flex;
    height: 50px;
    margin: 20px 0 0 0;
    align-items: center;
    background-color: #f9f9f9;
    justify-content: space-between;

    .inp-controll {
      height: 36px;
      background-color: #f9f9f9;
      width: 90%;
      margin-left: 10px;
    }

    input {
      caret-color: #fe2c55;
    }

    input::-webkit-input-placeholder {
      color: #686868;
    }

    .sele {
      margin-right: 20px;
      color: #686868;
    }
  }

  .sign-box:nth-child(3) {
    margin-top: 0px;
    margin-top: 10px;
  }

  .code-btn button {
    margin: 10px 0;
    width: 100%;
    padding: 15px 0;
    border: none;
    font-size: 18px;
    letter-spacing: 5px;
    color: #686868;
  }

  .active {
    color: #ffffff;
    background-color: #fe2c55;
  }

  .load-btn {
    display: flex;
    justify-content: center;
  }

  .loads {
    width: 16px;
    height: 16px;
    border: 3px solid cadetblue;
    border-bottom: 3px #cccccc solid;
    border-radius: 50%;
    animation: load 1s infinite linear;
    margin-right: 5px;
  }

  @keyframes load {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }
}
</style>

Binding and other function routing

First, configure the login route in the route file. The path is as follows:

The configuration code is as follows:

 {
    path: '/logIn', // Sign in
    name: 'LogIn',
    component: () => import(/* webpackChunkName: "logIn" */ '../views/LogIn.vue'),
  },
  {
    path: '/register', // register
    name: 'Register',
    component: () => import(/* webpackChunkName: "register" */ '../views/Register.vue'),
  },
  {
    path: '/code', // SMS verification
    name: 'Code',
    component: () => import(/* webpackChunkName: "code" */ '../views/Code.vue'),
  },

This is the route configuration in the navigation bar, so how to jump to the page through the route in the page? We have the function of obtaining the verification code on our login page. How to jump to the verification code page?
First, we need to bind click events, as follows:

<button :disabled="disabled" :class="[btnBg? 'active':'']" @click="getCode">Get SMS verification code</button>

Define functions in JavaScript to realize jump, as follows:

<script>
export default {
  name: 'Register',
  data() {
    return {
      telErea: '',
      showMask: false,
      disabled: true,
      btnBg: false,
      phone: '  ',
    };
  },
  methods: {
    back() {
      this.$router.push({ path: '/index' });
    },
  },
};
</script>

[warm tips] jump to the page here. We use this$ router. Push implementation.

Completion effect



Concluding remarks

This chapter mainly introduces the registration, login, verification code and other related contents. If you have any questions or deficiencies, please leave a message for discussion.

Project warehouse

The project is managed by Git, and the final project will be released to GitHub. Interested partners can learn and discuss together to improve the project.
Project address: GitHub

Previous: Comment list function

Topics: Javascript css3 html5 Vue.js