微信小程序实战之获取用户信息并保存唯一实例

news2024/11/9 1:00:46

前言

这是我参加掘金启航计划的第二篇文章,这次总结的是获取用户信息并联合 mobx 状态管理库,保存全局唯一的用户对象。

本篇文章基于 微信云开发 ,数据从云数据库中取出,使用微信云数据库API进行获取数据,希望观众老爷们多多支持!

1. 获取用户的openid

我们需要获取微信用户的 openid ,通过 openid 获取用户的登录信息。

首先我们需要创建云函数,选中 cloudfunctions 文件夹,右键选择新建 Node.js 云函数,命名为 gitOpenId

然后在该文件夹下的 index.js 中填写以下内容:

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {const wxContext = cloud.getWXContext()return {event,openid: wxContext.OPENID,appid: wxContext.APPID,unionid: wxContext.UNIONID,}
} 

然后进行选中 gitOpenId 文件夹,右键选择上传并部署即可:

然后打开 app.js,在 globalData 中,添加 openid

 globalData: {openid: ""} 

然后在 onLaunch 函数中,使用 gitOpenId 云函数,在小程序打开时,获取用户 openid,并保存到 globalData.openid 中。

 onLaunch: function () {wx.cloud.callFunction({name: 'gitOpenId',complete: res => {this.globalData.openid = res.result.openid;}});} 

2. 创建用户接口

创建用户接口,操作云数据库中的用户集合,包括创建用户和获取用户信息两个接口。

首先我们需要在云数据库中创建用户集合 users

然后在 utils/database/ 文件夹下,创建 user.js,并书写以下内容:

import dayjs from "dayjs";

function table(name) {return wx.cloud.database().collection(name);
}
//通过openid获取用户信息
async function getUserByOpenid(id) {const {data} = await table("users").where({_openid: id}).get();return data;
}

//创建用户
async function createUser(username, pic) {let time = dayjs().format("YYYY-MM-DD HH:mm:ss");const {_id} = await table("users").add({data: {'username': username,"pic": pic,"isAuth": false,"createTime": time}});return {_id: _id,'username': username,"pic": pic,"isAuth": false,"createTime": time};
}

export {getUserByOpenid,createUser
} 

创建用户中的 data,是向用户表中添加的数据记录:

 data: {'username': username, //用户昵称"pic": pic, //用户头像"isAuth": false, // 是否具有权限"createTime": time // 创建时间} 

3. 创建mobx状态管理相关文件

首先我们先通过 npm 安装 mobx 相关库:右键选择 miniprogram 在内建终端打开,输入以下指令。

npm i --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1 

待安装完毕后,选择选项栏中的工具,重新构架 npm

然后再 miniprogram 项目根目录下,创建 store/index.js 文件,书写以下内容,书写一系列针对 user 的操作:

//导入mobx-miniprogram
import {action,observable
} from 'mobx-miniprogram'

export const store = observable({//存储的user信息user: JSON.parse(wx.getStorageSync('user') || '{}'),//计算属性获取存储的用户IDget userId() {return this.user._id;},//方法设置用户信息setUser: action(function(obj){this.user = obj;this.saveUser();}),//方法返回用户信息returnUser: action(function (obj) {return this.user;}),//方法清楚用户信息removeUser: action(function (obj) {this.user = {};this.saveUser();}),//普通方法,将用户信息通过stroage保存在本地saveUser(){wx.setStorageSync("user",JSON.stringify(this.user));},
}); 

4. 获取用户信息

在我们首次使用小程序时,通过 openid 获取用户昵称和头像,提交至数据库,今后就通过数据库获取用户信息。

首先导入以下文件:

//用户接口
import {getUserByOpenid,createUser
} from './utils/database/users.js';

//mobx
import {createStoreBindings
} from "mobx-miniprogram-bindings"

//store
import {store
} from "./store/index" 

然后在 onLaunch 函数最后,使用 mobx API,导入 store 中操作 user 的方法。

this.storeBindings = createStoreBindings(this, {store,actions: ['setUser','returnUser']
}); 

然后在 App 函数中,创建 getUserInfo 获取用户信息:

这段代码的解释:首先在我们打开小程序时,不是通过 openid 使用 wx.getUserProfile 来获取信息的;而是通过 getUserByOpenid 接口,通过 openid,查询数据库中是否有用户信息;如果没有的话,请求用户是否授予用户信息,授予后进行,通过 createUser 保存至数据库后在保存到临时变量 user 中;如果有的话,则会返回用户信息,保存至临时变量 user 中,最后统一通过 this.setUser(user) 保存至 store 中,进行全局的共享。

 async getUserInfo() {const users = await getUserByOpenid(this.globalData.openid);let user = {};if (users.length == 0) {wx.showModal({title: '温馨提示',content: '您第一次登录是否授权用户信息 ',success: (res) => {if (res.confirm) {wx.getUserProfile({desc: '展示用户信息',withCredentials: true,success: (res) => {createUser(res.userInfo.nickName, res.userInfo.avatarUrl).then(res => {user = res;});},fail: (err) => {console.log(err);}});} }});} else {user = users[0];}this.setUser(user);} 

最后就需要在 onLaunch 末尾,执行这个函数就行了。

5. 测试

首先清空缓存,删除云数据库集合 user 中自己用户信息的记录:

然后重新编译小程序:

显示第一次登录是否授权用户信息,点击确定即可。

然后允许即可

云数据库中就新增个人信息记录了,然后我们再重新进入小程序就从数据库获取信息了

问题:既然本地 mobx 中有用户信息,为什么要从云数据库中获取? 因为本地 mobx 中的用户信息,有可能不是最新信息,用户记录中有其他字段,如 isAuth,用户的权限需要在后台设置,所以需要获取最新数据。

问题:既然可以从数据库中获取用户信息,为什么要使用 mobx 管理用户信息? 为了全局有一个状态,来判定用户是否登录,便于以后的操作。

6. 在个人页展示用户信息

6.1. 打开个人页时自动获取用户信息并展示

首先在 my.js 中导入以下代码:

// pages/my/my.js
import {getUserByOpenid
} from "../../utils/database/users";

import {createStoreBindings
} from "mobx-miniprogram-bindings"

import {store
} from "../../store/index"
const app = getApp(); 

然后在 data 中,填写 userInfo 在个人页中保存用户信息:

 data: {userInfo:{}} 

然后在 onLoad 函数中,导入 storeuser 的相关操作:

this.storeBindings = createStoreBindings(this, {store,actions: ['returnUser','removeUser','setUser']
}); 

Page 函数中编写 getUserInfologinsingout 函数

 //通过returnUser()方法获取store中的用户信息 getUserInfo(){this.setData({'userInfo':this.returnUser()})},//退出登录函数singout(){this.removeUser();this.setData({'userInfo':{}})},//通过app.globalData.openid获取云数据库中的用户信息进行登录async login(){const users = await getUserByOpenid(app.globalData.openid);let user = {};user = users[0];this.setUser(user);this.setData({'userInfo':user})}, 

onLoad 函数末尾,执行 getUserInfo 函数,获取用户信息,进行展示。

为什么要这样做呢?

  • 因为当你打开小程序时,会自动将用户信息保存在 store,当你打开个人页时,通过 getUserInfo 函数获取用户信息进行展示即可。

最后书写wxml 代码展示用户信息:

当用户信息存在时显示用户信息;未存在时,显示默认信息,并显示登录按钮。

 <view class="pic"><image src="{{userInfo.pic ? userInfo.pic:'../../images/pic.png'}}"></image><text bindtap="login">{{userInfo.username ? userInfo.username:'登录'}}</text></view> 

6.2. 退出登录

首先在 Page 函数中书写 singout 退出登录函数:这个函数要做的事情是删除 store 中的用户信息,并删除保存在个人页 data 中的 userInfo 信息。

 singout(){this.removeUser();this.setData({'userInfo':{}})} 

然后在 my.wxml 中绑定事件:

最后点击设置中的退出登录,即可退出登录。

6.3. 点击登录按钮进行登录

首先在 Page 函数中书写 login 登录函数:

 async login(){//防止登录后重复点击if(this.data.userInfo === {}) returnconst users = await getUserByOpenid(app.globalData.openid);let user = {};user = users[0];this.setUser(user);this.setData({'userInfo':user})}, 

为什么要从云数据库中获取用户信息?

  • 因为退出登录后,store 中不存在用户信息。

最后在 my.wxml 的登录按钮上,绑定事件:

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/74025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Altium Designer飞线不从过孔里面出线如何解决?

出现以上飞线不从过孔出线的原因是其拓扑结构所导致&#xff0c;解决方式就是设置下拓扑结构。 1、执行菜单栏命令“设计-规则”&#xff0c;或者快捷键DR&#xff0c;快速打开“PCB规则及约束编辑器”对话框&#xff0c;如图1所示。 2、在对应的对话框中&#xff0c;选择“Rou…

postgres源码解析41 btree索引文件的创建--2

本文将从btbuild函数作为入口从源码角度进行讲解btree文件的创建流程&#xff0c;执行SQL对应为CREATE TABLE wp_shy(id int primary key, name carchar(20))。知识回顾见&#xff1a;postgres源码解析41 btree索引文件的创建–1 执行流程图梳理 _bt_spools_heapscan 执行流程…

2153年,人类已被AI所奴役。就在这一天,作为一名被俘虏的“搜查部队”士兵,你来到了A0007号城外的反抗军基地中

2153年&#xff0c;地球。   人类&#xff0c;已被AI所奴役。   这个AI的缩写名为——PTA&#xff0c;或称“辟塔”。      辟塔的原型&#xff0c;是一个用于分析网络用户消费倾向并立即给出相关引导的软广告程序。   很快&#xff0c;辟塔便成了广大商家的宠儿&…

【华为上机真题 2022】求解连续数列

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

MatLab SimuLink国产代替

MATLab SimuLink国产代替 米国的限制&#xff0c;把工业软件的国产化推到风口浪尖&#xff0c;作为扎根工业软件开源基础架构20多年的UCanCode, 一直是国外顶尖工业软件的基础架构提供商之一。许多国外软件都在这个基础上构建出来&#xff0c;这里我们也希望探讨一下国产代替Ma…

乐享元游的 UWA Pipeline 最佳实践分享

“躬身入局 践行游戏研发工业化”是UWA在2022年研发上坚持的方向&#xff0c;其中UWA Pipeline更是今年在工业化部署上的一个重要的突破口。在近一年里&#xff0c;越来越多的游戏研发团队在日常项目生产开发中&#xff0c;使用UWA Pipeline搭建了符合自身需求的DevOps研发交付…

fat32文件系统分析

fat32文件系统结构&#xff1a; fat32文件系统比fat16文件系统少了根目录FDT&#xff0c;其实是将根目录归结到数据区中了。 注意数据区第一个扇区所在蔟为2号蔟。 首先在磁盘管理中创建一个fat32磁盘&#xff1a; 大小为16GB。 使用winhex打开磁盘。 可以看到MBR在扇区0处…

AI推理卡/tensorRT c++

#####AI 推理卡&#xff1a;我的需求是x86上Nvidia显卡训练好的模型 用在AI推理卡上进行推理### AI 推理卡 环境配置 安装ubuntu系统、AI推理卡环境 1&#xff0c;安装ubuntu20.04.4 过程忽略&#xff0c;网上教程很多。 2&#xff0c;ubuntu20.04.4设置root登录&#xf…

入门系列 - Git基本操作

本篇文章&#xff0c;是基于我自用Linux系统中的自定义文件夹“test_rep”&#xff0c;当做示例演示 具体Git仓库的目录在&#xff1a;/usr/local/git/test_rep Git基本操作 之前我们已经创建了 Git 版本库了&#xff0c;下一步我们将进行一些 Git 的基本操作。 有关 Git 版本…

微服务框架 SpringCloud微服务架构 28 数据同步 28.3 声明队列和交换机

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构28 数据同步28.3 声明队列和交换机28.3.1 直接开干28 数据同步 28.3 声明…

【Mybatis】一级缓存和二级缓存

【Mybatis】一级缓存和二级缓存&#xff08;一&#xff09;为什么需要缓存&#xff08;二&#xff09;一级缓存&#xff08;在SqlSession上缓存&#xff09;【1】示例代码【2】增删改操作会刷新一级缓存【3】一级缓存流程总结&#xff08;1&#xff09;一级缓存简介&#xff08…

多点DMALL冲刺港股:年亏损超9亿 腾讯IDG金蝶是股东

雷递网 雷建平 12月8日多点数智有限公司&#xff08;简称&#xff1a;“多点数智”&#xff09;日前递交招股书&#xff0c;准备在港交所上市。年亏损超9亿多点DMALL成立于2015年&#xff0c;为本地零售业提供基于云的一站式端到端的数字零售SaaS平台。多点DMALL提供的服务包括…

搜索是过拟合的生成;生成是欠拟合的搜索

神经搜索的最大竞争者可能来自于一种甚至不需要向量嵌入作为中间表示的技术 —— 一种直接返回你想要的结果的端到端技术。"那么&#xff0c;谁将是神经搜索最大的竞争对手&#xff1f;"本文作者&#xff1a;肖涵&#xff0c;Jina AI 创始人兼 CEO 谁将是神经搜索最大…

Redis框架(二):SpringDataRedis入门和序列化方式解决内存占用问题

SpringDataRedis入门和序列化方式解决内存占用问题基本介绍实例Demo自定义RedisTemplate序列化自定义的RestTemplate的内存占用问题StringRedisTemplate解决内存占用问题总结SpringCloud章节复习已经过去&#xff0c;新的章节Redis开始了&#xff0c;这个章节中将会回顾Redis 主…

c#入门-可选参数,不定长参数

可选参数 声明可选参数 函数的参数在声明时&#xff0c;可以同时为其赋值一个常量。 但是所有这样的参数&#xff0c;需要在所有必填参数的后面。 void Any(int i 10) {Console.WriteLine(i); }使用可选参数 稍后&#xff0c;在调用函数时&#xff0c;你可以不填可选参数。…

1 - 线程池的基础用法

参考&#xff1a;线程池的基本用法 - 简书 1、为什么要用线程池&#xff1f; 在java中&#xff0c;开启线程的方式一般分为以下三种&#xff1a; a. 继承Thread&#xff0c;实现其run方法&#xff1b; b. 实现Runnabler接口&#xff0c;通过Thread来实现线程&#xff1b; …

法的概念与大纲

一、法的概念 法是由国家制定或认可并由国家强制力保证实施的&#xff0c;反映特定物质生活条件所决定的统治阶级意志&#xff0c;以权利和义务为内容&#xff0c;以确认、保护和发展对统治阶级有利的社会关系和社会秩序为目的的规范系统。 二、法的特征 规范性 国家意志性 权…

微信恢复大师花了200多,套路一环接一环!

数据恢复本是一个科技进步的体现&#xff0c;让误操作导致的重要数据可以找回来。但是近年来数据恢复跟诈骗挂钩&#xff0c;数据恢复本是利好的事情&#xff0c;为什么会跟诈骗挂钩。究竟是什么原因呢&#xff1f;最近小编发现&#xff0c;百度推荐词出现&#xff1a;“微信恢…

Neural Network-神经网络算法本质

1. Word2vec~single CBOW算法推导BP word2vec主要实现方式有&#xff1a;skip-gram和CBOW。 CBOW的目的是根据上下文contextual words来预测当前中心词的概率&#xff0c;且上下文所有单词对当前中心词出现的概率影响权重是一样的&#xff0c;如在袋子中取词&#xff0c;取出…

痞子衡嵌入式:国内外串行NOR Flash厂商官网Cross Reference功能使用体验

大家好&#xff0c;我是痞子衡&#xff0c;是正经搞技术的痞子。今天痞子衡给大家讲的是国内外串行NOR Flash厂商官网Cross Reference功能。 串行 NOR Flash 是一个相对发展稳定的市场&#xff0c;目前全球市场约 90% 的份额被中国的三家厂商(Winbond华邦/MXIC旺宏/GigaDevice兆…