Vue學(xué)習(xí)之路之登錄注冊(cè)實(shí)例代碼
根據(jù)Vue.js + Element UI + MongoDB進(jìn)行開(kāi)發(fā)
P1 安裝Vue-CLI
利用Vue.js提供的一個(gè)官方命令行工具
# 全局安裝 vue-cli $ npm install --global vue-cli # 創(chuàng)建一個(gè)基于 webpack 模板的新項(xiàng)目 $ vue init webpack my-project # 安裝依賴,走你 $ cd my-project $ npm install $ npm run dev
Vue.js 主要目錄結(jié)構(gòu)
. ├── build # 一些webpack的文件,配置參數(shù)什么的,一般不用動(dòng) ├── config # vue項(xiàng)目的基本配置文件 ├── index.html # 主頁(yè) ├── node_modules # 項(xiàng)目中安裝的依賴模塊 ├── package.json # 項(xiàng)目文件,記載著一些命令和依賴還有簡(jiǎn)要的項(xiàng)目描述信息 ├── README.md ├── server # 自己創(chuàng)建的后端文件,可以忽視 ├── src # 源碼文件夾,基本上文件都應(yīng)該放在這里 ├── App.vue # App.vue組件 ├── assets # 資源文件夾,里面放一些靜態(tài)資源 ├── components # 這里放的都是各個(gè)組件文件 ├── main.js # 入口文件 └── router # vue-router 路由配置 ├── static # 生成好的文件會(huì)放在這個(gè)目錄下 ├── test # 測(cè)試文件夾,測(cè)試都寫在這里 ├── .babelrc # babel編譯參數(shù),vue開(kāi)發(fā)需要babel編譯 ├── .gitignore └── .eslintignore
完成后就可以在/src/components/*.vue模板中寫代碼,ctrl+s保存后頁(yè)面會(huì)自動(dòng)刷新,若無(wú)效請(qǐng)檢查端口是否被占用
P2 安裝Element UI
npm i element-ui -S
完成后在main.js中添加如下代碼完整引入Element,就能在/src/components/*.vue模板中使用Element UI的組件
// main.js import ElementUI from 'element-ui' import 'element-ui/lib/theme-default/index.css' Vue.use(ElementUI)
P3 登錄注冊(cè)功能
思路
- 得益于vue的數(shù)據(jù)雙向綁定,讓我們不用操作DOM就能邊輸入邊驗(yàn)證字符串合法性
- 利用axios實(shí)現(xiàn)前后端的數(shù)據(jù)交互
- 利用jsonwebtoken實(shí)現(xiàn)登錄驗(yàn)證,結(jié)合vue-router的beforeEnter導(dǎo)航鉤子在跳轉(zhuǎn)前攔截驗(yàn)證access_token的有效性
驗(yàn)證輸入的賬號(hào)和密碼是否合法(利用elementui的form表單)
export default { name: 'register', data () { var validateUser = (rule, value, cb) => { var pattern = /^[\w\u4e00-\u9fa5]{3,10}$/g if (value === '') { cb(new Error('請(qǐng)輸入用戶名')) } else if (!pattern.test(value)) { cb(new Error('請(qǐng)輸入3-10個(gè)字母/漢字/數(shù)字/下劃線')) } else { cb() } } var validatePwd = (rule, value, cb) => { var pattern = /^\S{3,20}$/g if (value === '') { cb(new Error('請(qǐng)輸入密碼')) } else if (!pattern.test(value)) { cb(new Error('請(qǐng)輸入3-20個(gè)非空白字符')) } else { if (this.registerForm.checkPwd !== '') { this.$refs.registerForm.validateField('checkPwd') } cb() } } var validateCheckPwd = (rule, value, cb) => { if (value === '') { cb(new Error('請(qǐng)?jiān)俅屋斎朊艽a')) } else if (value !== this.registerForm.pwd) { cb(new Error('兩次輸入密碼不一致!')) } else { cb() } } return { registerForm: { userName: '', pwd: '', checkPwd: '' }, registerRule: { userName: [ { validator: validateUser, trigger: 'blur' } ], pwd: [ { validator: validatePwd, trigger: 'blur' } ], checkPwd: [ { validator: validateCheckPwd, trigger: 'blur' } ] } } }, methods: { submitForm (formName) { this.$refs[formName].validate((valid) => { if (valid) { ... } else { return false } }) } } }
利用axios實(shí)現(xiàn)與后端數(shù)據(jù)的交互
Axios.post('http://localhost:3000/register', data) .then(res => { console.log(res.data) if (res.data.code === 0) { this.$message({ showClose: true, message: '注冊(cè)成功', type: 'success' }) router.push({name: 'Login'}) } else { this.$message({ showClose: true, message: '注冊(cè)失敗', type: 'error' }) } })
使用 JSON WEB Tokens 實(shí)現(xiàn)登錄驗(yàn)證
由于node后端和vue前端是兩個(gè)不同的端口(:3000和:8090),對(duì)于跨域(我已經(jīng)允許跨域訪問(wèn)),session和cookie就不要想了,并不是設(shè)置一個(gè)什么就能解決的,花了一下午才發(fā)現(xiàn),所以使用了token來(lái)做api請(qǐng)求,而且還能加密。
后端處理登錄
// sever/db/dbHelper.js exports.findUser = function(data, cb) { User.findOne({ username: data.usr }, function(err, doc) { // 用戶密碼都正確 // jwt.encode({加密對(duì)象, 持續(xù)時(shí)間}, 密鑰字符串) entries.data = user entries.code = 0 var time = moment().add(1, 'days').valueOf() entries.access_token = jwt.encode({ iss: user._id, exp: time }, jwtTokenSecret) cb(true, entries) }) }
加密后的entries.access_token:
前端獲取到后端傳遞過(guò)來(lái)的access_token,將其保存進(jìn)sessionStorage。這個(gè)導(dǎo)航鉤子我放在/p路由獨(dú)享的鉤子下,在進(jìn)入/p/:id前攔截導(dǎo)航,通過(guò)axios向后端傳遞access_token,根據(jù)后臺(tái)返回值判斷是否已經(jīng)登錄。
注意router.beforeEach確保要調(diào)用next方法,否則鉤子就不會(huì)被 resolved,但after鉤子沒(méi)有 next方法,不能改變導(dǎo)航
beforeEnter: (to, from, next) => { let pattern = /^(\/p)/g let token = sessionStorage.getItem('accessToken') //保存token if (pattern.test(to.path)) { Axios.post('http://localhost:3000/isLogin', {access_token: token}) .then(res => { if (res.data.code === 0) { console.log(from) console.log(to) next() } else { router.push({name: 'Login'}) next() } }) .catch(err => { console.log(err) }) } }
后端處理token是否合法
后臺(tái)獲取到傳遞的token值,利用jwt.decode(token, jwtTokenSecret)對(duì)其解碼,解碼結(jié)果就是當(dāng)初我們加密的對(duì)象{iss, exp},首先根據(jù)exp判斷token是否過(guò)期,然后根據(jù)_id查詢數(shù)據(jù)庫(kù)是否有這個(gè)用戶
// 登錄驗(yàn)證 exports.authority = function (req, cb) { // JWT 允許客戶端使用一下3個(gè)方法附加token: // 作為請(qǐng)求鏈接(query)的參數(shù),作為主體的參數(shù)(body), // 和作為請(qǐng)求頭(Header)的參數(shù)。 var token = (req.body && req.body.access_token) || (req.query && req.query.access_token) || req.headers['access-token'] if (token) { try { var decoded = jwt.decode(token, jwtTokenSecret) // 解碼 if (decoded.exp <= Date.now()) { // 判斷token是否過(guò)期 entries.code = 99 cb(false, entries) } else { // 之前加密對(duì)象是 user._id User.findOne({ _id: decoded.iss }, function(err, user) { if (err) { console.log(err) } else if (user !== null) { entries.code = 0 cb(true, entries) } }) } } catch (err) { console.log(err) } } else { entries.code = 99 cb(false, entries) } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue?使用el-table循環(huán)生成表格的過(guò)程
這篇文章主要介紹了vue?使用el-table循環(huán)生成表格的過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue3+elementPlus項(xiàng)目支持生成、設(shè)置默認(rèn)附件方式
這篇文章主要介紹了vue3+elementPlus項(xiàng)目支持生成、設(shè)置默認(rèn)附件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue-cli+axios實(shí)現(xiàn)文件上傳下載功能(下載接收后臺(tái)返回文件流)
這篇文章主要介紹了vue-cli+axios實(shí)現(xiàn)文件上傳下載功能(下載接收后臺(tái)返回文件流),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05Vue實(shí)現(xiàn)點(diǎn)擊按鈕下載文件的操作代碼(后端Java)
最近項(xiàng)目中需要實(shí)現(xiàn)點(diǎn)擊按鈕下載文件的需求,前端用的vue后端使用的java代碼,今天通過(guò)本文給大家分享vue點(diǎn)擊按鈕下載文件的實(shí)現(xiàn)代碼,需要的朋友參考下吧2021-08-08vue組件中傳值EventBus的使用及注意事項(xiàng)說(shuō)明
這篇文章主要介紹了vue組件中傳值EventBus的使用及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11Vue組件簡(jiǎn)易模擬實(shí)現(xiàn)購(gòu)物車
這篇文章主要為大家詳細(xì)介紹了Vue組件簡(jiǎn)易模擬實(shí)現(xiàn)購(gòu)物車,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12Vue輸入框狀態(tài)切換&自動(dòng)獲取輸入框焦點(diǎn)的實(shí)現(xiàn)方法
這篇文章主要介紹了Vue輸入框狀態(tài)切換&自動(dòng)獲取輸入框焦點(diǎn)的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05vue中json格式化顯示數(shù)據(jù)(vue-json-viewer)
這篇文章主要給大家介紹了關(guān)于vue中json格式化顯示數(shù)據(jù)(vue-json-viewer)的相關(guān)資料,Vue-json-viewer是一個(gè)Vue組件,用于在Vue應(yīng)用中顯示JSON數(shù)據(jù)的可視化工具,需要的朋友可以參考下2024-05-05