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


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-Mozilla和IE中的一个函数直接量的问题
Jan 09 Javascript
javascript 特殊字符串
Feb 25 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
Aug 24 Javascript
jQuery布局插件UI Layout简介及使用方法
Apr 03 Javascript
javascript 寻找错误方法整理
Jun 15 Javascript
node.js操作mongoDB数据库示例分享
Nov 26 Javascript
用Move.js配合创建CSS3动画的入门指引
Jul 22 Javascript
分享Javascript实用方法二
Dec 13 Javascript
Bootstrap实现渐变顶部固定自适应导航栏
Aug 27 Javascript
JS实现上传图片的三种方法并实现预览图片功能
Jul 14 Javascript
vue仿淘宝订单状态的tab切换效果
Jun 23 Javascript
jQuery实现鼠标响应式淘宝动画效果示例
Feb 13 jQuery
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
JAVA/JSP学习系列之七
2006/10/09 PHP
在PHP中使用灵巧的体系结构
2006/10/09 PHP
php与java通过socket通信的实现代码
2013/10/21 PHP
thinkphp的URL路由规则与配置实例
2014/11/26 PHP
thinkPHP5框架设置404、403等http状态页面的方法
2018/06/05 PHP
php基于 swoole 实现的异步处理任务功能示例
2019/08/13 PHP
JQery 渐变图片导航效果代码 漂亮
2010/01/01 Javascript
Javascript的表单验证-提交表单
2016/03/18 Javascript
javascript和jquery实现用户登录验证
2016/05/04 Javascript
js中使用使用原型(prototype)定义方法的好处详解
2016/07/04 Javascript
JS 中可以提升幸福度的小技巧(可以识别更多另类写法)
2018/07/28 Javascript
JavaScript自动生成 年月范围 选择功能完整示例【基于jQuery插件】
2019/09/03 jQuery
javascrpt密码强度校验函数详解
2020/03/18 Javascript
WebStorm中如何将自己的代码上传到github示例详解
2020/10/28 Javascript
Python3 能振兴 Python的原因分析
2014/11/28 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
使用Kivy将python程序打包为apk文件
2017/07/29 Python
python实现AES加密解密
2019/03/28 Python
python时间序列按频率生成日期的方法
2019/05/14 Python
django数据库自动重连的方法实例
2019/07/21 Python
pytorch中如何使用DataLoader对数据集进行批处理的方法
2019/08/06 Python
弄懂这56个Python使用技巧(轻松掌握Python高效开发)
2019/09/18 Python
jupyter notebook 实现matplotlib图动态刷新
2020/04/22 Python
Python无损压缩图片的示例代码
2020/08/06 Python
matplotlib自定义鼠标光标坐标格式的实现
2021/01/08 Python
HTML5网页录音和上传到服务器支持PC、Android,支持IOS微信功能
2019/04/26 HTML / CSS
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
学习党章思想汇报
2014/01/07 职场文书
运动会广播稿20字
2014/02/18 职场文书
出生证明公证书
2014/04/09 职场文书
党的群众路线教育实践活动个人承诺书
2014/05/22 职场文书
四风剖析查摆对照检查材料思想汇报
2014/09/24 职场文书
铅球加油稿100字
2014/09/26 职场文书
教你用Python matplotlib库制作简单的动画
2021/06/11 Python
Python基于百度API识别并提取图片中文字
2021/06/27 Python
MySQL创建管理KEY分区
2022/04/13 MySQL