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


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 相关文章推荐
dojo 之基础篇(二)之从服务器读取数据
Mar 24 Javascript
Javascript匿名函数的一种应用 代码封装
Jun 27 Javascript
11款新鲜的jQuery插件[附所有demo下载]
Jan 24 Javascript
获得所有表单值的JQuery实现代码[IE暂不支持]
May 24 Javascript
js采用map取到id集合组并且实现点击一行选中一行
Dec 16 Javascript
一个不错的仿携程自定义数据下拉选择select
Sep 01 Javascript
webpack2.0配置postcss-loader的方法
Aug 17 Javascript
微信小程序自定义导航教程(兼容各种手机)
Dec 12 Javascript
详解vue后台系统登录态管理
Apr 02 Javascript
vue中实现Monaco Editor自定义提示功能
Jul 05 Javascript
Webpack 4如何动态切割JS注入文件名详解
Jul 09 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
Nov 06 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
php5中类的学习
2008/03/28 PHP
php heredoc和phpwind的模板技术使用方法小结
2008/03/28 PHP
Ajax PHP 边学边练 之三 数据库
2009/11/26 PHP
PHP判断文件是否被引入的方法get_included_files用法示例
2016/11/29 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
PHP二维数组去重算法
2016/12/17 PHP
jQuery UI 应用不同Theme的办法
2010/09/12 Javascript
jQueryUI如何自定义组件实现代码
2010/11/14 Javascript
event.X和event.clientX的区别分析
2011/10/06 Javascript
JS给Textarea文本框添加行号的方法
2015/08/20 Javascript
JS检测移动端横竖屏的代码
2016/05/30 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
ES6下子组件调用父组件的方法(推荐)
2018/02/23 Javascript
javascript中call()、apply()的区别
2019/03/21 Javascript
WebSocket的简单介绍及应用
2019/05/23 Javascript
微信小程序全局变量GLOBALDATA的定义和调用过程解析
2019/09/23 Javascript
Python版实现微信公众号扫码登陆
2020/05/28 Javascript
js实现查询商品案例
2020/07/22 Javascript
vue3自定义dialog、modal组件的方法
2021/01/04 Vue.js
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
selenium在执行phantomjs的API并获取执行结果的方法
2018/12/17 Python
python使用pandas处理excel文件转为csv文件的方法示例
2019/07/18 Python
django多个APP的urls设置方法(views重复问题解决)
2019/07/19 Python
利用Python脚本批量生成SQL语句
2020/03/04 Python
解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程
2020/03/10 Python
python怎么判断素数
2020/07/01 Python
Python selenium模块实现定位过程解析
2020/07/09 Python
Python 处理日期时间的Arrow库使用
2020/08/18 Python
全球速卖通法国在线交易平台:AliExpress法国
2017/07/07 全球购物
专科毕业生求职简历的自我评价
2013/10/12 职场文书
记者岗位职责
2014/01/06 职场文书
学生实习介绍信
2014/01/15 职场文书
销售员态度差检讨书
2014/10/26 职场文书
服务员态度差检讨书
2014/10/28 职场文书
浅谈如何提高PHP代码质量之单元测试
2021/05/28 PHP
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis