Open FrankFang opened 7 years ago
cp -r step-3 step-4 cd step-4 webpack --watch #然后新开窗口写代码,这个不要关
上个任务中,我们的数据存在 localStorage 中,这样有很多弊端:
所以,我们是不是应该买一台服务器来存所有用户的数据?
可以,但是服务器是要钱的,我们现在还没必要花这个钱。
没有服务器能不能存数据呢? 答案是「不能,但是又能」。
说「不能」是因为无论如何,我们都需要一个地方存数据。 说「能」是因为我们不用自己买服务器。
今天我们使用 LeanCloud 的免费服务来存储我们的所有数据。
你需要去 https://leancloud.cn 创建一个账户。
创建成功后,你需要验证你的邮箱,否则无法创建应用。
如下图操作:
创建成功后就放在那里,因为接下来我们要按照 LeanCloud 的「JavaScript SDK 文档」来开发登录、注册功能。
首先还是用 HTML 把界面做出来。
目前我们的页面的结构是
div#app > div.newTask + ol.todos
我们要改成
div#app section#signInAndSignUp section#todo div.newTask + ol.todos
用一个 section#todo 将原有内容包起来,然后新建一个 section#signInAndSignUp(注意大小写)
最终结果是:
<div id="app"> <section id="signInAndSignUp"> <div> <label><input type="radio" name="type" value="signUp">注册</label> <label><input type="radio" name="type" value="login">登入</label> </div> <div class="signUp"> <form> <div class="formRow"> 用户名<input type="text"> </div> <div class="formRow"> 密码<input type="password"> </div> <div class="formActions"> <input type="submit" value="注册"> </div> </form> </div> <div class="login"> <form> <div class="formRow"> 用户名<input type="text"> </div> <div class="formRow"> 密码<input type="password"> </div> <div class="formActions"> <input type="submit" value="登入"> </div> </form> </div> </section> <section id="todo"> <div class="newTask"> <input type="text" v-model="newTodo" @keypress.enter="addTodo"> </div> <ol class="todos"> <li v-for="todo in todoList"> <input type="checkbox" v-model="todo.done"> {{ todo.title }} <span v-if="todo.done">已完成</span> <span v-else>未完成</span> <button @click="removeTodo(todo)">X</button> </li> </ol> </section> </div>
预览图:
我们希望
所以我们需要加一个变量,叫做 actionType,它有两个取值:'signUp' 和 'login',都是字符串。
app.js
... el: '#app', data: { actionType: 'signUp', ...
然后将 actionType 与 radio button 绑定(使用 v-model):
<section id="signInAndSignUp"> <div> <label><input type="radio" name="type" v-model="actionType" value="signUp">注册</label> <label><input type="radio" name="type" v-model="actionType" value="login">登入</label> </div> ...
最后让两个表单根据 actionType 来显示和隐藏(注意单引号,为什么要加单引号呢?想想):
<div class="signUp" v-if="actionType=='signUp'"> <form> <div class="formRow"> 用户名<input type="text"> </div> <div class="formRow"> 密码<input type="password"> </div> <div class="formActions"> <input type="submit" value="注册"> </div> </form> </div> <div class="login" v-if="actionType=='login'"> <form> <div class="formRow"> 用户名<input type="text"> </div> <div class="formRow"> 密码<input type="password"> </div> <div class="formActions"> <input type="submit" value="登入"> </div> </form> </div>
这样一来,用户点击 radio button 时就会改变 actionType 的值,actionType 的值一变,两个表单就会一个隐藏,一个显示。
要实现注册功能,首先我们要用数据来表达表单里的每个字段。
data: { actionType: 'signUp', formData: { username: '', password: '' },
然后将 input 与数据绑定起来,另外还要绑定 form 的 submit 事件:
<div class="signUp" v-if="actionType === 'signUp'"> <form @submit.prevent=signUp> <!--👈--> <div class="formRow"> 用户名<input type="text" v-model="formData.username"> <!--👈--> </div> <div class="formRow"> 密码<input type="password" v-model="formData.password"> <!--👈--> </div> <div class="formActions"> <input type="submit" value="注册"> </div> </form> </div>
接下来我们来完善 signUp 的逻辑。在写代码之前,我们需要阅读 leanCloud 的文档:
npm install leancloud-storage --save
初始化 https://leancloud.cn/docs/sdk_setup-js.html#初始化 app.js
import Vue from 'vue' import AV from 'leancloud-storage' var APP_ID = '8axnRtGoxCJhEzsvNPEAHnol-gzGzoHsz'; var APP_KEY = '0YH4XkYflb4CUPfA743TGj8G'; AV.init({ appId: APP_ID, appKey: APP_KEY }); var app = new Vue({ ...
验证 LeanCloud SDK 安装成功 https://leancloud.cn/docs/sdk_setup-js.html#验证
... AV.init({ appId: APP_ID, appKey: APP_KEY }); var TestObject = AV.Object.extend('TestObject'); var testObject = new TestObject(); testObject.save({ words: 'Hello World!' }).then(function(object) { alert('LeanCloud Rocks!'); }) var app = new Vue({ ...
刷新 page.html 后看到 如果可以用 AV 对象了,然后把上面的验证代码删掉。
接下来我们看 LeanCloud 关于注册的文档,如果你看不懂,可以使用我们的「copy-run-modify」套路。按照文档的例子,我们写出这样的代码:
methods: { addTodo: function(){ ... }, removeTodo: function(todo){ ... }, signUp: function () { let user = new AV.User(); user.setUsername(this.formData.username); user.setPassword(this.formData.password); user.signUp().then(function (loginedUser) { console.log(loginedUser); }, function (error) { }); } }
刷新页面,我们选择注册,然后用户名填入「123123」,密码填入「123123」,先别急着提交,打开开发者工具,切到 Network,然后提交:
你会看到发了两个请求到 LeanCloud 的服务器,这两个请求就是向 LeanCloud 的服务器存入用户名和密码。 然后再切到 console,你会看到打印出的 loginedUser:
这里我们只关注它的三个属性:attributes, createdAt, id。
其中 attributes 就是我们传给数据库的 username(我们不是还传了一个 password 吗?服务器是不会把 password 传给前端的)
createdAt 是这个数据创建的时间,id 是用户的 id,也是我们区别用户的唯一凭据。
好了,到此为止,我们的注册功能已经做好了。是不是很简单。 目前的代码快照在这里:https://github.com/jirengu-inc/jrg-project-5/blob/a2690c8efe55262e7850ca3e807fa4852198ffd5/step-4/app.js
你到 LeanCloud 的 控制面板 点击「存储」,然后点击「_User」就能看到这个用户的数据了:
注册做完了接下来是登入,步骤也差不多。
首先绑定数据,我们复用注册的 formData 这个数据,因为
<div class="login" v-if="actionType === 'login'"> <form @submit.prevent="login"> <!--👈--> <div class="formRow"> 用户名<input type="text" v-model="formData.username"> <!--👈--> </div> <div class="formRow"> 密码<input type="password" v-model="formData.password"> <!--👈--> </div> <div class="formActions"> <input type="submit" value="登入"> </div> </form> </div>
然后看一下 LeanCloud 文档,这次大家自己找文档,找不到就用 Google 搜,你会找到的。 看懂文档你就可以添加 login 这个方法了:
signUp: function () { let user = new AV.User(); user.setUsername(this.formData.username); user.setPassword(this.formData.password); user.signUp().then(function (loginedUser) { console.log(loginedUser); }, function (error) { }); }, login: function () { AV.User.logIn(this.formData.username, this.formData.password).then(function (loginedUser) { console.log(loginedUser); }, function (error) { }); }
接下来刷新 page.html,选中「登入」,输入用户名「123123」,密码「123123」。 观察 network 和 console,会得到跟注册类似的结果。
好了,登录功能就完成了。
那么我们如何判断用户是否已登录。
LeanCloud 文档说 AV.User.current() 可以获取当前登录的用户。那么我们这么做:
data: { ... todoList: [], currentUser: null, // 👈 },
signUp: function () { let user = new AV.User(); user.setUsername(this.formData.username); user.setPassword(this.formData.password); user.signUp().then((loginedUser) => { // 👈,将 function 改成箭头函数,方便使用 this this.currentUser = this.getCurrentUser() // 👈 }, (error) => { alert('注册失败') // 👈 }); }, login: function () { AV.User.logIn(this.formData.username, this.formData.password).then((loginedUser) => { // 👈 this.currentUser = this.getCurrentUser() // 👈 }, function (error) { alert('登录失败') // 👈 }); }, getCurrentUser: function () { // 👈 let {id, createdAt, attributes: {username}} = AV.User.current() // 上面这句话看不懂就得看 MDN 文档了 // 我的《ES 6 新特性列表》里面有链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment return {id, username, createdAt} // 看文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Object_initializer#ECMAScript_6%E6%96%B0%E6%A0%87%E8%AE%B0 }
page.html
<section id="signInAndSignUp" v-if="!currentUser"> ... <section id="todo" v-if="currentUser">
然后刷新 page.html ,登录之后,登录表单就不见啦。
后面的功能我写教程写不动了,大家看我的 commit
添加登出功能 如果用户已经登入,就直接展示 todo
搞定上面的教程,满足以下功能:
预览地址:https://jirengu-inc.github.io/jrg-project-5/step-4/page.html 代码:看本仓库的 step-4 目录
代码 预览
我们需要一台服务器吗?
上个任务中,我们的数据存在 localStorage 中,这样有很多弊端:
所以,我们是不是应该买一台服务器来存所有用户的数据?
可以,但是服务器是要钱的,我们现在还没必要花这个钱。
No Backend(无后台)
没有服务器能不能存数据呢? 答案是「不能,但是又能」。
说「不能」是因为无论如何,我们都需要一个地方存数据。 说「能」是因为我们不用自己买服务器。
今天我们使用 LeanCloud 的免费服务来存储我们的所有数据。
创建 LeanCloud 账户
你需要去 https://leancloud.cn 创建一个账户。
创建成功后,你需要验证你的邮箱,否则无法创建应用。
创建 resumer 应用
如下图操作:
创建成功后就放在那里,因为接下来我们要按照 LeanCloud 的「JavaScript SDK 文档」来开发登录、注册功能。
登录和注册
首先还是用 HTML 把界面做出来。
页面分区
目前我们的页面的结构是
我们要改成
用一个 section#todo 将原有内容包起来,然后新建一个 section#signInAndSignUp(注意大小写)
最终结果是:
预览图:
Tab 切换
我们希望
所以我们需要加一个变量,叫做 actionType,它有两个取值:'signUp' 和 'login',都是字符串。
app.js
然后将 actionType 与 radio button 绑定(使用 v-model):
最后让两个表单根据 actionType 来显示和隐藏(注意单引号,为什么要加单引号呢?想想):
这样一来,用户点击 radio button 时就会改变 actionType 的值,actionType 的值一变,两个表单就会一个隐藏,一个显示。
注册
要实现注册功能,首先我们要用数据来表达表单里的每个字段。
然后将 input 与数据绑定起来,另外还要绑定 form 的 submit 事件:
接下来我们来完善 signUp 的逻辑。在写代码之前,我们需要阅读 leanCloud 的文档:
初始化 https://leancloud.cn/docs/sdk_setup-js.html#初始化 app.js
验证 LeanCloud SDK 安装成功 https://leancloud.cn/docs/sdk_setup-js.html#验证
刷新 page.html 后看到 如果可以用 AV 对象了,然后把上面的验证代码删掉。
接下来我们看 LeanCloud 关于注册的文档,如果你看不懂,可以使用我们的「copy-run-modify」套路。按照文档的例子,我们写出这样的代码:
刷新页面,我们选择注册,然后用户名填入「123123」,密码填入「123123」,先别急着提交,打开开发者工具,切到 Network,然后提交:
你会看到发了两个请求到 LeanCloud 的服务器,这两个请求就是向 LeanCloud 的服务器存入用户名和密码。 然后再切到 console,你会看到打印出的 loginedUser:
这里我们只关注它的三个属性:attributes, createdAt, id。
其中 attributes 就是我们传给数据库的 username(我们不是还传了一个 password 吗?服务器是不会把 password 传给前端的)
createdAt 是这个数据创建的时间,id 是用户的 id,也是我们区别用户的唯一凭据。
好了,到此为止,我们的注册功能已经做好了。是不是很简单。 目前的代码快照在这里:https://github.com/jirengu-inc/jrg-project-5/blob/a2690c8efe55262e7850ca3e807fa4852198ffd5/step-4/app.js
去数据库看看这个用户
你到 LeanCloud 的 控制面板 点击「存储」,然后点击「_User」就能看到这个用户的数据了:
登入
注册做完了接下来是登入,步骤也差不多。
首先绑定数据,我们复用注册的 formData 这个数据,因为
然后看一下 LeanCloud 文档,这次大家自己找文档,找不到就用 Google 搜,你会找到的。 看懂文档你就可以添加 login 这个方法了:
接下来刷新 page.html,选中「登入」,输入用户名「123123」,密码「123123」。 观察 network 和 console,会得到跟注册类似的结果。
好了,登录功能就完成了。
登录前后
我们希望
那么我们如何判断用户是否已登录。
LeanCloud 文档说 AV.User.current() 可以获取当前登录的用户。那么我们这么做:
app.js
app.js
page.html
然后刷新 page.html ,登录之后,登录表单就不见啦。
其他功能
后面的功能我写教程写不动了,大家看我的 commit
添加登出功能 如果用户已经登入,就直接展示 todo
致饥人谷学员
搞定上面的教程,满足以下功能:
挑战
预览地址:https://jirengu-inc.github.io/jrg-project-5/step-4/page.html 代码:看本仓库的 step-4 目录