溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Vue怎么郵箱注冊和短信注冊登錄頁面

發(fā)布時(shí)間:2022-03-24 10:20:07 來源:億速云 閱讀:595 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“Vue怎么郵箱注冊和短信注冊登錄頁面”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Vue怎么郵箱注冊和短信注冊登錄頁面”吧!

一、項(xiàng)目環(huán)境

  1. 前端技術(shù)棧:Vue-Cli

  2. 前端軟體:WebStorm 2020.3

  3. 前端樣式: Bootstrap

  4. 后端技術(shù)棧:SpringBoot

  5. 后端軟體:IntelliJ IEDA2019

  6. JavaJDK:1.8

  7. 服務(wù)器:阿里云Centos 7

  8. 其他:MyBatis,Redis,MySql,Docker,Shiro

二、項(xiàng)目演示

  1. 項(xiàng)目源碼:shoppingProject01_pub : version6.0

  2. 項(xiàng)目參考:Project05;不良人_Vue-Cli;不良人_Redis;不良人_Axios;尚硅谷_Redis

  3. 項(xiàng)目功能:
    1)郵箱注冊登錄:
    用戶應(yīng)用郵箱注冊點(diǎn)擊提交后,網(wǎng)站會給用戶發(fā)送郵件附帶激活碼鏈接,用戶點(diǎn)擊鏈接實(shí)現(xiàn)賬號激活傳送門。
    2)短信注冊登錄:
    用戶應(yīng)用手機(jī)號注冊時(shí),點(diǎn)擊“獲取驗(yàn)證碼”按鈕,手機(jī)會接收到網(wǎng)站發(fā)送的短信附帶驗(yàn)證碼。基于Redis實(shí)現(xiàn)了驗(yàn)證碼有效期5分鐘,每個(gè)手機(jī)號只能獲取三次短信驗(yàn)證碼傳送門。
    3)alipay支付:
    通過下載Android版支付寶沙箱app用戶可通過alipay掃碼購買網(wǎng)站上的商品,后臺MySql會記錄該訂單行為傳送門,網(wǎng)頁展示如圖1所示。
    Vue怎么郵箱注冊和短信注冊登錄頁面

圖1 商品展示頁面

4)用戶小分級:
當(dāng)用戶掃碼購買年度VIP會員后,購買網(wǎng)站上的商品一律半價(jià),后臺MySql記錄用戶角色的變更。
5)用戶積分排行榜:
用戶購買商品會增加自己的積分,網(wǎng)頁展示如圖2所示。
Vue怎么郵箱注冊和短信注冊登錄頁面

圖2 排行榜展示頁面
  1. 項(xiàng)目中遇到的大坑:
    1)郵件發(fā)送功能本地測試通過,服務(wù)器端測試Bug頻出,解決辦法。
    2)項(xiàng)目在服務(wù)器部署后,無法連接服務(wù)器上的Redis。解決辦法:(1)將Redis在服務(wù)器部署而非Docker;(2)將Redis端口改為7000;(3)防火墻active狀態(tài)下放行服務(wù)器和阿里云的7000端口;(4)修改Redis.conf文件。
    3)git上傳本地源碼到gitee,誤操作導(dǎo)致本地源碼被gitee上的舊代碼覆蓋,第二天才發(fā)現(xiàn)。解決辦法:因?yàn)樵诜?wù)器上留有源碼的jar包,通過反編譯工具jd_gui救回半條命。另外git上傳文件參考傳送門。

三、主要模塊說明

Vue-Cli模塊說明:

1.1 Vue-Cli的概述:

1)以前后端分離、單頁面web應(yīng)用(SPA)為特點(diǎn),Vue-Cli可以創(chuàng)建一個(gè)Vue項(xiàng)目,這個(gè)項(xiàng)目存在腳手架規(guī)范。Vue-Cli的優(yōu)勢如下:
(1) 基于腳手架規(guī)范的開發(fā)會變得很靈活。
(2) Vue-Cli基于webpack構(gòu)建并帶有合理的默認(rèn)配置,打包工具webpack能夠聚合單頁面和各種開發(fā)組件。
(3) Vue-Cli是一個(gè)豐富的官方插件集合,繼承了前端生態(tài)中最好的工具。

2)安裝過程:
(1) 安裝WebStorm(用于開發(fā)),安裝node.js,安裝vue-cli,安裝axios(用于發(fā)起跨域請求),引入bootstrap樣式。

3)部署過程:

npm run build               # 在WebStorm終端執(zhí)行,生成dist文件夾
docker pull nginx:1.19.10   # 不建議Vue-cli項(xiàng)目部署到tomcat,因?yàn)閠omcat屬于動態(tài)服務(wù)器,啟動需要java環(huán)境,是為了解析動態(tài)語言jsp的;像純靜態(tài)的就部署到靜態(tài)服務(wù)器nginx上。
mkdir html                  # 為了做docker容器內(nèi)外的數(shù)據(jù)卷映射
mv dist/ html/
docker run -p 80:80 --name nginx01 -d -v /root/html/dist/:/usr/share/nginx/html nginx:1.19.10  # 數(shù)據(jù)卷映射
# 此時(shí)可訪問  http://120.79.133.235:80/index.html

4)Vue-Cli開發(fā)要點(diǎn):
(1)在WebStorm中,開發(fā)過程主要面向src文件,如圖3所示:
Vue怎么郵箱注冊和短信注冊登錄頁面

圖3 WebStorm目錄


[1] 首先掌握路由(router)和組件(components[公有組件],views[私有組件]),組件就是一個(gè)個(gè)“頁面”,組件建立后要向路由進(jìn)行注冊; [2] asserts封裝了bootstrap樣式,并在main.js中被導(dǎo)入; [3] 為了發(fā)送跨域請求,在utils中封裝了axios實(shí)例,代碼如下:

import axios from 'axios'

// 創(chuàng)建默認(rèn)實(shí)例
const instance = axios.create({
  baseURL: 'http://120.79.133.235:8989/eb',
  // timeout: 10000,
});

// 請求攔截器
instance.interceptors.request.use(config=>{
  console.log("請求攔截器");
  return config;
})
// 響應(yīng)攔截器
instance.interceptors.response.use(response=>{
  console.log("響應(yīng)攔截器");
  return response;
}, err=>{
  console.log("響應(yīng)出現(xiàn)錯(cuò)誤時(shí)進(jìn)入的攔截器");
});

// 暴露instance實(shí)例對象
export default instance;

在各組件中,對于后端的get和post請求方法如下:

// Get請求
// 向后端接口發(fā)當(dāng)前頁碼,獲取當(dāng)前頁面的商品List
instance.get("/item/findAllItem?page="+this.page).then(res=>{
        that.items = res.data.items;
        that.totalPage = res.data.totalPage;
        that.page = res.data.page;
      });

// Post請求
// 向后端接口發(fā)送當(dāng)前商品id和用戶id,獲取商品購買狀態(tài)
instance.post("/order/alipay/callback",{itemId:this.itemid,userId:this.user.id}).then(res=>{
        if ( res.data.code == 20000 ) {
          alert("提示:您已購買該商品");
        } else {
          alert("提示:您未購買該商品");
        }
      });
    }

[4] 組件之間的跳轉(zhuǎn)和傳值方法如下:

// 跳轉(zhuǎn)到MailReg組件
this.$router.push({name:"MailReg"});

// 跳轉(zhuǎn)到item組件,并傳遞當(dāng)前商品的id
this.$router.push({path:"/item",query:{ItemId:myid}});
// item組件接收方法:
this.itemid = this.$route.query.ItemId;

// 另外不同組件可以依據(jù)token獲取登錄用戶信息,需要用到redis,詳見下文

用戶積分排行榜模塊說明:
1.1 Reids概述:
1) Redis是一種基于內(nèi)存的數(shù)據(jù)存儲NoSql;
2) Redis支持豐富的數(shù)據(jù)類型(String, List, Set, ZSet, Hash);
3) Redis有兩種持久化方法: (1)快照(snapshot)存儲,也叫rdb持久化,保存當(dāng)前時(shí)刻的數(shù)據(jù)狀態(tài);(2) AOF(append only file)存儲,將所有redis的寫命令記錄到日志文件中,Redis支持持久化間隔最快也是一秒,所以它是事務(wù)不安全的,即是可能丟失數(shù)據(jù)的。
4)Redis的應(yīng)用場景:
(1) 利用Redis字符串完成項(xiàng)目中手機(jī)驗(yàn)證碼存儲的實(shí)現(xiàn)。------本項(xiàng)目采用
(2) 利用Redis字符串類型完成具有時(shí)效性的業(yè)務(wù)功能,如訂單還有40分鐘即將關(guān)閉。
(3) 利用Redis實(shí)現(xiàn)分布式集群系統(tǒng)中的Session共享。
(4) 利用Redis的ZSet數(shù)據(jù)類型(可排序set類型:元素+分?jǐn)?shù))實(shí)現(xiàn)排行榜功能。 ------本項(xiàng)目采用
(5) 利用Redis完成分布式緩存。 ------本項(xiàng)目實(shí)現(xiàn)MySql中數(shù)據(jù)的緩存
(6) 利用Redis存儲認(rèn)證之后的token信息。 ------非常方便,本項(xiàng)目采用。
(7) 利用Redis解決分布式集群系統(tǒng)中分布式鎖問題。

1.2 基于Redis實(shí)現(xiàn)前端組件從后端獲取用戶信息
Step1:前端Login.vue組件中用戶輸入登錄信息提交的接口如下:

// 這里調(diào)用了后端/user/login接口,獲取當(dāng)前登錄用戶的token,存入Session的localStorage中,在后續(xù)網(wǎng)頁瀏覽過程中可隨時(shí)調(diào)取這個(gè)token
instance.post("/user/login",this.user).then(res=>{
        if ( res.data.state ) {
          alert(res.data.msg+",點(diǎn)擊確定進(jìn)入主頁");
          // 前端存儲token信息
          localStorage.setItem("token",res.data.token);
          that.$router.push({path:"/itemList"});
        } else {
          alert(res.data.msg);
          that.user = {};
        }
      });

Step2:后端/user/login接口實(shí)現(xiàn)如下:

// Controller層
@PostMapping("login")
public Map<String, Object> loginAccount(@RequestBody User user, HttpSession session) {
    return userService.loginAccount(user, session);
}

// Service層
// 情況3:查詢到一個(gè)用戶時(shí)
// 獲取主體對象
try {
     Subject subject = SecurityUtils.getSubject();
     subject.login(new UsernamePasswordToken(user.getName(), user.getPassword()));
     User userDB = userListDB.get(0);
     String token = session.getId();
     if (userDB.getScore() == null) {
           userDB.setScore(0.0);
           userDAO.updateUserScore(userDB);
     }
     redisTemplate.opsForValue().set("TOKEN_" + token, userDB, 30, TimeUnit.MINUTES);
     redisTemplate.opsForZSet().add("userRank", userDB, userDB.getScore());
     map.put("token", token);
     map.put("state",true);
     map.put("msg","登錄成功");
     return map;
     ...

Redis整合SpringBoot有兩種Template,即RedisTemplate和StringRedisTemplate。其中StringRedisTemplate是RedisTemplate的子類,兩個(gè)方法基本一致,不同之處在于操作的數(shù)據(jù)類型不同,RedisTemplate中的兩個(gè)泛型都是Object,意味著存儲的key和value都可以是一個(gè)對象,而StringRedisTemplate的兩個(gè)泛型都是String,意味著StringRedisTemplate的key和value都只能是字符串。
在Step2中,我將token和數(shù)據(jù)庫中的用戶信息userDB綁定在一起存入了Redis中,后續(xù)前端組件獲取登錄用戶信息的代碼如下:

// 從localStorage獲取token
let token = localStorage.getItem("token");
let that = this;
// 發(fā)送axios請求,根據(jù)token獲取用戶信息
instance.get("/user/token?token="+token).then(res=>{
that.user = res.data;
console.log(that.user);
})

后端/user/token的接口如下:

@GetMapping({"token"})
public User findUser(String token) {
   System.out.println("接收的token信息:" + token);
   return (User)redisTemplate.opsForValue().get("TOKEN_" + token);
}

Step3:用戶退出登錄時(shí),應(yīng)消除瀏覽器中對應(yīng)的token,后端接口代碼如下:

    // 退出登錄
    @DeleteMapping({"logout"})
    public Map<String, Object> logout(String token) {
        Map<String, Object> map = new HashMap<>();
        try {
            redisTemplate.delete("TOKEN_" + token);
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
            map.put("state", true);
            map.put("msg", "提示:退出賬戶成功");
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            map.put("state", false);
            map.put("msg", "提示:退出賬戶失敗");
            return map;
        }
    }

1.3 基于Redis的用戶積分排行榜實(shí)現(xiàn)
MySql中的用戶信息如圖4所示:
Vue怎么郵箱注冊和短信注冊登錄頁面

圖4 MySql中的用戶信息


Redis中的UserRank如圖5所示:

Vue怎么郵箱注冊和短信注冊登錄頁面

圖5 Redis中的UserRank

Step1:當(dāng)用戶登錄時(shí),他的首要任務(wù)是接入U(xiǎn)serRank對應(yīng)的信息,后端代碼如下:

if (userDB.getScore() == null) {
    userDB.setScore(0.0);
    userDAO.updateUserScore(userDB);
}
    redisTemplate.opsForValue().set("TOKEN_" + token, userDB, 30, TimeUnit.MINUTES);
    redisTemplate.opsForZSet().add("userRank", userDB, userDB.getScore());

userDB是數(shù)據(jù)庫中當(dāng)前登錄用戶的信息(一定是有的,你注冊了,對吧?),若用戶首次登錄我將他的分?jǐn)?shù)在數(shù)據(jù)庫設(shè)置為0.0,之后我在Redis的ZSet中加入這個(gè)用戶,你知道,Set集合不會存儲重復(fù)key值的元素,因此不會同一個(gè)用戶出現(xiàn)在UserRank中兩次。兩個(gè)template完成了token綁定User,User綁定UserRank中Score的過程,之后的分?jǐn)?shù)更新過程會反復(fù)使用這兩個(gè)template實(shí)現(xiàn)。
Step2:當(dāng)用戶信息更新時(shí),相應(yīng)的與用戶信息有關(guān)的兩個(gè)template都要發(fā)生變化,代碼如下:

// key值序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 由當(dāng)前用戶的token獲取當(dāng)前用戶的信息
User firstUser = (User)redisTemplate.opsForValue().get("TOKEN_" + token);
// 刪除zSet中的當(dāng)前用戶
 redisTemplate.opsForZSet().remove("userRank", firstUser);
// 產(chǎn)生新的當(dāng)前用戶(昵稱改變)
List<User> userListDB = this.userDAO.selectUserByName(user.getName());
User secondUser = userListDB.get(0);
// 更新token中當(dāng)前用戶的信息
redisTemplate.opsForValue().set("TOKEN_" + token, secondUser, 30, TimeUnit.MINUTES);
// 產(chǎn)生zSet中的當(dāng)前用戶
redisTemplate.opsForZSet().add("userRank", secondUser, secondUser.getScore());

Step3:當(dāng)用戶掃碼支付時(shí),首次進(jìn)入的后端controller如下:

// 支付單件商品
    @GetMapping("payForItem")
    public byte[] alipay(String itemid,String userid, String token) {
        this.token = token;
        log.info("itemid=====>"+itemid);
        log.info("userid=====>"+userid);
        PayVo payVo = new PayVo();
        payVo.setItemId(itemid);
        payVo.setUserId(userid);
        System.out.println(payVo.getUserId());
        return alipayService.alipay(payVo);
    }

在alipayService有一個(gè)小型用戶分級,即vip用戶購物價(jià)格減半:

            // 1:支付的用戶
            String userId = payVo.getUserId();
            // my 1: 依據(jù)用戶id查詢用戶
            User user = userService.selectUserById(Integer.valueOf(userId));
            // 依據(jù)商品id查詢商品
            Item item = itemService.getItemById(payVo.getItemId());
            // my 1: 依據(jù)用戶id查詢用戶
            if ( item == null ) return null;
            // 2: 支付金額
            String tempMoney = item.getPrice().toString();
            String money = "";
            if ( user.getRole().equals("normal") ) {
                money = tempMoney;
            }
            if ( user.getRole().equals("vip") ) {
                Double tempMoney2 = Double.valueOf(tempMoney)*0.5;
                money = String.valueOf(tempMoney2);
            }

在payForItem相同文件下,調(diào)用了payCommonService,在這里會實(shí)現(xiàn)用戶積分更新和用戶等級更新:

payCommonService.payUserPublic(bodyJsonObject, userId, user.getName(), orderNumber, tradeno, "alipay", this.token);

將"VIP"這件商品的id設(shè)置為“666”,當(dāng)用戶購買該商品時(shí),當(dāng)前用戶更新過程如下:

if ( itemId.equals("666") ) {
            int myuserId = Integer.valueOf(userId);
            User userDB = userService.selectUserById(myuserId);
            // key值序列化
            this.redisTemplate.setKeySerializer(new StringRedisSerializer());
            // 由當(dāng)前token獲取當(dāng)前用戶信息
            User firstUser = (User)redisTemplate.opsForValue().get("TOKEN_" + token);
            // 由當(dāng)前用戶信息刪除當(dāng)前用戶zSet
            redisTemplate.opsForZSet().remove("userRank", firstUser);
            // 更新當(dāng)前用戶信息身份
            userDB.setRole("vip");
            // 更新當(dāng)前用戶新身份的分?jǐn)?shù)
            userService.updateUserRole(userDB);
            List<User> userListDB = this.userDAO.selectUserByName(userDB.getName());
            // 獲取當(dāng)前新身份用戶的完整信息
            User secondUser = userListDB.get(0);
            // 更新當(dāng)前token對應(yīng)的當(dāng)前用戶
            redisTemplate.opsForValue().set("TOKEN_" + token, secondUser, 30, TimeUnit.MINUTES);
            // 設(shè)置當(dāng)前用戶的zSet
            redisTemplate.opsForZSet().add("userRank", secondUser, secondUser.getScore().doubleValue());
        }

當(dāng)前用戶積分更新過程如下:

        // 更新當(dāng)前用戶的積分
        double tempScore = Double.valueOf(orderDetail.getPrice()) * 0.3;
        String key1 = "TOKEN_" + token;
        // 由當(dāng)前token獲取當(dāng)前用戶
        User user = (User)redisTemplate.opsForValue().get(key1);
        // 更新當(dāng)前用戶的zSet分?jǐn)?shù)
        redisTemplate.opsForZSet().incrementScore("userRank", user, tempScore);
        // 獲取當(dāng)前用戶的zSet分?jǐn)?shù)
        double newScore = redisTemplate.opsForZSet().score("userRank", user);
        // 刪除當(dāng)前用戶的zSet(因?yàn)橐庐?dāng)前用戶的信息,將當(dāng)前用戶在數(shù)據(jù)庫中的分?jǐn)?shù)進(jìn)行同步)
        redisTemplate.opsForZSet().remove("userRank", new Object[] { user });
        user.setScore(newScore);
        userDAO.updateUserScore(user);
        // 更新token對應(yīng)的當(dāng)前用戶的信息
        redisTemplate.opsForValue().set(key1, user);
        // 新增當(dāng)前用戶的zSet
        redisTemplate.opsForZSet().add("userRank", user, newScore);

感謝各位的閱讀,以上就是“Vue怎么郵箱注冊和短信注冊登錄頁面”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Vue怎么郵箱注冊和短信注冊登錄頁面這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

vue
AI