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


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 相关文章推荐
JS Range HTML文档/文字内容选中、库及应用介绍
May 12 Javascript
Javascript 面向对象(二)封装代码
May 23 Javascript
javascript ajax 仿百度分页函数
Oct 29 Javascript
中止javascript执行的方法
Feb 14 Javascript
按Enter键触发事件的jquery方法实现代码
Feb 17 Javascript
使用BootStrap实现悬浮窗口的效果
Dec 13 Javascript
angularjs的select使用及默认选中设置
Apr 08 Javascript
使用JavaScript进行表单校验功能
Aug 01 Javascript
基于Vue 2.0 监听文本框内容变化及ref的使用说明介绍
Aug 24 Javascript
vue-cli 3.x 修改dist路径的方法
Sep 19 Javascript
vue实现PC端录音功能的实例代码
Jun 05 Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
May 28 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
Syphon 秘笈
2021/03/03 冲泡冲煮
解析php dirname()与__FILE__常量的应用
2013/06/24 PHP
php实现的常见排序算法汇总
2014/09/08 PHP
利用PHP判断文件是否为图片的方法总结
2017/01/06 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
PHP7移除的扩展和SAPI
2021/03/09 PHP
jQuery 操作option的实现代码
2011/03/03 Javascript
js点击更换背景颜色或图片的实例代码
2013/06/25 Javascript
jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
2013/12/02 Javascript
jquery鼠标停止移动事件
2013/12/21 Javascript
浅析webapp框架AngularUI的demo
2014/12/21 Javascript
如何使用HTML5地理位置定位功能
2015/04/27 Javascript
使用jquery实现仿百度自动补全特效
2015/07/23 Javascript
jQuery文本框得到与失去焦点动态改变样式效果
2016/09/08 Javascript
ES6中Generator与异步操作实例分析
2017/03/31 Javascript
angularjs 缓存的使用详解
2018/03/19 Javascript
JS拖拽排序插件Sortable.js用法实例分析
2019/02/20 Javascript
微信小程序进入广告实现代码实例
2019/09/19 Javascript
利用Python实现Windows定时关机功能
2017/03/21 Python
python生成特定分布数的实例
2019/12/05 Python
python类中super() 的使用解析
2019/12/19 Python
Python Tkinter Entry和Text的添加与使用详解
2020/03/04 Python
Python3内置函数chr和ord实现进制转换
2020/06/05 Python
SheIn俄罗斯:时尚女装网上商店
2017/02/28 全球购物
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
澳大利亚网上书店:QBD
2021/01/09 全球购物
类如何去实现接口
2013/12/19 面试题
电气自动化大学生求职信
2013/10/16 职场文书
感恩节活动方案
2014/01/27 职场文书
中专毕业生自我鉴定
2014/02/02 职场文书
《巨人的花园》教学反思
2014/02/12 职场文书
爱国卫生月实施方案
2014/02/21 职场文书
同学毕业留言寄语
2015/02/27 职场文书
中学政教处工作总结
2015/08/13 职场文书
Dubbo+zookeeper搭配分布式服务的过程详解
2022/04/03 Java/Android
Java无向树分析 实现最小高度树
2022/04/09 Javascript