1. 程式人生 > 實用技巧 >Vue登入註冊

Vue登入註冊

  1. 註冊
    1.1 註冊頁面的佈局
    1.2 註冊業務邏輯的實現
    1.3封裝api
  2. 登入
    3.導航守衛
  3. 註冊
    1.1 註冊頁面的佈局
    需要用到Vant的Field元件
    1.views下新建一個註冊頁面 ,完成基本佈局。引入Vue和Field並使用。
    3.給註冊頁面新增一個單獨的路由,註冊頁面不需要底部。(注意,相關樣式需要引入不同的元件,請細心檢視官方文件,按需拿取內容)
  4. 利用計算屬性給輸入框做條件判斷。本案例以手機號為例。

1.在views目錄下建立三個檔案
1.1、一個RetrievePass.vue檔案寫入註冊的程式碼塊
1.2、一個Register.vue檔案寫入手機驗證碼登入
1.3、一個Login.vue檔案寫入密碼登入

RetrievePass.vue檔案註冊

<template>
<!-- 註冊 -->
  <div>
    <div class="zhx_retrieve">
      <van-field v-model="sms" center clearable placeholder="請輸入手機號">
        <template #button>
          <a size="small" type="primary">傳送驗證碼</a>
        </template>
      </van-field>
      <van-cell-group>
        <van-field v-model="sss" placeholder="請輸入驗證碼" />
      </van-cell-group>
      <van-cell-group>
        <van-field v-model="password" placeholder="請輸入密碼" />
      </van-cell-group>
    </div>
    <div class="zhx_login_button">
      <button>登入</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sms: "",
      sss: "",
      password: "",
    };
  },
};
</script>

<style>
.zhx_retrieve {
  width: 100%;
  height: 25vh;
}
.zhx_login_button {
  width: 100%;
  height: 10vh;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 0.8rem;
}
.zhx_login_button button {
  width: 90%;
  height: 7vh;
  background: orange;
  border-radius: 18px;
  border: none;
}
</style>

  

1.2 註冊業務邏輯的實現
注:在此之前,記住要先去路由頁面新增一個註冊頁面的路由。
1.補充了密碼以及驗證碼的計算屬性判斷
密碼:如果為空返回空,如果不符合正則,返回格式錯誤,否則表示可以直接返回空
驗證碼:如果為空返回空,否則不為五位,返回驗證碼格式錯誤,否則成功返回空
2.驗證碼

繫結點選事件senCode
將提示資訊{{buttonmsg}}放在按鈕內容中。
定義函式:(定時器注意用箭頭函式)每一秒鐘定義一次,先提前宣告時間,在計時器內讓時間減減,當時間為零時,清除定時器,同時btn的內容改為傳送驗證碼,最後return。未return時,讓按鈕內的內容為時間減減+後重新發送(注意:在開啟定時器時,要讓按鈕禁止點選,在清除定時器後再讓按鈕可點。)

Register.vue檔案手機驗證碼登入

<template>
  <!-- 手機驗證登入 -->
  <div>
    <div class="zhx_login_img">
      <img src="../../assets/login/Login.png" alt="" />
    </div>
    <div class="zhx_register">
      <van-field v-model="sms" center clearable placeholder="請輸入手機號">
        <template #button>
          <a
            style="color: red"
            v-show="isShow == false"
            size="small"
            type="primary"
            @click="onClickSend"
            >傳送驗證碼</a
          >
          <a style="color: gray" v-show="isShow == true"
            >獲取驗證碼({{ num }})</a
          >
        </template>
      </van-field>
      <van-cell-group>
        <van-field v-model="sss" placeholder="請輸入驗證碼" />
      </van-cell-group>
    </div>
    <div class="zhx_register_pass">
      <span>*未註冊的手機號將自動註冊</span>
      <span @click="onLogin">使用密碼登入</span>
    </div>
    <div class="zhx_login_button">
      <button @click="redister">登入</button>
    </div>
  </div>
</template>

<script>
import Vue from "vue";
import { Toast } from "vant";

Vue.use(Toast);
export default {
  data() {
    return {
      sms: "",
      sss: "",
      isShow: false,
      num: 60,
    };
  },
  methods: {
    onLogin() {
      this.$router.push("/login");
    },
    onClickSend() {
      this.$APP
        .smsCode({
          mobile: this.sms,
          sms_type: "login",
        })
        .then((res) => {
          console.log(res);
          if (res.data.code === 200) {
            this.countDown();
            Toast(res.data.msg);
          } else if (res.data.code == 201) {
            Toast(res.data.msg);
          }
        });
    },
    //倒計時
    countDown() {
      this.isShow = true;
      setInterval(() => {
        this.num--;
        if (this.num <= 0) {
          this.isShow = false;
          this.num = 60;
        }
      }, 1000);
    },

    redister() {
      this.$APP
        .login({
          mobile: this.sms,
          sms_code: this.sss,
          client: 1,
          type: 2,
        })
        .then((res) => {
          console.log(res);
          let token = res.data.data.remember_token;
          window.localStorage.setItem("token", token);
          this.$router.push("/home");
        });
    },
  },
};
</script>

<style scoped>
.zhx_register {
  width: 100%;
  height: 15vh;
}
.zhx_login_img {
  width: 100%;
  height: 30vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.zhx_login_img img {
  width: 80%;
}

.zhx_login_button {
  width: 100%;
  height: 10vh;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 0.8rem;
}
.zhx_login_button button {
  width: 90%;
  height: 7vh;
  background: orange;
  border-radius: 18px;
  border: none;
}
.zhx_register_pass {
  width: 100%;
  height: 12vh;
  display: flex;
  justify-content: space-around;
  font-size: 0.6rem;
  color: gray;
}
</style>

  Login.vue檔案密碼登入

<template>
  <!-- 密碼登入 -->
  <div class="zhx_login">
    <div class="zhx_login_img">
      <img src="../../assets/login/Login.png" alt="" />
    </div>
    <div>
      <van-form @submit="onSubmit">
        <van-field
          v-model="username"
          name="使用者名稱"
          placeholder="使用者名稱"
          :rules="[{ required: true, message: '請填寫使用者名稱' }]"
        />
        <van-field
          v-model="password"
          type="password"
          name="密碼"
          placeholder="密碼"
          :rules="[{ required: true, message: '請填寫密碼' }]"
        />
      </van-form>
    </div>
    <div class="zhx_login_register">
      <span @click="retrieve">找回密碼</span>
      <div>
        <span @click="onRegister">註冊/驗證碼登入</span>
      </div>
    </div>
    <div class="zhx_login_button">
      <button @click="onClickLogin">登入</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: "",
      password: "",
    };
  },
  methods: {
    onSubmit(values) {
      console.log("submit", values);
    },
    retrieve() {
      this.$router.push("/retrieve");
    },
    onRegister() {
      this.$router.push("/register");
    },
    //登入
    onClickLogin() {
      this.$APP
        .login({
          mobile: this.username,
          password: this.password,
          type: 1,
        })
        .then((res) => {
          console.log(res);
          let token = res.data.data.remember_token;
          window.localStorage.setItem("token", token);
          console.log(res.data.data.is_new);
          this.$router.push("/home");
        });
    },
  },
};
</script>

<style scoped>
.zhx_login {
  width: 100%;
}
.zhx_login_img {
  width: 100%;
  height: 30vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.zhx_login_img img {
  width: 80%;
}
.zhx_login_register {
  width: 100%;
  height: 10vh;
  display: flex;
  align-items: center;
  justify-content: space-around;
  font-size: 0.6rem;
  color: gray;
}
.zhx_login_button {
  width: 100%;
  height: 10vh;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 0.8rem;
}
.zhx_login_button button {
  width: 90%;
  height: 7vh;
  background: orange;
  border-radius: 18px;
  border: none;
}
</style>

  

在src裡建立一個api檔案寫入三個js檔案進行封裝
1.1、一個core.js檔案封裝axios請求攔截和響應攔截
1.2、一個index.js檔案封裝請求的方法
1.3、一個path.js檔案封裝介面

core.jsaxios請求攔截和響應攔截

import axios from "axios"
import apl from "./path"
import {
    Loading
} from 'element-ui';

const instance = axios.create({ //axios建立的例項
    baseURL: 'http://120.53.31.103:84', // `baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。
    timeout: 5000, // `timeout` 指定請求超時的毫秒數(0 表示無超時時間)  如果請求話費了超過 `timeout` 的時間,請求將被中斷
    headers: {
        'X-Custom-Header': 'foobar' // `headers` 是即將被髮送的自定義請求頭
    }
});

var loading = null


// 新增請求攔截器
instance.interceptors.request.use(function (config) {
    // 在傳送請求之前做些什麼
    loading = Loading.service();
    return config;
}, function (error) {
    // 對請求錯誤做些什麼
    return Promise.reject(error);
});

// 新增響應攔截器
instance.interceptors.response.use(function (response) {
    // 對響應資料做點什麼
    setTimeout(function () {
        loading.close()
    }, 500)
    return response;
}, function (error) {
    // 對響應錯誤做點什麼
    return Promise.reject(error);
});

export function request(method, url, params) { //建立的request函式,把函式丟擲
    switch (method) { //switch判斷
        case apl.METHODS.GET: //當請求的方式為GET的時候,
            return get(url, params) //把get方式return出去
        case apl.METHODS.POST: //當請求的方式為POST的時候,
            return post(url, params) //把post方式return出去
    }
}

function get(url, params) { //封裝的一個get函式
    return instance.get(url, params)
}

function post(url, params) { //封裝的一個post函式
    return instance.post(url, params)
}

  index.js檔案請求的方法

import {
    request
} from "../apl/core"
import apl from "../apl/path"

const APP = {
    login(params) {
        return request(apl.METHODS.POST, apl.URL.Login, params);
    },
    smsCode(params) {
        return request(apl.METHODS.POST, apl.URL.SmsCode, params);
    },
    change(params) {
        return request(apl.METHODS.POST, apl.URL.Change, params);
    },
}

export default APP

  path.js檔案介面

const apl = {
    METHODS: {
        GET: "get", //get請求
        POST: "post" //post請求
    },
    //介面路徑
    URL: {
        //登入
        Login: "/api/app/login",
        //驗證碼登入
        SmsCode: "/api/app/smsCode",
        //修改密碼
        Change: "/api/app/password"
    }
}
export default apl

  在router檔案裡配置需要的檔案

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/login/Login.vue')
  },
  {
    path: '/register',
    name: 'Register',
    component: () => import('../views/login/Register.vue')
  },
  {
    path: '/retrievePass',
    name: 'RetrievePass',
    component: () => import('../views/login/RetrievePass.vue')
  },
  {
    path: '/home',
    name: 'Home',
    component: () => import('../views/Home.vue')
  }
]

const router = new VueRouter({
  // mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

  在min.js裡配置自己需要的元件

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Vant from "vant"
import "vant/lib/index.css"
import axios from "axios"
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vue.use(Vant)
Vue.prototype.$axios = axios
Vue.config.productionTip = false

import APP from './apl/index'
Vue.prototype.$APP = APP;


new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')