微信小程序+云开发实现欢迎登录注册


Posted in Javascript onMay 24, 2019

前段时间和同学一起做了一个小程序,用来参加学校的比赛,完成后把项目内容分割一下,贴到博客上面,算是学习记录和总结吧。

因为是学生党,而且并没有很大的需要,所以选择了微信小程序为开发者提供的“云开发”选项。

开发者可以使用云开发开发微信小程序、小游戏,无需搭建服务器,即可使用云端能力。
按照微信的说法:

云开发为开发者提供完整的云端支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。
目前提供三大基础能力支持:

  • 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写自身业务逻辑代码
  • 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 数据库
  • 存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理

首先,开通云开发功能是第一步(默认你已经注册好了微信小程序账号而且申请好了一个AppId),经测试,云开发并不能使用测试号,只能使用真实的AppId。

注:AppID 首次开通云环境后,需等待大约 10 分钟方可正常使用云 API,在此期间官方后台服务正在做准备服务,如尝试在小程序中调用云 API 则会报 cloud init error:{ errMsg: “invalid scope” } 的错误

微信小程序+云开发实现欢迎登录注册

之后新建就行了。

新建的项目已经包含了一个快速开发的Demo,而且含有云函数示例,初始化函数等等,最好可以先看看,熟悉一下。

微信小程序+云开发实现欢迎登录注册

首先看一下app.js这个文件:

//app.js
App({
 onLaunch: function () {
if (!wx.cloud) {
 console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
 wx.cloud.init({
traceUser: true,
 })
}
})

wx.cloud.init()为云端环境初始化函数,如果有多个云开发环境则需要指定env参数,如下:

wx.cloud.init({
 env: 'test-x1dzi'
})

具体可以查看官方文档:

developers.weixin.qq.com

接下来声明一些全局数据

//全局数据
globalData: {
  //用户ID
  userId: '',
  //用户信息
  userInfo: null,
  //授权状态
  auth: {
   'scope.userInfo': false
  },
  //登录状态
  logged: false
}

最后的样子是这样:

//app.js
App({
	//全局数据
	globalData: {
  	//用户ID
	  userId: '',
	  //用户信息
	  userInfo: null,
	  //授权状态
	  auth: {
	   'scope.userInfo': false
	  },
	  //登录状态
	  logged: false
	},

	onLaunch: function() {
		if (!wx.cloud) {
			console.error('请使用 2.2.3 或以上的基础库以使用云能力')
		} else {
			wx.cloud.init({
				traceUser: true,
				env: 'winbin-2hand'
			})
		}
	}
})

注意将env参数换成你自己的云开发环境。

把Pages目录下的除index外的文件夹删除。

并且在app.json中的Pages字段中下仅保留index项:

app.json

{
	"pages": [
	"pages/index/index"
	],
	"window": {
		"backgroundColor": "#F6F6F6",
		"backgroundTextStyle": "light",
		"navigationBarBackgroundColor": "#F6F6F6",
		"navigationBarTitleText": "云开发 QuickStart",
		"navigationBarTextStyle": "black",
		"navigationStyle": "custom"
	},
	"sitemapLocation": "sitemap.json"
}

页面文件内容如下:

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>

因为微信小程序声称wx.getUserInfo(Object object)在以后将不再支持,这里使用另一种方式来显示用户的信息。

标签<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({
 /**
  * 页面的初始数据
  */
 data: {
  hiddenButton: true
 },

 /**
  *从云端获取资料
  *如果没有获取到则尝试新建用户资料
  */
 onGotUserInfo: function(e) {
  var _this = this
  //需要用户同意授权获取自身相关信息
  if (e.detail.errMsg == "getUserInfo:ok") {
   //将授权结果写入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 {
       //未成功获取到用户信息
       //调用注册方法
       console.log("未注册")
       _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: '请检查网络您的状态',
      duration: 800,
      icon: 'none'
     })
     console.error("get_setUserInfo调用失败", err.errMsg)
    }
   })
  } else
   console.log("未授权")
 },

 /**
  * 注册用户信息
  */
 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("注册失败", res)
     wx.showToast({
      title: '请检查网络您的状态',
      duration: 800,
      icon: 'none'
     })
    }
   },
   fail: err => {
    wx.showToast({
     title: '请检查网络您的状态',
     duration: 800,
     icon: 'none'
    })
    console.error("get_setUserInfo调用失败", err.errMsg)
   }
  })
 },

 /**
  * 生命周期函数--监听页面加载
  */
 onLoad: function() {
  let _this = this
  //需要用户同意授权获取自身相关信息
  wx.getSetting({
   success: function(res) {
    if (res.authSetting['scope.userInfo']) {
     //将授权结果写入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("未注册")
       }
      },
      fail: err => {
       _this.setData({
        hiddenButton: false
       })
       wx.showToast({
        title: '请检查网络您的状态',
        duration: 800,
        icon: 'none'
       })
       console.error("get_setUserInfo调用失败", err.errMsg)
      }
     })
    } else {
     _this.setData({
      hiddenButton: false
     })
     console.log("未授权")
    }
   },
   fail(err) {
    _this.setData({
     hiddenButton: false
    })
    wx.showToast({
     title: '请检查网络您的状态',
     duration: 800,
     icon: 'none'
    })
    console.error("wx.getSetting调用失败", err.errMsg)
   }
  })
 }
})

下面是云函数配置

根据传入的参数:update ,getSelf ,setSelf ,getOthers

分别执行:更新用户信息,获取自身信息,设置自身信息,获取其他用户信息 四种操作。

此函数需要使用npm添加md5模块,用来加密用户openid并将其存放在数据库中

// 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

// 云函数入口函数
exports.main = async(event, context) => {
 console.log(event)
 const wxContext = cloud.getWXContext()
 //更新当前信息
 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) {
  //获取当前用户信息
  try {
   return await usersTable.doc(md5(wxContext.OPENID)).field({
    openid: false
   }).get()
  } catch (e) {
   console.error(e)
  }
 } else if (event.setSelf == true) {
  //添加当前用户信息
  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)
  }
 }
}

数据库数据形式:

微信小程序+云开发实现欢迎登录注册

至此就全部完成了。有需要的可以到github上查看:github:john-tito

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript 布尔型分析
Dec 22 Javascript
JS高级拖动技术 setCapture,releaseCapture
Jul 31 Javascript
js用Date对象处理时间实现思路及代码
Jan 31 Javascript
js判断FCKeditor内容是否为空的两种形式
May 14 Javascript
jquery操作select详解(取值,设置选中)
Feb 07 Javascript
详解maxlength属性在textarea里奇怪的表现
Dec 27 Javascript
JavaScript中函数声明与函数表达式的区别详解
Aug 18 Javascript
JS实现可编辑的后台管理菜单功能【附demo源码下载】
Sep 13 Javascript
Angular ng-repeat遍历渲染完页面后执行其他操作详细介绍
Dec 13 Javascript
基于javascript的异步编程实例详解
Apr 10 Javascript
node.js支持多用户web终端实现及安全方案
Nov 29 Javascript
vue实现图片懒加载的方法分析
Feb 05 Javascript
30分钟用Node.js构建一个API服务器的步骤详解
May 24 #Javascript
Electron-vue开发的客户端支付收款工具的实现
May 24 #Javascript
JS实现判断数组是否包含某个元素示例
May 24 #Javascript
JS实现查找数组中对象的属性值是否存在示例
May 24 #Javascript
jQuery中使用validate插件校验表单功能
May 24 #jQuery
echarts多条折线图动态分层的实现方法
May 24 #Javascript
Echarts动态加载多条折线图的实现代码
May 24 #Javascript
You might like
php开发工具之vs2005图解
2008/01/12 PHP
php中理解print EOT分界符和echo EOT的用法区别小结
2010/02/21 PHP
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
浅谈PHP中output_buffering
2015/07/13 PHP
php 使用fopen函数创建、打开文件详解及实例代码
2016/09/24 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
laravel 解决Validator使用中出现的问题
2019/10/25 PHP
JavaScript的eval JSON object问题
2009/11/15 Javascript
JQuery浮动DIV提示信息并自动隐藏的代码
2010/08/29 Javascript
myeclipse安装jQuery插件的方法
2011/03/29 Javascript
jQuery 2.0.3 源码分析之core(一)整体架构
2014/05/27 Javascript
Mac OS X 系统下安装和部署Egret引擎开发环境
2014/09/03 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
jQuery的position()方法详解
2015/07/19 Javascript
js实现浏览本地文件并显示扩展名的方法
2015/08/17 Javascript
jQuery easyui的validatebox校验规则扩展及easyui校验框validatebox用法
2016/01/18 Javascript
基于jquery实现二级联动效果
2017/03/30 jQuery
angular+ionic返回上一页并刷新页面
2017/08/08 Javascript
实现两个文本框同时输入的实例
2017/09/25 Javascript
vue之a-table中实现清空选中的数据
2019/11/07 Javascript
Vue elementui字体图标显示问题解决方案
2020/08/18 Javascript
[57:55]EG vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
11个并不被常用但对开发非常有帮助的Python库
2015/03/31 Python
python实现mysql的单引号字符串过滤方法
2015/11/14 Python
详解python之配置日志的几种方式
2017/05/22 Python
解决pyqt5中QToolButton无法使用的问题
2019/06/21 Python
Django实现基于类的分页功能
2019/10/31 Python
利用Python脚本实现自动刷网课
2020/02/03 Python
python是怎么被发明的
2020/06/15 Python
Python爬虫Scrapy框架CrawlSpider原理及使用案例
2020/11/20 Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
2021/01/05 Python
优秀幼教自荐信
2014/02/03 职场文书
小学优秀辅导员事迹材料
2014/05/11 职场文书
争先创优心得体会
2014/09/12 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书
Python实现学生管理系统并生成exe可执行文件详解流程
2022/01/22 Python