微信小程序开发-蓝牙功能开发
0. 前言
这两天刚好了解了一下微信小程序的蓝牙功能。主要用于配网功能。发现微信的小程序蓝牙API已经封装的很好了。编程起来很方便。什么蓝牙知识都不懂的情况下,不到两天就晚上数据的收发了,剩下的就是数据帧格式的定义,当然这部分就不是本次博客的重点。
1. 准备硬件
这里我准备了CH341SER这个作为USB转串口。用sscom5.13.1 串口工具。由于我不太懂硬件开发。硬件部分都是由公司其他人开发的。我只是负责把环境搭建起来。然后负责我的微信小程序开发。
2. 开发小程序简单讲解
onLoad 这个一方面是用来获取当前连接的WiFi名称,减少用户输入,另一方面也是用来判断当前是否开启GPS功能。对于Android用户,是需要打开GPS蓝牙功能才能搜索到周围的蓝牙设备。
- onLoad: function(options) {
- var that = this;
- wx.startWifi({
- success(res) {
- console.log(res.errMsg)
- wx.getConnectedWifi({
- success: function(res) {
- console.log(res);
- that.setData({
- ssid: res.wifi.SSID
- })
- },
- fail: function(res) {
- if(res.errCode == 12006){
- wx.showModal({
- title: '请打开GPS定位',
- content: 'Android手机不打开GPS定位,无法搜索到蓝牙设备.',
- showCancel: false
- })
- }
- console.log(res);
- }
- })
- }
- })
- },
搜索蓝牙设备相关代码
- searchBleEvent: function(ret){
- var ssid = this.data.ssid;
- var pass = this.data.pass;
- console.log(ssid, pass);
- if (util.isEmpty(ssid) || util.isEmpty(pass)) {
- util.toastError('请输入WiFi名称及密码');
- return;
- }
- this.initBLE();
- },
初始化蓝牙适配器
- initBLE: function() {
- this.printLog("启动蓝牙适配器, 蓝牙初始化")
- var that = this;
- wx.openBluetoothAdapter({
- success: function(res) {
- console.log(res);
- that.findBLE();
- },
- fail: function(res) {
- util.toastError('请先打开蓝牙');
- }
- })
- },
定义搜索设备任务
- findBLE: function() {
- this.printLog("打开蓝牙成功.")
- var that = this
- wx.startBluetoothDevicesDiscovery({
- allowDuplicatesKey: false,
- interval: 0,
- success: function(res) {
- wx.showLoading({
- title: '正在搜索设备',
- })
- console.log(res);
- delayTimer = setInterval(function(){
- that.discoveryBLE() //3.0 //这里的discovery需要多次调用
- }, 1000);
- setTimeout(function () {
- if (isFound) {
- return;
- } else {
- wx.hideLoading();
- console.log("搜索设备超时");
- wx.stopBluetoothDevicesDiscovery({
- success: function (res) {
- console.log('连接蓝牙成功之后关闭蓝牙搜索');
- }
- })
- clearInterval(delayTimer)
- wx.showModal({
- title: '搜索设备超时',
- content: '请检查蓝牙设备是否正常工作,Android手机请打开GPS定位.',
- showCancel: false
- })
- util.toastError("搜索设备超时,请打开GPS定位,再搜索")
- return
- }
- }, 15000);
- },
- fail: function(res) {
- that.printLog("蓝牙设备服务发现失败: " + res.errMsg);
- }
- })
- },
搜索设备回调
- discoveryBLE: function() {
- var that = this
- wx.getBluetoothDevices({
- success: function(res) {
- var list = res.devices;
- console.log(list);
- if(list.length <= 0){
- return ;
- }
- var devices = [];
- for (var i = 0; i < list.length; i++) {
- //that.data.inputValue:表示的是需要连接的蓝牙设备ID,
- //简单点来说就是我想要连接这个蓝牙设备,
- //所以我去遍历我搜索到的蓝牙设备中是否有这个ID
- var name = list[i].name || list[i].localName;
- if(util.isEmpty(name)){
- continue;
- }
- if(name.indexOf('JL') >= 0 && list[i].RSSI != 0){
- console.log(list[i]);
- devices.push(list[i]);
- }
- }
- console.log('总共有' + devices.length + "个设备需要设置")
- if (devices.length <= 0) {
- return;
- }
- that.connectBLE(devices);
- },
- fail: function() {
- util.toastError('搜索蓝牙设备失败');
- }
- })
- },
设置可以进行连接的设备
- connectBLE: function(devices){
- this.printLog('总共有' + devices.length + "个设备需要设置")
- var that = this;
- wx.hideLoading();
- isFound = true;
- clearInterval(delayTimer);
- wx.stopBluetoothDevicesDiscovery({
- success: function (res) {
- that.printLog('连接蓝牙成功之后关闭蓝牙搜索');
- }
- })
- //两个的时候需要选择
- var list = [];
- for (var i = 0; i < devices.length; i++) {
- var name = devices[i].name || devices[i].localName;
- list.push(name + "[" + devices[i].deviceId + "]")
- }
- this.setData({
- deviceArray: list
- })
- //默认选择
- this.setData({
- currDeviceID: list[0]
- })
- },
选择设备,然后点击对应的配网按钮,创建BLE连接
- createBLE: function(deviceId){
- this.printLog("连接: [" + deviceId+"]");
- var that = this;
- this.closeBLE(deviceId, function(res){
- console.log("预先关闭,再打开");
- setTimeout(function(){
- wx.createBLEConnection({
- deviceId: deviceId,
- success: function (res) {
- that.printLog("设备连接成功");
- that.getBLEServiceId(deviceId);
- },
- fail: function (res) {
- that.printLog("设备连接失败" + res.errMsg);
- }
- })
- }, 2000)
- });
- },
获取蓝牙设备提供的服务UUID(本项目由于只会提供一个服务,就默认选择,实际项目,会自定义这个UUID的前缀或者后缀规则,定义多个不同的服务)
- //获取服务UUID
- getBLEServiceId: function(deviceId){
- this.printLog("获取设备[" + deviceId + "]服务列表")
- var that = this;
- wx.getBLEDeviceServices({
- deviceId: deviceId,
- success: function(res) {
- console.log(res);
- var services = res.services;
- if (services.length <= 0){
- that.printLog("未找到主服务列表")
- return;
- }
- that.printLog('找到设备服务列表个数: ' + services.length);
- if (services.length == 1){
- var service = services[0];
- that.printLog("服务UUID:["+service.uuid+"] Primary:" + service.isPrimary);
- that.getBLECharactedId(deviceId, service.uuid);
- }else{ //多个主服务
- //TODO
- }
- },
- fail: function(res){
- that.printLog("获取设备服务列表失败" + res.errMsg);
- }
- })
- },
获取服务下的特征值(由于这个例子,是包含两个特征值,一个用于读,一个用于写,实际项目,跟上面的服务一样,要定义好特征量UUID的规则)
- getBLECharactedId: function(deviceId, serviceId){
- this.printLog("获取设备特征值")
- var that = this;
- wx.getBLEDeviceCharacteristics({
- deviceId: deviceId,
- serviceId: serviceId,
- success: function(res) {
- console.log(res);
- //这里会获取到两个特征值,一个用来写,一个用来读
- var chars = res.characteristics;
- if(chars.length <= 0){
- that.printLog("未找到设备特征值")
- return ;
- }
- that.printLog("找到设备特征值个数:" + chars.length);
- if(chars.length == 2){
- for(var i=0; i<chars.length; i++){
- var char = chars[i];
- that.printLog("特征值[" + char.uuid + "]")
- var prop = char.properties;
- if(prop.notify == true){
- that.printLog("该特征值属性: Notify");
- that.recvBLECharacterNotice(deviceId, serviceId, char.uuid);
- }else if(prop.write == true){
- that.printLog("该特征值属性: Write");
- that.sendBLECharacterNotice(deviceId, serviceId, char.uuid);
- }else{
- that.printLog("该特征值属性: 其他");
- }
- }
- }else{
- //TODO
- }
- },
- fail: function(res){
- that.printLog("获取设备特征值失败")
- }
- })
- },
recv 接收设备发送过来数据
- recvBLECharacterNotice: function(deviceId, serviceId, charId){
- //接收设置是否成功
- this.printLog("注册Notice 回调函数");
- var that = this;
- wx.notifyBLECharacteristicValueChange({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: charId,
- state: true, //启用Notify功能
- success: function(res) {
- wx.onBLECharacteristicValueChange(function(res){
- console.log(res);
- that.printLog("收到Notify数据: " + that.ab2hex(res.value));
- //关闭蓝牙
- wx.showModal({
- title: '配网成功',
- content: that.ab2hex(res.value),
- showCancel: false
- })
- });
- },
- fail: function(res){
- console.log(res);
- that.printLog("特征值Notice 接收数据失败: " + res.errMsg);
- }
- })
- },
send 小程序发送数据到设备
- sendBLECharacterNotice: function (deviceId, serviceId, charId){
- //发送ssid/pass
- this.printLog("延时1秒后,发送SSID/PASS");
- var that = this;
- var cell = {
- "ssid": this.data.ssid,
- "pass": this.data.pass
- }
- var buffer = this.string2buffer(JSON.stringify(cell));
- setTimeout(function(){
- wx.writeBLECharacteristicValue({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: charId,
- value: buffer,
- success: function(res) {
- that.printLog("发送SSID/PASS 成功");
- },
- fail: function(res){
- console.log(res);
- that.printLog("发送失败." + res.errMsg);
- },
- complete: function(){
- }
- })
- }, 1000);
- },
手机端可以同时连接多个蓝牙设备,但是同一个蓝牙设备不能被多次连接,所以需要在每次连接前关闭BLE连接
- closeBLE: function(deviceId, callback){
- var that = this;
- wx.closeBLEConnection({
- deviceId: deviceId,
- success: function(res) {
- that.printLog("断开设备[" + deviceId + "]成功.");
- console.log(res)
- },
- fail: function(res){
- that.printLog("断开设备成功.");
- },
- complete: callback
- })
- },
说明:接收数据和发送数据时,注意BLE限制了发送数据包的大小,现在20byte。具体参考微信小程序官方文档: https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth-ble/wx.writeBLECharacteristicValue.html
3. 蓝牙相关的所有JS代码
- // pages/bluetoothconfig/bluetoothconfig.js
- const util = require('../../utils/util.js')
- var delayTimer; //用来控制是否持续服务发现
- var isFound = false;
- Page({
- /**
- * 页面的初始数据
- */
- data: {
- ssid: '',
- pass: '',
- logs: [],
- deviceArray: [],
- currDeviceID: '请选择...'
- },
- onLoad: function(options) {
- var that = this;
- wx.startWifi({
- success(res) {
- console.log(res.errMsg)
- wx.getConnectedWifi({
- success: function(res) {
- console.log(res);
- that.setData({
- ssid: res.wifi.SSID
- })
- },
- fail: function(res) {
- if(res.errCode == 12006){
- wx.showModal({
- title: '请打开GPS定位',
- content: 'Android手机不打开GPS定位,无法搜索到蓝牙设备.',
- showCancel: false
- })
- }
- console.log(res);
- }
- })
- }
- })
- },
- bindPickerChange: function(ret){
- var array = this.data.deviceArray;
- console.log(array[ret.detail.value]);
- this.setData({
- currDeviceID: array[ret.detail.value]
- })
- },
- searchBleEvent: function(ret){
- var ssid = this.data.ssid;
- var pass = this.data.pass;
- console.log(ssid, pass);
- if (util.isEmpty(ssid) || util.isEmpty(pass)) {
- util.toastError('请输入WiFi名称及密码');
- return;
- }
- this.initBLE();
- },
- bleConfigEvent: function (ret) {
- var deviceID = this.data.currDeviceID;
- console.log("选中:" + deviceID);
- if (util.isEmpty(deviceID) || deviceID == "请选择..."){
- util.toastError("请先搜索设备");
- return ;
- }
- var device = deviceID.split('[');
- if(device.length <= 1){
- util.toastError("请先搜索设备");
- return ;
- }
- var id = device[device.length - 1].replace("]", "");
- console.log(id);
- util.toastError("连接" + id);
- this.createBLE(id);
- },
- initBLE: function() {
- this.printLog("启动蓝牙适配器, 蓝牙初始化")
- var that = this;
- wx.openBluetoothAdapter({
- success: function(res) {
- console.log(res);
- that.findBLE();
- },
- fail: function(res) {
- util.toastError('请先打开蓝牙');
- }
- })
- },
- findBLE: function() {
- this.printLog("打开蓝牙成功.")
- var that = this
- wx.startBluetoothDevicesDiscovery({
- allowDuplicatesKey: false,
- interval: 0,
- success: function(res) {
- wx.showLoading({
- title: '正在搜索设备',
- })
- console.log(res);
- delayTimer = setInterval(function(){
- that.discoveryBLE() //3.0 //这里的discovery需要多次调用
- }, 1000);
- setTimeout(function () {
- if (isFound) {
- return;
- } else {
- wx.hideLoading();
- console.log("搜索设备超时");
- wx.stopBluetoothDevicesDiscovery({
- success: function (res) {
- console.log('连接蓝牙成功之后关闭蓝牙搜索');
- }
- })
- clearInterval(delayTimer)
- wx.showModal({
- title: '搜索设备超时',
- content: '请检查蓝牙设备是否正常工作,Android手机请打开GPS定位.',
- showCancel: false
- })
- util.toastError("搜索设备超时,请打开GPS定位,再搜索")
- return
- }
- }, 15000);
- },
- fail: function(res) {
- that.printLog("蓝牙设备服务发现失败: " + res.errMsg);
- }
- })
- },
- discoveryBLE: function() {
- var that = this
- wx.getBluetoothDevices({
- success: function(res) {
- var list = res.devices;
- console.log(list);
- if(list.length <= 0){
- return ;
- }
- var devices = [];
- for (var i = 0; i < list.length; i++) {
- //that.data.inputValue:表示的是需要连接的蓝牙设备ID,
- //简单点来说就是我想要连接这个蓝牙设备,
- //所以我去遍历我搜索到的蓝牙设备中是否有这个ID
- var name = list[i].name || list[i].localName;
- if(util.isEmpty(name)){
- continue;
- }
- if(name.indexOf('JL') >= 0 && list[i].RSSI != 0){
- console.log(list[i]);
- devices.push(list[i]);
- }
- }
- console.log('总共有' + devices.length + "个设备需要设置")
- if (devices.length <= 0) {
- return;
- }
- that.connectBLE(devices);
- },
- fail: function() {
- util.toastError('搜索蓝牙设备失败');
- }
- })
- },
- connectBLE: function(devices){
- this.printLog('总共有' + devices.length + "个设备需要设置")
- var that = this;
- wx.hideLoading();
- isFound = true;
- clearInterval(delayTimer);
- wx.stopBluetoothDevicesDiscovery({
- success: function (res) {
- that.printLog('连接蓝牙成功之后关闭蓝牙搜索');
- }
- })
- //两个的时候需要选择
- var list = [];
- for (var i = 0; i < devices.length; i++) {
- var name = devices[i].name || devices[i].localName;
- list.push(name + "[" + devices[i].deviceId + "]")
- }
- this.setData({
- deviceArray: list
- })
- //默认选择
- this.setData({
- currDeviceID: list[0]
- })
- },
- createBLE: function(deviceId){
- this.printLog("连接: [" + deviceId+"]");
- var that = this;
- this.closeBLE(deviceId, function(res){
- console.log("预先关闭,再打开");
- setTimeout(function(){
- wx.createBLEConnection({
- deviceId: deviceId,
- success: function (res) {
- that.printLog("设备连接成功");
- that.getBLEServiceId(deviceId);
- },
- fail: function (res) {
- that.printLog("设备连接失败" + res.errMsg);
- }
- })
- }, 2000)
- });
- },
- //获取服务UUID
- getBLEServiceId: function(deviceId){
- this.printLog("获取设备[" + deviceId + "]服务列表")
- var that = this;
- wx.getBLEDeviceServices({
- deviceId: deviceId,
- success: function(res) {
- console.log(res);
- var services = res.services;
- if (services.length <= 0){
- that.printLog("未找到主服务列表")
- return;
- }
- that.printLog('找到设备服务列表个数: ' + services.length);
- if (services.length == 1){
- var service = services[0];
- that.printLog("服务UUID:["+service.uuid+"] Primary:" + service.isPrimary);
- that.getBLECharactedId(deviceId, service.uuid);
- }else{ //多个主服务
- //TODO
- }
- },
- fail: function(res){
- that.printLog("获取设备服务列表失败" + res.errMsg);
- }
- })
- },
- getBLECharactedId: function(deviceId, serviceId){
- this.printLog("获取设备特征值")
- var that = this;
- wx.getBLEDeviceCharacteristics({
- deviceId: deviceId,
- serviceId: serviceId,
- success: function(res) {
- console.log(res);
- //这里会获取到两个特征值,一个用来写,一个用来读
- var chars = res.characteristics;
- if(chars.length <= 0){
- that.printLog("未找到设备特征值")
- return ;
- }
- that.printLog("找到设备特征值个数:" + chars.length);
- if(chars.length == 2){
- for(var i=0; i<chars.length; i++){
- var char = chars[i];
- that.printLog("特征值[" + char.uuid + "]")
- var prop = char.properties;
- if(prop.notify == true){
- that.printLog("该特征值属性: Notify");
- that.recvBLECharacterNotice(deviceId, serviceId, char.uuid);
- }else if(prop.write == true){
- that.printLog("该特征值属性: Write");
- that.sendBLECharacterNotice(deviceId, serviceId, char.uuid);
- }else{
- that.printLog("该特征值属性: 其他");
- }
- }
- }else{
- //TODO
- }
- },
- fail: function(res){
- that.printLog("获取设备特征值失败")
- }
- })
- },
- recvBLECharacterNotice: function(deviceId, serviceId, charId){
- //接收设置是否成功
- this.printLog("注册Notice 回调函数");
- var that = this;
- wx.notifyBLECharacteristicValueChange({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: charId,
- state: true, //启用Notify功能
- success: function(res) {
- wx.onBLECharacteristicValueChange(function(res){
- console.log(res);
- that.printLog("收到Notify数据: " + that.ab2hex(res.value));
- //关闭蓝牙
- wx.showModal({
- title: '配网成功',
- content: that.ab2hex(res.value),
- showCancel: false
- })
- });
- },
- fail: function(res){
- console.log(res);
- that.printLog("特征值Notice 接收数据失败: " + res.errMsg);
- }
- })
- },
- sendBLECharacterNotice: function (deviceId, serviceId, charId){
- //发送ssid/pass
- this.printLog("延时1秒后,发送SSID/PASS");
- var that = this;
- var cell = {
- "ssid": this.data.ssid,
- "pass": this.data.pass
- }
- var buffer = this.string2buffer(JSON.stringify(cell));
- setTimeout(function(){
- wx.writeBLECharacteristicValue({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: charId,
- value: buffer,
- success: function(res) {
- that.printLog("发送SSID/PASS 成功");
- },
- fail: function(res){
- console.log(res);
- that.printLog("发送失败." + res.errMsg);
- },
- complete: function(){
- }
- })
- }, 1000);
- },
- closeBLE: function(deviceId, callback){
- var that = this;
- wx.closeBLEConnection({
- deviceId: deviceId,
- success: function(res) {
- that.printLog("断开设备[" + deviceId + "]成功.");
- console.log(res)
- },
- fail: function(res){
- that.printLog("断开设备成功.");
- },
- complete: callback
- })
- },
- printLog: function(msg){
- var logs = this.data.logs;
- logs.push(msg);
- this.setData({ logs: logs })
- },
- /**
- * 将字符串转换成ArrayBufer
- */
- string2buffer(str) {
- if (!str) return;
- var val = "";
- for (var i = 0; i < str.length; i++) {
- val += str.charCodeAt(i).toString(16);
- }
- console.log(val);
- str = val;
- val = "";
- let length = str.length;
- let index = 0;
- let array = []
- while (index < length) {
- array.push(str.substring(index, index + 2));
- index = index + 2;
- }
- val = array.join(",");
- // 将16进制转化为ArrayBuffer
- return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
- return parseInt(h, 16)
- })).buffer
- },
- /**
- * 将ArrayBuffer转换成字符串
- */
- ab2hex(buffer) {
- var hexArr = Array.prototype.map.call(
- new Uint8Array(buffer),
- function (bit) {
- return ('00' + bit.toString(16)).slice(-2)
- }
- )
- return hexArr.join('');
- },
- inputSSID: function(res) {
- var ssid = res.detail.value;
- this.setData({
- ssid: ssid
- })
- },
- inputPASS: function(res) {
- var pass = res.detail.value;
- this.setData({
- pass: pass
- })
- }
- })
//补充util.js
- const formatTime = date => {
- const year = date.getFullYear()
- const month = date.getMonth() + 1
- const day = date.getDate()
- const hour = date.getHours()
- const minute = date.getMinutes()
- const second = date.getSeconds()
- return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
- }
- const formatNumber = n => {
- n = n.toString()
- return n[1] ? n : '0' + n
- }
- const isEmpty = function(str){
- if(str == null || str == undefined || str == ""){
- return true;
- }
- return false;
- }
- const randomWord = function(range){
- var str = "",
- arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
- // 随机产生
- for (var i = 0; i < range; i++) {
- var pos = Math.round(Math.random() * (arr.length - 1));
- str += arr[pos];
- }
- return str;
- }
- const toastServerError = function(){
- wx.showToast({
- title: '服务器异常,请稍后重试!',
- icon: 'none',
- duration: 1200,
- mask: true
- })
- }
- const toastError = function(info){
- wx.showToast({
- title: info,
- icon: 'none',
- duration: 1200,
- mask: true
- })
- }
- module.exports = {
- formatTime: formatTime,
- isEmpty: isEmpty,
- toastServerError: toastServerError,
- toastError: toastError,
- randomWord: randomWord
- }
//补充分包代码
- /* 统一发送数据,带分包 */
- sendBLEData: function (deviceId, serviceId, charId, array){
- var that = this;
- if(array.length <= 0){
- that.printLog("发送SSID/PASS 完成");
- return;
- }
- var list = array.splice(0, 20);
- var buffer = new Uint8Array(list).buffer;
- wx.writeBLECharacteristicValue({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: charId,
- value: buffer,
- success: function (res) {
- that.printLog("发送SSID/PASS 分包发送");
- that.sendBLEData(deviceId, serviceId, charId, array);
- },
- fail: function (res) {
- console.log(res);
- that.printLog("发送失败." + res.errMsg);
- },
- complete: function () {
- }
- })
- },
4. 运行时截图
工具下载地址:
https://files.cnblogs.com/files/wunaozai/sscom5.13.1.zip
https://files.cnblogs.com/files/wunaozai/CH341SER_64bit.zip
源代码下载 :
https://files.cnblogs.com/files/wunaozai/bluetoothconfig.rar
参考资料:
https://www.cnblogs.com/guhonghao/p/9947144.html
本文地址:
https://www.cnblogs.com/wunaozai/p/11512874.html
微信小程序开发-蓝牙功能开发的更多相关文章
- 微信小程序调用蓝牙功能控制车位锁
第一次学用微信小程序,项目需要,被逼着研究了一下,功能是调用微信小程序的蓝牙功能,连接上智能车位锁,控制升降,大概步骤及调用的小程序接口API如下: 1.打开蓝牙模块 wx.openBluetooth ...
- 微信小程序之蓝牙开发(详细读数据、写数据、附源码)
本文将详细介绍微信小程序的蓝牙开发流程(附源码)准备:微信只支持低功耗蓝牙也就是蓝牙4.0,普通的蓝牙模块是用不了的,一定要注意. 蓝牙可以连TTL接到电脑上,再用XCOM调试 一开始定义的变量 va ...
- 微信小程序购物商城系统开发系列-工具篇
微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统.新的生态,未来大部分应用场景都将 ...
- 微信小程序购物商城系统开发系列
微信小程序购物商城系统开发系列 微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统. ...
- 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...
- 从微信小程序到鸿蒙js开发【13】——list加载更多&回到顶部
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1.list加载更多 2.list回到顶部 3.<从微信小程序到鸿蒙js开发>系列文章合集 1.list加 ...
- 微信小程序版博客——开发汇总总结(附源码)
花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...
- 微信小程序购物商城系统开发系列-目录结构
上一篇我们简单介绍了一下微信小程序的IDE(微信小程序购物商城系统开发系列-工具篇),相信大家都已经蠢蠢欲试建立一个自己的小程序,去完成一个独立的商城网站. 先别着急我们一步步来,先尝试下写一个自己的 ...
- 从微信小程序到鸿蒙js开发【11】——页面路由
目录: 1.router.push()&wx.navigateTo() 2.router.replace()&wx.redirectTo() 3.router.back()&w ...
随机推荐
- React: 研究React的组件化
一.简介大概 在以往的Web开发中,会把web页面所有的复杂控件作为一个单一的整体进行开发,由于控件之间需要进行通信,因此不同的组件之间的耦合度会很多,由于开发一个控件的时候要考虑到控件与控件之间的联 ...
- IT兄弟连 HTML5教程 HTML和CSS的关系
HTML是描述网页的标记语言,是将内容放到网页上,虽然HTML本身也自带一些样式功能,通过自身的属性,来实现一些特定的效果,制作出来的只能是一个网页,而不是一个美观的网页.最主要的是在HTML里面,一 ...
- linux学习之Ubuntu
查看自己的ubuntu版本,输入以下命令(我的都是在root用户下的,在普通用户要使用sudo)第一行的lsb是因为没有安装LSB,安装之后就不会出现这个东西.LSB(Linux Standards ...
- win7系统下安装Ubuntu18.04组成双系统
最近在闲鱼上花了350大洋淘到了一台tinkpad sl510,这大概是一台发布于2009年的一台电脑了吧,处理器是酷睿二t440,2Gddr3的显卡,让我有点意外的是这台电脑的硬盘是7200转的32 ...
- What is Java virtual machine?
Java Virtual Machine (JVM) is a specification that provides runtime environment in which java bytec ...
- make 命令与 Makefile
make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建.虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发.ma ...
- iota: Golang 中优雅的常量
阅读约 11 分钟 注:该文作者是 Katrina Owen,原文地址是 iota: Elegant Constants in Golang 有些概念有名字,并且有时候我们关注这些名字,甚至(特别)是 ...
- 易优CMS:volist的基础应用
[基础用法] 名称:volist 功能:数据/记录循环输出标签 语法: {eyou:channel type='top'} {eyou:volist name='$field ...
- windows下dubbo-admin2.6.x之后版本的安装
安装zookeeper(单机) 下载bin.tar.gz的版本,解压 conf下的zoo_sample.cfg改zoo.cfg zoo.cfg里添加配置 dataDir=G:/zookeeper-/d ...
- Shadow broker=>fuzzbunch+metasploit 攻击外网测试以及metasploit大批量扫描目标IP
0x01 前言 4月14日,影子经纪人在steemit.com上公开了一大批NSA(美国国家安全局)“方程式组织” (Equation Group)使用的极具破坏力的黑客工具,其中包括可以远程攻破全球 ...