项目演示地址:https://hujiyi.github.io/acme-world-web/
Leancloud 数据存储
LeanCloud
(原 AVOS Cloud) 是针对移动应用的一站式云端服务,专注于为应用开发者提供工具和平台。提供包括LeanStorage 数据存储
、LeanMessage 通信服务
、LeanAnalytics 统计分析
、LeanModules 拓展模块
等四大类型的后端云服务。当前项目使用了LeanStorage 数据存储
来实现论坛数据的保存。
Leancloud SDK
的初始化配置信息
LeanCloud
国内默认的是华北节点
,但是去年华北节点的文件服务器因为某些原因,出现了域名服务方面的问题。导致文件可以上传,但是没办法访问,所以这里建设使用 华东节点
。
登录 Leancloud华东节点 (没有账号的请先注册),然后创建应用,应用名称自己取,操作类似下图:
应用创建成功后,点击该应用最左边的 数据存储
图标,进入应用管理界面,如下图:
在右侧菜单选择:设置
-> 应用凭证
, 即可看到当前应用的 AppID
, AppKey
, REST API服务器地址
等初始化 Leancloud SDK
所需要的信息,如下图:
请将上图中的 AppID
, AppKey
, REST API服务器地址
(画圈、打勾的那三个)信息复制后,粘贴到 src/api/config/lc.config.js
文件中完成初始化信息配置。
Leancloud SDK
数据存储
在 Leancloud
应用管理界面选择:数据存储
-> 结构化数据
, 列表显示当前应用以下划线开头的内置的Class
, leancloud 的每一个 Class 就相当于数据库的一个表。
名为 _User
的内置 Class
用于保存用户信息的, 除了原来的字段,我们也可以添加更多的字段如:头像、昵称等。
账号服务类
在 src/api/
文件夹下新建一个名为 service
的文件夹,并在该文件夹中添加文件:account_service.js
。
打开新建的 src/api/service/account_service.js
, 编辑其代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| import LC from 'leancloud-storage';
class AccountService {
async signUp(username, password, email = '') { try { let user = new LC.User(); user.setUsername(username); user.setPassword(password); user.set('nickname', username); if (email) { user.setEmail(email); } let response = await user.signUp(); console.log('注册账号成功:', response); return { "status_code": "ok", "user": response, }; } catch (e) { console.log('注册账号失败:', e.code, e); return { "status_code": e.code, "user": null, }; } }
async logIn(username, password) { try { let user = await LC.User.logIn(username, password); if (user) { console.log('登录成功:', user); return { "status_code": "ok", "user": user, }; } } catch (e) { console.log('登录失败:', e.code, e); return { "status_code": e.code, "user": null, }; } return null; }
async logOut() { return LC.User.logOut(); }
async passwordResetByEmail(email) { try { let response = await LC.User.requestPasswordReset(email); console.log(response.code, typeof response); return { "status_code": "ok" }; } catch (e) { console.log("发送邮件:", e.code, e); return { "status_code": e.code, } } }
async getToken() { return LC.User.current().getSessionToken(); }
}
export default new AccountService();
|
leancloud SDK
用户的相关文档请查看:https://leancloud.cn/docs/leanstorage_guide-js.html#hash954895
新用户注册功能的实现
打开文件 src/views/account/pages/SignUp.vue
, 编辑其代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| <template> <el-card shadow="always" class="login-module"> <el-form> <div class="horiz-container form-title"> <span>注册新用户</span> <div class="spacer"></div> <span> <router-link to="/"> <i class="fa fa-home fa-lg" aria-hidden="true"></i> </router-link> </span> </div> <el-form-item> <el-input type="text" prefix-icon="fa fa-envelope-o fa-lg" v-model="email" placeholder="电子邮箱" ></el-input> </el-form-item>
<el-form-item> <el-input type="text" prefix-icon="fa fa-user-o fa-lg" v-model="username" placeholder="用户名" ></el-input> </el-form-item> <el-form-item> <el-input type="password" prefix-icon="fa fa-lock fa-lg" v-model="password" placeholder="密码" ></el-input> </el-form-item> <el-form-item> <el-button class="full-width" type="primary" @click="createUser">注册新用户</el-button> </el-form-item> <div class="horiz-container"> <div class="spacer"></div> <router-link to="/login" class="link"> <el-link :underline="false" type="success">使用已有账号登录</el-link> </router-link> </div> </el-form> </el-card> </template>
<script>
import AccountService from "../../../api/service/account_service"; export default { name: "SignUp", data: () => ({ username: "", password: "", email: "", }), methods: { async createUser() { let response = await AccountService.signUp(this.username, this.password, this.email); if (response.status_code == "ok") { let token = await AccountService.getToken(); localStorage.setItem("token", token); localStorage.setItem("currentUser", this.username); this.$router.push("/dashboard"); } else { let errorMsg = { "125": "无效的电子邮件地址", "202": "此用户名已被注册", "203": "此电子邮箱已经被占用", "-1": "请求被终止,请检查网络连接状况", }; this.$notify.error({ title: '注册失败', message: errorMsg[response.status_code], showClose: false, }); } } }, }; </script>
<style> .login-module { width: 380px; } </style>
|
在项目结果的网页中点击链接到注册新用户
的界面, 输入新用户的电子邮箱
,用户名
和密码
, 如下图所示(为方便看到可能出现的错误或异常信息,请按 F12
打开浏览器的Web开发者工具
, 请切换到 控制台(Console)
选项卡):
点击 注册新用户
按钮, 注册成功后,浏览器跳转到后台管理界面, 如下图所示:
注册失败时,或上角显示 注册失败
的提示,同时浏览器的控制台输出相应的异常信息, 如下图所示:
注册成功后,在 leancloud
的应用管理后台 刷新
后可以看到 _User
已经添多了一条记录
实现登录功能
打开文件 src/views/account/pages/Login.vue
, 编辑内容如以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| <template> <el-card shadow="always" class="login-module"> <el-form> <div class="horiz-container form-title"> <span>用户登录</span> <div class="spacer"></div> <span> <router-link to="/"> <i class="fa fa-home fa-lg" aria-hidden="true"></i> </router-link> </span> </div> <el-form-item> <el-input type="text" prefix-icon="fa fa-user-o fa-lg" v-model="username" placeholder="用户名" ></el-input> </el-form-item> <el-form-item> <el-input type="password" prefix-icon="fa fa-lock fa-lg" v-model="password" placeholder="密码" ></el-input> </el-form-item> <el-form-item> <el-button class="full-width" type="primary" @click="login">登录</el-button> </el-form-item> <div class="horiz-container"> <div class="spacer"></div> <router-link to="/password_reset" class="mx-2"> <el-link :underline="false" type="warning">忘记密码</el-link> </router-link> <router-link to="/signup" class="mx-2"> <el-link :underline="false" type="danger">没有账号</el-link> </router-link> </div> </el-form> </el-card> </template>
<script>
import AccountService from "../../../api/service/account_service"; import { Loading } from "element-ui"; export default { name: "Login", data: () => ({ username: "zhangsan", password: "123456", loading: '', }), methods: { async login() { this.showLoading('#login', '正在登录中...');
let response = await AccountService.logIn(this.username, this.password); if (response.status_code == "ok") { const curr = localStorage.getItem("preRoute"); let token = await AccountService.getToken(); localStorage.setItem("token", token); localStorage.setItem("currentUser", this.username); console.log('response.user:', response.user);
if (curr === null || curr === '/' || curr === '/account' || curr === "/login") { this.$router.push({ path: "/dashboard" }); } else { this.$router.push({ path: curr }); } } else { let errorMsg = { "210": "用户名和密码不匹配", "211": "找不到用户", "219":'登录失败次数超过限制,请稍候再试,或者重设密码', "-1": "请求被终止,请检查网络连接状况", }; this.$notify.error({ title: '登录失败', message: errorMsg[response.status_code], showClose: false, }); } this.endLoading(); },
showLoading(targetNode, message) { this.loading = Loading.service({ lock: true, text: message, target: document.querySelector(targetNode), }); },
endLoading() { this.loading.close(); },
getUser(user) { return { id: user.id, username: user.get("username"), email: user.get("email"), }; }, } }; </script>
<style> .login-module { width: 380px; } </style>
|
浏览器进入到登录页面
,输入 用户名
和 密码
登录, 登录不成功,显示相应的错误提示,效果如下图:
登录成功,则进入后台管理 或是自动跳转到登录界面的前一页。
实现通过邮箱找回密码
打开文件 src/views/account/pages/PasswordReset.vue
, 编辑其内容如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| <template> <el-card shadow="always" class="login-module"> <el-form> <div class="horiz-container form-title"> <span>通过邮箱找回密码</span> <div class="spacer"></div> <span> <router-link to="/"> <i class="fa fa-home fa-lg" aria-hidden="true"></i> </router-link> </span> </div> <div v-if="sendEmailSuccess"> <el-alert :title="`请登录 ${this.email} 邮箱进行密码重置`" type="success" effect="dark" center show-icon :closable="false" ></el-alert> </div> <div v-else> <el-form-item> <el-input type="text" prefix-icon="fa fa-envelope-o fa-lg" v-model="email" placeholder="电子邮箱" ></el-input> </el-form-item>
<el-form-item> <el-button class="full-width" type="primary" @click="passwordReset">发送找回密码的邮件</el-button> </el-form-item> <div class="horiz-container"> <div class="spacer"></div> <router-link to="/login" class="link"> <el-link :underline="false" type="success">使用已有账号登录</el-link> </router-link> <router-link to="/signup" class="mx-2"> <el-link :underline="false" type="danger">没有账号</el-link> </router-link> </div> </div> </el-form> </el-card> </template>
<script> import AccountService from "../../../api/service/account_service"; export default { name: "PasswordReset", data: () => ({ email: "", sendEmailSuccess: false, }), methods: { async passwordReset() { let email = this.email.trim(); let response = await AccountService.passwordResetByEmail(email); if (response.status_code == "ok") { this.sendEmailSuccess = true; this.$notify.success({ title: '发送重置密码邮件成功', message: "请查看邮件,以便完成密码重置", showClose: false, });
} else { let errorMsg = { "1": "请不要往同一个邮件地址发送太多邮件", "205": "此电子邮箱没有被注册使用", "-1": "请求被终止,请检查网络连接状况" }; this.$notify.error({ title: '密码重置失败', message: errorMsg[response.status_code], showClose: false, }); } } } }; </script>
<style> .login-module { width: 380px; } </style>
|
浏览器进入到找回密码的界面,填写用户注册时的电子邮箱, 邮箱填写错误,显示相应的提示信息:
填写正确的电子邮箱,发送重置密码邮件,登录到自己的邮箱,即可重置密码:
在后台管理界面显示当前登录用户及注销
打开文件 src/views/dashboard/layout/Header.vue
, 编辑其内容如以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| <template> <div class="lay-header horiz-container"> <router-link to="/"> <el-button type="text">首页</el-button> </router-link> <div class="spacer"></div> <el-link :underline="false" type="success" class="mx-2"> <i class="fa fa-bell fa-lg"></i> 消息 </el-link> <el-link :underline="false" type="danger" class="mx-2"> <i class="fa fa-envelope fa-lg"></i> 邮件 </el-link> <el-link :underline="false" type="primary" class="mx-2" v-if="currentUser" >当前用户: {{ currentUser }}</el-link> <el-link :underline="false" type="danger" class="mx-2" @click="logout">注销</el-link> </div> </template>
<script> import AccountService from "../../../api/service/account_service.js" export default { name: 'LayoutHeader', methods: { async logout() { console.log("logout"); await AccountService.logOut(); if (this.$route.path != "/") { localStorage.removeItem("preRoute"); localStorage.removeItem("token"); this.$router.push("/"); } }, },
computed: { currentUser() { if (localStorage.getItem('token')) { return localStorage.getItem('currentUser') } }, } } </script>
<style> .lay-header { height: 60px; align-items: center; } </style>
|
登录成功后,后台管理页面的右上角显示 当前用户名,并实现用户的注销, 效果如下图所示:
后继内容:
使用 Element UI 和 Leancloud 的 Vue.js 项目开发 VII
===END===