目录

树莓派+小程序开发(一)
树莓派+小程序开发(二)
四:真机调试
五: 让小程序连接树莓派
六:小程序控制面板设计
七:树莓派如何解析小程序的信息
八:树莓派如何回信息给小程序
九:树莓派与微信小程序通过websocket通信
十:小程序实时显示树莓派温湿度
十一:python版 websocket服务器实现
十二:python版websocket 服务器如何整合led和beep
十三:Python版服务器整合dht11温湿度传感器

一:前言

作者:下家山
做这个项目的初衷是因为腾讯关闭了微信的对外接口,导致我不能通过微信控制树莓派,所以我开始学习小程序,我的最终目标是通过小程序能够控制我树莓派上接的设备,比如我点一下按钮可以让我树莓派上的灯开,远程关机,还可以把树莓派上采集的数据比如温湿度上传到我手机的小程序上,我们的最终目标是手机能够实时显示温湿度信息,并且能控制树莓派上的灯和蜂鸣器,效果如图:

通过这个项目,你将会学到很酷的应用,就是通过你的手机远程控制你的树莓派。打开了这个通道,就大大扩展了你树莓派的边界。

因为最近的疫情,我可能每天都有进展,一般会一次上传一个章节,但是后面上班了可能是一周,也许到那时这个项目已经完成了,但愿。

好了,我们开工了,let’s go…

1.1 从注册开始

第一步是要注册一个小程序开发的账号,就像所有第三方开发一样,微信公众号也需要,但是我们往往不记得小程序注册的网址是多少,谁记得这个呢,没关系,我们可以通过百度帮我们找,只需要我们知道在百度里面搜微信小程序即可,所以我们从注册开始吧。
小程序注册官方地址

一个邮箱只能绑定一个小程序账号,邮箱不够用可以在注册一个腾讯qq邮箱,就是申请qq就有了qq邮箱。同样的方法,你可以到百度搜索腾讯qq,然后找到官网进入,懒的人可以从这里直接进去
腾讯qq注册官网

填写了小程序邮箱信息后,需要进去登陆激活一下


1.2 填写主体信息

一个身份证可以注册多个,同样管理员手机号也没有限制,不用担心,一个手机号可以注册多个小程序

看到下面的感叹号,恭喜你OK 了

我们可以进入开发阶段了

二. 工具下载

https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
我们下载稳定版(预发布版本和开发版本是给前沿探索者用的,如果像看看微信下程序的团队又研究了什么新东西出来了,可以去下载研究。)
如果你是windows系统,红色框标注的,如果苹果系统下载macos版本

安装后在桌面上是这个图片,不熟悉前端的人觉得这个log很丑,其实它是前端开发语言html的标志行符号</>

三 .进入开发

第一打开需要手机扫码(注册的手机)

3.1 新建项目


使用测试号即可。

3.2 文件结构

3.3 运行效果


pages,index,logs,utils,app.*五者的关系
1)pages,utils,app三者是并列关系
2)pages里面包含index,logs两个页面
3) app.js, app.json, app.wxss是控制整个小程序的,页面index,logs由app.json来配置

3.2.1 index.js负责页面逻辑

3.2.2 index.json负责页面配置

3.2.3 index.wxml负责页面结构

3.2.4 index.wxss负责页面样式

3.3 app解析

App.json全局配置

微信官方文档

{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {    "backgroundTextStyle": "light",    "navigationBarBackgroundColor": "#fff",    "navigationBarTitleText": "WeChat",    "navigationBarTextStyle": "black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}

负责页面配置,json语法格式(都是字典形式,或者字典套字典),最外层的花括号{}表示一个无名字典,然后里面是四个键值对,分别是
Key(键):value值)
“pages”:+列表,
”window”:+字典(也就是字典里面套字典了)
“style”:+字符串
“sitemapLocation”:+字符串

关键字”pages”

关键字“pages”表示整个小程序的配置页面,如果去掉"pages/index/index",则看不到第一页,程序装载后直接显示的是第二页,如图

关键字”window”

关键字”window”是对整体窗体的控制,以及外观配置
“backgroundTextStyle”:“light”,//用于控制view中的上拉下拉加载效果,只能是light/dark两种选择,一种亮色,一种暗色,如果设置其他,比如设置为black,编译出错,提示:
ppJSON[“window”][“backgroundTextStyle”]
字段需为 dark 或 light
“navigationBarBackgroundColor”: “#fff”,
“navigationBarTitleText”: “WeChat”,
“navigationBarTextStyle”: “black”
这三行,是设置导航栏的,我们可以改动一下,看看导航栏在哪个位置

关键字”style”

“style”: “v2”,是为了说明组件库版本采用的是新版v2
在下面的连接中可以找到所有基础版本库说明
https://developers.weixin.qq.com/miniprogram/dev/framework/release/v2.html

Style官方说明
基础库 2.8.0 开始支持,低版本需做兼容处理。
微信客户端 7.0 开始,UI 界面进行了大改版。小程序也进行了基础组件的样式升级。app.json 中配置 “style”: "v2"可表明启用新版的组件样式。
本次改动涉及的组件有 button icon
radio checkbox switch slider。可前往小程序示例进行体验。

关键字“sitemapLocation”

“sitemapLocation”: “sitemap.json”
文件sitemap.json内容

{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{  "action": "allow",  "page": "*"  }]
}

关键字sitemapLocation的作用主要是设置是否允许微信能否搜索小程序内的页面

官方说明:

微信现已开放小程序内搜索,开发者可以通过
sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。
爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler 及场景值:1129。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。

sitemap 配置

小程序根目录下的 sitemap.json 文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有 sitemap.json ,则默认为所有页面都允许被索引;

app.wxss全局样式

app.wxss作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。
/app.wxss/

/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}

我们改动align-items做实验,看变化结果
Align-items表示所有条目垂直对齐方式,我们这里是居中对齐,它有以下对齐方式

如果我们改为baseline,效果如下

App.wxss会作用于局部样式文件index.wxss和logs.wxss,我们从index.wxss和logs.wxss中可以看到使用了container类。

App.js全局逻辑

官方说明
https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html

App()函数

App(Object object)
注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。
App() 必须在
app.js中调用,必须调用且只能调用一次。不然会出现无法预期的后果

//app.js
App({onLaunch: function() {// 展示本地存储能力var logs= wx.getStorageSync('logs') ||[]logs.unshift(Date.now())wx.setStorageSync('logs',logs)// 登录wx.login({success: res => {// 发送 res.code 到后台换取 openId, sessionKey, unionId}})// 获取用户信息wx.getSetting({success: res => {if(res.authSetting['scope.userInfo']) {// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框wx.getUserInfo({success: res => {// 可以将 res 发送给后台解码出 unionIdthis.globalData.userInfo= res.userInfo// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回// 所以此处加入 callback 以防止这种情况if (this.userInfoReadyCallback){this.userInfoReadyCallback(res)}}})}}})},globalData: {userInfo: null}
})

onLaunch(Object object)

小程序初始化完成时触发,全局只触发一次。参数也可以使用 wx.getLaunchOptionsSync 获取。

Logs

// 展示本地存储能力

这一段代码的理解,就如注释所说,是展示本地存储能力,
var logs = wx.getStorageSync(‘logs’)|| []
这一句是通过名字logs获取数组里面的内容,如果是第一次(首次数组为空,获取到为假),则把空数组[]复制给logs;
logs.unshift(Date.now())是获取当前时间,并且插入数组logs中,unshift是前插,也叫头部插入。
大家可以直接logs.unshift(1),看看效果
如果是1,则插入格林威治初始时间

Logs.push(1)则是尾部插入,每次时间会累加历使数据

logs.shift()头部删除 logs.unshift()头部插入
logs.pop()尾部删除 logs.push()尾部插入

wx对象

Object wx
小程序 API 全局对象,用于承载小程序能力相关 API。具体请参考小程序 API 参考文档。

wx.env

小程序环境变量对象

wx.login()


Res=>是一个函数,叫箭头函数
X=>xx
相当于
Function(x)
{
Return x
x;
}
所以res=>{}相当于function(res){}
我们修改一下代码,添加一条打印语句

// 登录wx.login({success: res => {console.log("登陆信息:",res)// 发送 res.code 到后台换取 openId, sessionKey, unionId}})

我们通过console.log打印出登陆成功的返回值得到:
登陆信息:
{errMsg: “login:ok”, code:
“02167XtM1w2bE9161KsM12wkuM167Xtm”}
Login:ok表示成功登陆,你可以试试不用手机扫码登陆,看看返回值

wx.getSetting获取用户信息

// 获取用户信息wx.getSetting({success: res => {console.log("认证信息:", res)if(res.authSetting['scope.userInfo']) {// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框wx.getUserInfo({success: res => {// 可以将 res 发送给后台解码出 unionIdconsole.log("用户信息:", res)this.globalData.userInfo= res.userInfo// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回// 所以此处加入 callback 以防止这种情况if (this.userInfoReadyCallback){this.userInfoReadyCallback(res)}}})}}})}

我添加了两条语句,为了获取认证信息和用户信息
console.log(“认证信息:”, res)
console.log(“用户信息:”, res)
运行结果:

globalData全局变量
globalData: {
userInfo: null
}
globalData是字典,里面的userInfo初值为Null空,等待后续赋值。

3.4 index解析

Index.js解析

//index.js
//获取应用实例
const app = getApp()Page({data: {motto: 'Hello World',userInfo: {},hasUserInfo: false,canIUse: wx.canIUse('button.open-type.getUserInfo')},//事件处理函数bindViewTap: function() {wx.navigateTo({url: '../logs/logs'})},onLoad: function () {if (app.globalData.userInfo) {this.setData({userInfo: app.globalData.userInfo,hasUserInfo: true})} else if (this.data.canIUse){// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回// 所以此处加入 callback 以防止这种情况app.userInfoReadyCallback = res => {this.setData({userInfo: res.userInfo,hasUserInfo: true})}} else {// 在没有 open-type=getUserInfo 版本的兼容处理wx.getUserInfo({success: res => {app.globalData.userInfo = res.userInfothis.setData({userInfo: res.userInfo,hasUserInfo: true})}})}},getUserInfo: function(e) {console.log(e)app.globalData.userInfo = e.detail.userInfothis.setData({userInfo: e.detail.userInfo,hasUserInfo: true})}
})

Index.wxml 页面结构

Button标签


这里面的逻辑关系,在index.wxml代码第4行
获取头像昵称
Wx:if是一个判断语句,hasUserInfo第一次装载页面时时false,canIUse是一个字典中的key,它的值value是有定义的,所以这里&&后面应该时为真的,但前面hasUserInfo再非一次(!表示取反)则为真,因此,wx:if里面为真,因此会显示“获取头像昵称”字样在界面上。

如果我们点击按钮”获取头像昵称”,则会触发绑定的函数调用getUserInfo
该函数定义在Index.js中的第46行。


其中,hasUserInfo会赋值为真true.
这样再次刷新页面时,不会再显示“获取图像昵称”,而会显示真实图像了
,注意需要微信扫码登陆

Image标签

 <block wx:else><image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image><text class="userinfo-nickname">{{userInfo.nickName}}</text></block>

Wx:else是和button中的wx:if对应的,当if条件不成立时则会进入else,即显示image
Image通过Bindtap绑定到函数bindViewTap,bindtap是一个点击事件,这样当点击了头像时,则执行bindViewTap函数,该函数定义在index.js中的13行

 //事件处理函数bindViewTap: function() {wx.navigateTo({url: '../logs/logs'})},

在这个函数中,wx.navigateTo()是一个界面切换函数,url:’…/logs/logs’则会告诉wx.navigateTo切换到上级目录下面的logs文件夹下面的logs.js从而装载下一个页面logs.js

Text标签

{{userInfo.nickName}}
这一段控制的是头像下面的昵称名称

字体和颜色的控制是通过index.wxss中的userinfo-nickname类来控制的

Index.wxss文件解析

/**index.wxss**/
.userinfo {display: flex;flex-direction: column;align-items: center;
}
.userinfo-avatar {width: 128rpx;height: 128rpx;margin: 20rpx;border-radius: 50%;
}
.userinfo-nickname {color: #aaa;
}
.usermotto {margin-top: 200px;
}

Motto显示

Motto:是座右铭,格言,警句的意思

<view class="usermotto"><text class="user-motto">{{motto}}</text></view>
Class=”usermotto”表示使用index.wxss中的usermotto样式控制
.usermotto {margin-top: 200px;//表示别名显示离上面的图片image200个像素距离
}
{{motto}}中的motto是微信小程序中的对变量的引用语法格式,这个变量定义在index.js中
Page({data: {motto: 'Hello World',//变量motto的定义和初始化,它其实也是一个键值对userInfo: {},hasUserInfo: false,canIUse: wx.canIUse('button.open-type.getUserInfo')},

Index.wxml视图层view


Index.wxml负责页面结构,这种结构通常通过view来管理,这里有三个view(第一层view),一个大view,包含两个小view(第二层view控制)
而这些view层的样式控制是通过app.wxss和index.wxss文件来控制的,
App.wxss负责大view的样式,index.wxss负责小view的样式。这三个文件的关系如下:

3.5 logs解析

Logs整个的页面是为了展现本地存储能力的,所以是通过日志(打印当前时间,每次加载子页面的时间)
效果如图

Logs.js子页面逻辑

//logs.js
const util = require('../../utils/util.js')
//requre包含另一个文件,相当于include和import
Page({data: {logs: []//空列表,方便后面追加},onLoad: function () {console.log("装载logs页面....")this.setData({//在app.js中已经调用wx.setStorageSync('logs', logs)设置了当前时间logs: (wx.getStorageSync('logs') || []).map(log => {//通过util.js中的格式化操作把时间转成字符串return util.formatTime(new Date(log))})})}
})

Logs.json解析
{
“navigationBarTitleText”: “查看启动日志”,
“usingComponents”: {}
}
页面配置文件,设置导航栏标题,切换到logs页面时的“查看启动日志”就是这里设置的

Logs.wxml解析

Logs页面结构设计,即打印日志的格式,样式

<!--logs.wxml-->
<view class="container log-list"><block wx:for="{{logs}}" wx:for-item="log"><text class="log-item">{{index + 1}}. {{log}}</text></block>
</view>

这里有循环语句wx:for,会统计日志的行数,index从0开始计数,所以+1,方便用户看

Logs.wxss解析

.log-list {display: flex;flex-direction: column;padding: 40rpx;
}
.log-item {margin: 10rpx;
}

负责logs.wxml结构显示的样式

3.6 util.js解析

formatTime是一个函数,参数就是date
=>后面的花括号是函数体,其中的year,month,day,hour,minute,second每个变量占用一条语句,js中的语句不需要分号,换行就行了

const formatTime = date => {const year = date.getFullYear()  //取得参数date中的年const month = date.getMonth() + 1//取得参数date中的月,因为月从0开始,所以要+1const day = date.getDate()    //得到天const hour = date.getHours()  //得到小时const minute = date.getMinutes() //得到分钟const second = date.getSeconds()  //得到秒//返回年月日,时分秒,年月日以/隔开,时分秒以:隔开,形如2020/02/25 20:21:34return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
//把列表转成字符串
const formatNumber = n => {n = n.toString()return n[1] ? n : '0' + n   //这一句没有什么意义,去掉也没问题
}module.exports = {formatTime: formatTime//导出函数,供外部调用(logs.js)
}

End

有什么问题,大家可以留言,包括错别字。
接下来:我们将推倒微信小程序例程,从头再来。
树莓派+小程序开发(一)
树莓派+小程序开发(二)
四:真机调试
五: 让小程序连接树莓派
六:小程序控制面板设计
七:树莓派如何解析小程序的信息
八:树莓派如何回信息给小程序
九:树莓派与微信小程序通过websocket通信
十:小程序实时显示树莓派温湿度
十一:python版 websocket服务器实现
十二:python版websocket 服务器如何整合led和beep
十三:Python版服务器整合dht11温湿度传感器

树莓派+小程序开发(一)相关推荐

  1. 小程序开发需要注意什么

    小程序对于现在的生活来说已经是一个特别热门的应用了,没有人不知道小程序的存在,小程序有很多的优势,使用特别方便并且不占内存,所以受很多人的喜欢,那么小程序开发需要注意些什么呢?今天方维网络就给大家分享 ...

  2. 微信小程序开发的完整流程介绍,新手必读

    自从跳一跳小程序游戏出现后,一夜之间,小程序就变得家喻户晓了,功能开发也越来越丰富,在微信搜一搜就会发现许多大品牌早已有自己的小程序了,越来越多的企业和商家都看中了这个风口,想快速开发出一款属于自己的 ...

  3. 01 小程序开发入门

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.什么是小程序 小程序是一种不需要下载安装即可使用的应用,它实现了应用"触手可 ...

  4. 微信小程序开发(2)_data属性

    假设我们的环境都做好了,现在我们开始开发自己的小程序 首先我们开发出自己的 Hello World 我们要做的事情是当前点击hello World的时候HelloWorld的颜色发生变化: 这个是我们 ...

  5. 微信小程序开发之选项卡

    选项卡是web开发中经常使用到的一个模块,在小程序中竟然没有,这里参考别人的文章自己做了一个双选项卡 实现思路: 通过绑定swichNav事件来控制currentTab(当前选项卡)和isShow(是 ...

  6. 微信小程序开发优秀教程及文章合集第一期

    2019独角兽企业重金招聘Python工程师标准>>> 我会不定期的选取一些优质教程,整理成辑,以便大家集中阅读: 新手向!微信小程序开发手记系列: 微信小程序开发手记<一&g ...

  7. 经验总结--我的小程序开发和进化之路

    前言 从接触小程序开始,到现在大大小小做了差不多有五六个小程序项目了,小项目的只有几个页面,大的项目有几十个页面.此篇文章是对之前项目的一个总结,项目的脚手架,开发框架和后期的优化是一个逐渐进化完善的 ...

  8. 新闻资讯小程序开发实践

    新闻资讯小程序开发实践 在腾讯小程序上线一周年之际,公司又决定把App产品部分内容在小程序上实现.就在小程序刚上线的时候,公司也有一款产品进行了小程序的研发,但后续没有持续的维护.这过了一年的时间,微 ...

  9. amos看拟合度在哪里看_小程序开发公司哪里强?看这几点

    如今小程序开发已不罕见,越来越多的线下商家需要布局线上渠道,小程序是一个非常好的选择.但是,对于不懂任何技术.也没有自身技术团队的小白而言,若想拥有自己的小程序,就需要找靠谱的微信小程序开发公司,但是 ...

最新文章

  1. RuntimeError Assertion cur_target = 0 cur_target n_classes failed
  2. 算法 - pyhton - 二分查找
  3. .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析
  4. 30个Python极简代码,10分钟get常用技巧!
  5. Spring Boot 2.x基础教程:配置文件详解
  6. 毕业设计-基于Python爬虫的疫情数据可视化系统
  7. 没有算法资源,产品经理如何从0到1搭建推荐系统?
  8. 用栈实现计算器c语言报告,利用栈实现c语言计算器
  9. 网页与多个服务器建立websoc,同一个页面怎么发起多个websocket
  10. 运维软件推荐(附带软件百度网盘分享)
  11. 河南增值税开票系统原服务器地址,河南省增值税发票综合服务平台登录入口:https://fpdk.henan.chinatax.gov.cn...
  12. maxscale mysql5.7_Centos7安装maxscale 实现mysql的读写分离
  13. “此网页上的某个 Web 部件或 Web 表单控件无法显示或导入。找不到该类型,或该类型未注册为安全类型。”
  14. python龙卷风框架,龙卷风python的简单异步示例
  15. 英文博客群建如何保证收录?
  16. 华硕开机自动进入BIOS解决办法
  17. Pano React Native SDK 来了!快速实现移动端音视频和白板
  18. 华为编程决赛后的感想
  19. 【SpringCloud】Could not find artifact org.springframework.cloud:spring-cloud-starter-xxx
  20. 《逃离禁闭岛》游戏评测:不一样的密室逃脱

热门文章

  1. Commvault资源集合(20191009)
  2. Redis之Vs Memcached
  3. 新视野大学英语第三版读写教程(四)Unite 4 Midterm test answer
  4. 智能手环数据研究1——系统响应时延简易评估
  5. 智慧景区电子票务系统人脸识别售检票基本思路
  6. 基于springboot的工资管理系统
  7. vue+echarts中国地图+省市级地图(全程教学,你也可以)
  8. vue中使用echarts实现中国地图加城市定位功能
  9. NOIP 2016 Day1 T3-换教室
  10. Day 014 MySQL-查询