微信小程序+云開發(fā)實(shí)現(xiàn)歡迎登錄注冊(cè)
前段時(shí)間和同學(xué)一起做了一個(gè)小程序,用來參加學(xué)校的比賽,完成后把項(xiàng)目內(nèi)容分割一下,貼到博客上面,算是學(xué)習(xí)記錄和總結(jié)吧。
因?yàn)槭菍W(xué)生黨,而且并沒有很大的需要,所以選擇了微信小程序?yàn)殚_發(fā)者提供的“云開發(fā)”選項(xiàng)。
開發(fā)者可以使用云開發(fā)開發(fā)微信小程序、小游戲,無需搭建服務(wù)器,即可使用云端能力。
按照微信的說法:
云開發(fā)為開發(fā)者提供完整的云端支持,弱化后端和運(yùn)維概念,無需搭建服務(wù)器,使用平臺(tái)提供的 API 進(jìn)行核心業(yè)務(wù)開發(fā),即可實(shí)現(xiàn)快速上線和迭代,同時(shí)這一能力,同開發(fā)者已經(jīng)使用的云服務(wù)相互兼容,并不互斥。
目前提供三大基礎(chǔ)能力支持:
- 云函數(shù):在云端運(yùn)行的代碼,微信私有協(xié)議天然鑒權(quán),開發(fā)者只需編寫自身業(yè)務(wù)邏輯代碼
- 數(shù)據(jù)庫:一個(gè)既可在小程序前端操作,也能在云函數(shù)中讀寫的 JSON 數(shù)據(jù)庫
- 存儲(chǔ):在小程序前端直接上傳/下載云端文件,在云開發(fā)控制臺(tái)可視化管理
首先,開通云開發(fā)功能是第一步(默認(rèn)你已經(jīng)注冊(cè)好了微信小程序賬號(hào)而且申請(qǐng)好了一個(gè)AppId),經(jīng)測(cè)試,云開發(fā)并不能使用測(cè)試號(hào),只能使用真實(shí)的AppId。
注:AppID 首次開通云環(huán)境后,需等待大約 10 分鐘方可正常使用云 API,在此期間官方后臺(tái)服務(wù)正在做準(zhǔn)備服務(wù),如嘗試在小程序中調(diào)用云 API 則會(huì)報(bào) cloud init error:{ errMsg: “invalid scope” } 的錯(cuò)誤
之后新建就行了。
新建的項(xiàng)目已經(jīng)包含了一個(gè)快速開發(fā)的Demo,而且含有云函數(shù)示例,初始化函數(shù)等等,最好可以先看看,熟悉一下。
首先看一下app.js這個(gè)文件:
//app.js App({ onLaunch: function () { if (!wx.cloud) { console.error('請(qǐng)使用 2.2.3 或以上的基礎(chǔ)庫以使用云能力') } else { wx.cloud.init({ traceUser: true, }) } })
wx.cloud.init()為云端環(huán)境初始化函數(shù),如果有多個(gè)云開發(fā)環(huán)境則需要指定env參數(shù),如下:
wx.cloud.init({ env: 'test-x1dzi' })
具體可以查看官方文檔:
接下來聲明一些全局?jǐn)?shù)據(jù)
//全局?jǐn)?shù)據(jù) globalData: { //用戶ID userId: '', //用戶信息 userInfo: null, //授權(quán)狀態(tài) auth: { 'scope.userInfo': false }, //登錄狀態(tài) logged: false }
最后的樣子是這樣:
//app.js App({ //全局?jǐn)?shù)據(jù) globalData: { //用戶ID userId: '', //用戶信息 userInfo: null, //授權(quán)狀態(tài) auth: { 'scope.userInfo': false }, //登錄狀態(tài) logged: false }, onLaunch: function() { if (!wx.cloud) { console.error('請(qǐng)使用 2.2.3 或以上的基礎(chǔ)庫以使用云能力') } else { wx.cloud.init({ traceUser: true, env: 'winbin-2hand' }) } } })
注意將env參數(shù)換成你自己的云開發(fā)環(huán)境。
把Pages目錄下的除index外的文件夾刪除。
并且在app.json中的Pages字段中下僅保留index項(xiàng):
app.json
{ "pages": [ "pages/index/index" ], "window": { "backgroundColor": "#F6F6F6", "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#F6F6F6", "navigationBarTitleText": "云開發(fā) QuickStart", "navigationBarTextStyle": "black", "navigationStyle": "custom" }, "sitemapLocation": "sitemap.json" }
頁面文件內(nèi)容如下:
index.wxml
<view class='container'> <open-data class="avs" type="userAvatarUrl"></open-data> <view class='username'> <text>Hello </text> <open-data type="userNickName"></open-data> </view> <button hidden='{{hiddenButton}}' class='moto-container' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="onGotUserInfo"> <text class='moto'> 開啟小程序之旅</text> </button> </view>
因?yàn)槲⑿判〕绦蚵暦Qwx.getUserInfo(Object object)在以后將不再支持,這里使用另一種方式來顯示用戶的信息。
標(biāo)簽<open-data type=""></open-data>
可以用來顯示用戶的一些信息
<open-data type="userAvatarUrl"></open-data>
顯示用戶的頭像
<open-data type="userNickName"></open-data>
顯示用戶的昵稱
詳情可以查看:wx.getUserInfo中的示例代碼部分
頁面樣式如下:
index.wxss
page { width: 100%; height: 100%; } .container { background: url('https://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-758991.png'); background-size: 400vw 100vh; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; } .avs { opacity: 0.9; width: 200rpx; height: 200rpx; margin-top: 160rpx; } .username { font-size: 32rpx; font-weight: bold; margin-top: 200rpx; } .moto-container { line-height: normal; border: 1px solid #450f80; width: 200rpx; height: 80rpx; border-radius: 5px; text-align: center; margin-top: 200rpx; padding: 0px; outline: none; } .moto { font-size: 22rpx; font-weight: bold; line-height: 80rpx; text-align: center; color: #450f80; }
這里使用了全屏背景
效果如下:
#接下來是js腳本#
首先說一下思路
流程圖如下
接下來是index.js
const app = getApp(); Page({ /** * 頁面的初始數(shù)據(jù) */ data: { hiddenButton: true }, /** *從云端獲取資料 *如果沒有獲取到則嘗試新建用戶資料 */ onGotUserInfo: function(e) { var _this = this //需要用戶同意授權(quán)獲取自身相關(guān)信息 if (e.detail.errMsg == "getUserInfo:ok") { //將授權(quán)結(jié)果寫入app.js全局變量 app.globalData.auth['scope.userInfo'] = true //嘗試獲取云端用戶信息 wx.cloud.callFunction({ name: 'get_setUserInfo', data: { getSelf: true }, success: res => { if (res.errMsg == "cloud.callFunction:ok") if (res.result) { //如果成功獲取到 //將獲取到的用戶資料寫入app.js全局變量 console.log(res) app.globalData.userInfo = res.result.data.userData app.globalData.userId = res.result.data._id wx.switchTab({ url: '/pages/home/home' }) } else { //未成功獲取到用戶信息 //調(diào)用注冊(cè)方法 console.log("未注冊(cè)") _this.register({ nickName: e.detail.userInfo.nickName, gender: e.detail.userInfo.gender, avatarUrl: e.detail.userInfo.avatarUrl, region: ['none', 'none', 'none'], campus: "none", studentNumber: "none", }) } }, fail: err => { wx.showToast({ title: '請(qǐng)檢查網(wǎng)絡(luò)您的狀態(tài)', duration: 800, icon: 'none' }) console.error("get_setUserInfo調(diào)用失敗", err.errMsg) } }) } else console.log("未授權(quán)") }, /** * 注冊(cè)用戶信息 */ register: function(e) { let _this = this wx.cloud.callFunction({ name: 'get_setUserInfo', data: { setSelf: false, userData: e }, success: res => { if (res.errMsg == "cloud.callFunction:ok" && res.result) { _this.setData({ hiddenButton: true }) app.globalData.userInfo = e app.globalData.userId = res.result._id _this.data.registered = true app.getLoginState() console.log(res) wx.navigateTo({ url: '/pages/mine/info/info' }) } else { console.log("注冊(cè)失敗", res) wx.showToast({ title: '請(qǐng)檢查網(wǎng)絡(luò)您的狀態(tài)', duration: 800, icon: 'none' }) } }, fail: err => { wx.showToast({ title: '請(qǐng)檢查網(wǎng)絡(luò)您的狀態(tài)', duration: 800, icon: 'none' }) console.error("get_setUserInfo調(diào)用失敗", err.errMsg) } }) }, /** * 生命周期函數(shù)--監(jiān)聽頁面加載 */ onLoad: function() { let _this = this //需要用戶同意授權(quán)獲取自身相關(guān)信息 wx.getSetting({ success: function(res) { if (res.authSetting['scope.userInfo']) { //將授權(quán)結(jié)果寫入app.js全局變量 app.globalData.auth['scope.userInfo'] = true //從云端獲取用戶資料 wx.cloud.callFunction({ name: 'get_setUserInfo', data: { getSelf: true }, success: res => { if (res.errMsg == "cloud.callFunction:ok" && res.result) { //如果成功獲取到 //將獲取到的用戶資料寫入app.js全局變量 console.log(res) app.globalData.userInfo = res.result.data.userData app.globalData.userId = res.result.data._id wx.switchTab({ url: '/pages/home/home' }) } else { _this.setData({ hiddenButton: false }) console.log("未注冊(cè)") } }, fail: err => { _this.setData({ hiddenButton: false }) wx.showToast({ title: '請(qǐng)檢查網(wǎng)絡(luò)您的狀態(tài)', duration: 800, icon: 'none' }) console.error("get_setUserInfo調(diào)用失敗", err.errMsg) } }) } else { _this.setData({ hiddenButton: false }) console.log("未授權(quán)") } }, fail(err) { _this.setData({ hiddenButton: false }) wx.showToast({ title: '請(qǐng)檢查網(wǎng)絡(luò)您的狀態(tài)', duration: 800, icon: 'none' }) console.error("wx.getSetting調(diào)用失敗", err.errMsg) } }) } })
下面是云函數(shù)配置
根據(jù)傳入的參數(shù):update ,getSelf ,setSelf ,getOthers
分別執(zhí)行:更新用戶信息,獲取自身信息,設(shè)置自身信息,獲取其他用戶信息 四種操作。
此函數(shù)需要使用npm添加md5模塊,用來加密用戶openid并將其存放在數(shù)據(jù)庫中
// clouldfunctions/get_setUserInfo/package.json { "name": "get_setUserInfo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "wx-server-sdk": "latest", "md5-node": "latest" } }
// clouldfunctions/get_setUserInfo/index.js const cloud = require('wx-server-sdk') const md5 = require('md5-node') //cloud.init() cloud.init({ traceUser: true, env: 'winbin-2hand' }) const db = cloud.database() const usersTable = db.collection("users") const _ = db.command // 云函數(shù)入口函數(shù) exports.main = async(event, context) => { console.log(event) const wxContext = cloud.getWXContext() //更新當(dāng)前信息 if (event.update == true) { try { return await usersTable.doc(md5(wxContext.OPENID)).update({ data: { userData: _.set(event.userData) }, }) } catch (e) { console.error(e) } } else if (event.getSelf == true) { //獲取當(dāng)前用戶信息 try { return await usersTable.doc(md5(wxContext.OPENID)).field({ openid: false }).get() } catch (e) { console.error(e) } } else if (event.setSelf == true) { //添加當(dāng)前用戶信息 try { return await usersTable.add({ data: { _id: md5(wxContext.OPENID), openid: wxContext.OPENID, userData: event.userData, boughtList: [], messageList: [], ontransList: [] } }) } catch (e) { console.error(e) } } else if (event.getOthers == true) { //獲取指定用戶信息 try { return await usersTable.doc(event.userId).field({ userData: true }).get() } catch (e) { console.error(e) } } }
數(shù)據(jù)庫數(shù)據(jù)形式:
至此就全部完成了。有需要的可以到github上查看:github:john-tito
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 微信小程序登錄與注冊(cè)功能的實(shí)現(xiàn)詳解
- 微信小程序?qū)崿F(xiàn)登錄注冊(cè)功能
- 詳解微信小程序入門從這里出發(fā)(登錄注冊(cè)、開發(fā)工具、文件及結(jié)構(gòu)介紹)
- 微信小程序?qū)崿F(xiàn)注冊(cè)登錄功能(表單校驗(yàn)、錯(cuò)誤提示)
- 微信小程序登錄態(tài)和檢驗(yàn)注冊(cè)過沒的app.js寫法
- 微信小程序?qū)崿F(xiàn)登錄注冊(cè)tab切換效果
- 微信小程序?qū)崿F(xiàn)登錄界面示例
- 微信小程序?qū)崿F(xiàn)登錄界面
- 微信小程序?qū)崿F(xiàn)登錄注冊(cè)界面
相關(guān)文章
Javascript new關(guān)鍵字的玄機(jī) 以及其它
本人是Javascript菜鳥,下面是前幾天學(xué)習(xí)Javascript的旅程心得,希望對(duì)和我一樣的入門者有點(diǎn)用,也希望高手批評(píng)指正。2010-08-08純JS實(shí)現(xiàn)圖片驗(yàn)證碼功能并兼容IE6-8(推薦)
這篇文章主要介紹了純JS實(shí)現(xiàn)圖片驗(yàn)證碼功能并兼容IE6-8瀏覽器,需要的朋友可以參考下2017-04-04JavaScript與jQuery中文檔就緒函數(shù)的區(qū)別
這篇文章主要介紹了JavaScript與jQuery中文檔就緒函數(shù)的區(qū)別,文章內(nèi)容介紹詳細(xì),具有一的的參考價(jià)值,需要的小伙伴可以參考一下2022-03-03js自動(dòng)生成的元素與頁面原有元素發(fā)生堆疊的解決方法
js自動(dòng)生成的元素與頁面原有元素發(fā)生堆疊通過去除浮動(dòng),給原有元素(商品擴(kuò)展信息部分)加上clear:both; 果然正常了2013-10-10QT與javascript交互數(shù)據(jù)的實(shí)現(xiàn)
本文主要介紹了QT與javascript交互數(shù)據(jù)的實(shí)現(xiàn),主要包括數(shù)據(jù)從QT流向JS以及數(shù)據(jù)從JS流向QT的幾種方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05JS實(shí)現(xiàn)單擊輸入框彈出選擇框效果完整實(shí)例
這篇文章主要介紹了JS實(shí)現(xiàn)單擊輸入框彈出選擇框效果的方法,涉及JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)操作頁面元素與相關(guān)屬性的實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-12-12