关于小程序:TaroReactTS基于InnerAudioContext封装一个基本的音频组件uniappvue后续更新

为什么要封装一个音频组件次要因为微信小程序官网的audio不保护了,并且在很多iOS真机上的确也存在点击无奈播放,总时长不显示等问题. 音频组件的要求与限度点击播放或者暂停显示播放进度及总时长通过图标变动显示以后音频所处状态(暂停/播放/加载中)页面音频更新时刷新组件状态全局有且只有一个音频处于播放状态来到页面之后要主动进行播放并销毁音频实例资料:icon_loading.gificon_playing.pngicon_paused.png InnerAudioContext提供的属性和办法属性: string src: 音频资源的地址,用于间接播放。bumber startTime: 开始播放的地位(单位:s),默认为 0boolean autoplay: 是否主动开始播放,默认为 falseboolean loop: 是否循环播放,默认为 falsenumber volume: 音量。范畴 0~1。默认为 1number playbackRate: 播放速度。范畴 0.5-2.0,默认为 1。(Android 须要 6 及以上版本)number duration: 以后音频的长度(单位 s)。只有在以后有非法的 src 时返回(只读)number currentTime: 以后音频的播放地位(单位 s)。只有在以后有非法的 src 时返回,工夫保留小数点后 6 位(只读)boolean paused: 以后是是否暂停或进行状态(只读)number buffered: 音频缓冲的工夫点,仅保障以后播放工夫点到此工夫点内容已缓冲(只读)办法: play(): 播放pause(): 暂停。暂停后的音频再播放会从暂停处开始播放stop(): 进行。进行后的音频再播放会从头开始播放。seek(postions: number):跳转到指定地位destory(): 销毁以后实例onCanplay(callback): 监听音频进入能够播放状态的事件。但不保障前面能够晦涩播放offCanplay(callback): 勾销监听音频进入能够播放状态的事件onPlay(callback): 监听音频播放事件offPlay(callback): 勾销监听音频播放事件onPause(callback): 监听音频暂停事件offPause(callback): 勾销监听音频暂停事件onStop(callback): 监听音频进行事件offStop(callback): 勾销监听音频进行事件onEnded(callback): 监听音频天然播放至完结的事件offEnded(callback): 勾销监听音频天然播放至完结的事件onTimeUpdate(callback): 监听音频播放进度更新事件offTimeUpdate(callback): 勾销监听音频播放进度更新事件onError(callback): 监听音频播放谬误事件offError(callbcak): 勾销监听音频播放谬误事件onWaiting(callback): 监听音频加载中事件。当音频因为数据有余,须要停下来加载时会触发offWaiting(callback): 勾销监听音频加载中事件onSeeking(callback): 监听音频进行跳转操作的事件offSeeking(callback): 勾销监听音频进行跳转操作的事件onSeeked(callback): 监听音频实现跳转操作的事件offSeeked(callback): 勾销监听音频实现跳转操作的事件让咱们开始吧???? ...

August 7, 2020 · 5 min · jiezi

关于小程序:TaroReactTS基于InnerAudioContext封装一个基本的音频组件uniappvue后续更新

为什么要封装一个音频组件次要因为微信小程序官网的audio不保护了,并且在很多iOS真机上的确也存在点击无奈播放,总时长不显示等问题. 音频组件的要求与限度点击播放或者暂停显示播放进度及总时长通过图标变动显示以后音频所处状态(暂停/播放/加载中)页面音频更新时刷新组件状态全局有且只有一个音频处于播放状态来到页面之后要主动进行播放并销毁音频实例资料:icon_loading.gificon_playing.pngicon_paused.png InnerAudioContext提供的属性和办法属性: string src: 音频资源的地址,用于间接播放。bumber startTime: 开始播放的地位(单位:s),默认为 0boolean autoplay: 是否主动开始播放,默认为 falseboolean loop: 是否循环播放,默认为 falsenumber volume: 音量。范畴 0~1。默认为 1number playbackRate: 播放速度。范畴 0.5-2.0,默认为 1。(Android 须要 6 及以上版本)number duration: 以后音频的长度(单位 s)。只有在以后有非法的 src 时返回(只读)number currentTime: 以后音频的播放地位(单位 s)。只有在以后有非法的 src 时返回,工夫保留小数点后 6 位(只读)boolean paused: 以后是是否暂停或进行状态(只读)number buffered: 音频缓冲的工夫点,仅保障以后播放工夫点到此工夫点内容已缓冲(只读)办法: play(): 播放pause(): 暂停。暂停后的音频再播放会从暂停处开始播放stop(): 进行。进行后的音频再播放会从头开始播放。seek(postions: number):跳转到指定地位destory(): 销毁以后实例onCanplay(callback): 监听音频进入能够播放状态的事件。但不保障前面能够晦涩播放offCanplay(callback): 勾销监听音频进入能够播放状态的事件onPlay(callback): 监听音频播放事件offPlay(callback): 勾销监听音频播放事件onPause(callback): 监听音频暂停事件offPause(callback): 勾销监听音频暂停事件onStop(callback): 监听音频进行事件offStop(callback): 勾销监听音频进行事件onEnded(callback): 监听音频天然播放至完结的事件offEnded(callback): 勾销监听音频天然播放至完结的事件onTimeUpdate(callback): 监听音频播放进度更新事件offTimeUpdate(callback): 勾销监听音频播放进度更新事件onError(callback): 监听音频播放谬误事件offError(callbcak): 勾销监听音频播放谬误事件onWaiting(callback): 监听音频加载中事件。当音频因为数据有余,须要停下来加载时会触发offWaiting(callback): 勾销监听音频加载中事件onSeeking(callback): 监听音频进行跳转操作的事件offSeeking(callback): 勾销监听音频进行跳转操作的事件onSeeked(callback): 监听音频实现跳转操作的事件offSeeked(callback): 勾销监听音频实现跳转操作的事件让咱们开始吧???? ...

August 7, 2020 · 5 min · jiezi

关于小程序:wepy2-获取元素节点

wepy.pagevar query = wx.createSelectorQuery();query.select('.wrap1').boundingClientRect();query.exec(function (rect) { console.log(rect)});打印是有数据的 wepy.component当我在组件中应用同样办法,返回的是null,很迷茫,直到我看见官网issue https://github.com/Tencent/wepy/issues/2251 微信官网文档 wx.createSelectorQuery()返回一个 SelectorQuery 对象实例。在自定义组件或蕴含自定 义组件的页面中,应应用 `this.createSelectorQuery()` 来代替所以正确的用法: const query = this.$wx.createSelectorQuery();query.select(dom).boundingClientRect();query.exec( (rect) => { console.log(rect)});最初留神wepy中的this. 是 wepy 的实例。和小程序不一样.this.$wx 才是对应的 小程序中的 this

August 7, 2020 · 1 min · jiezi

关于小程序:微信小程序踩坑

1.在scroll-view中不要有fixed定位的元素,会导致fixed元素不能失常固定(ios必现)2.audio音频资源加载中页面onHide后,无奈调用audio组件的api,须要等页面onShow后才可持续调用3.movable-view绑定touchstart事件不能够应用catch否则会使bindchange事件异样4.movable-area和movable-view组件能够在android端cover-view内应用 ios端渲染不进去5.原生写touchmove事件,优先在wxs里写事件函数6.在wxs文件里通过touchmove事件扭转正在进行touchmove事件的元素的地位,会使touchmove事件的参数不正确 而且数值与失常数值差距十分大7.微信小程序只能生成正式版的小程序码,且只能跳转到正式版的小程序,(测试时能够应用微信开发者工具抉择通过二维码编译小程序码,即可在微信开发者工具中关上)8.video组件当进入全屏时通过变量暗藏controls,video全屏时左上角的返回图标还会显示9.小程序蓝牙仅反对低功耗蓝牙(4.0),搜寻的时候也搜寻不到5.0的设施10.BackgroundAudioManager背景音频播放只能应用线上的音频资源11.小程序背景音频播放期间小程序页面onHide,js脚本会继续执行(setInterval等)

August 6, 2020 · 1 min · jiezi

关于小程序:微信小游戏云开发云函数

环境配置创立云函数目录1.新建目录,并在project.config.json减少字段 cloudfunctionRoot 指定寄存云函数的目录,设置胜利后,开发者中的目录会有非凡图标 装置wx-server-sdk云函数目录执行 npm install --save wx-server-sdk@latest创立形式1.工具中创立 建完会默认带这三个文件批改完须要手动上传 2.控制台创立 创立完开发者工具右键云函数目录,同步云函数同步完函数目录会是空的,须要手动增加config、index、package文件

August 5, 2020 · 1 min · jiezi

关于小程序:前端架构发展史

最后,前端是没有架构的,因为性能简略的代码毫无架构可言。通过一个简略的jQuery库操作DOM就能实现的工作,无需简单的设计模式和代码管理机制,也就不须要架构来反对起利用。 前端开发的倒退历史分为以下几个阶段: 古典时代:由后端渲染出前端HTML,用Table布局,用CSS进行简略的辅助动效时代:前端开始编写一些简略的JavaScript脚本来做动画成果,如轮播广告Ajax异步通信时代:2005年,Google在诸多Web利用中应用了异步通信技术如 Google地图,开启了Web前端的一个新时代一旦前端利用须要从后端获取数据,就意味着前端利用在运行时是动静地渲染内容的,这便是Model(模型)UI层解耦。jQuery可能提供DOM操作方法和模型引擎等。这时的开发人员须要做上面两件事: 动静生成HTML。由后端返回前端所须要的HTML,再动静替换页面的DOM页面。晚期的典型架构如jQuery Mobile,当时在前端写好模板与渲染逻辑,用户的行为触发后盾并返回对应的数据来渲染文件模板拆散。由后端用API返回前端所须要的JSON数据,再由前端来计算生成这些HTML。前端的模板再应用HTML,而是应用诸如 Mustache 这样的模板引擎来渲染HTML因为HTML的动静生成、模板的独立与拆散,前端利用开始变得复杂。后端的MVC架构进一步影响了前端开发,便诞生了一系列操起的MVC框架,如Backbone、Knockout等。与此同时,在 Ryan Lienhart Dahl等人开发了Node.js之后,前端的软件性能便一直地改善: 更好的构建工具。诞生了诸如 Grant 和 Gulp 等构建工具包治理。产生了用于前端的包管理工具 Bower 和 Npm模块治理。也呈现了AMD、Common.js 等不同的模块治理计划随着单页面利用的风行,前后端拆散框架也成为行业内的规范实际。由此,前端进入了一个新的时代,要思考的内容也越来越多: API 治理,采纳了诸如 Swagger 的 API 管理工具,各式的 Mock Server 也成为规范实际。大前端,由前端来开发跨平台挪动利用框架,采纳诸如 Ionic、React Native、Flutter 等框架。组件化,前端利用从此由一个个细小的组件联合而成,而不再是一个大的页面组件。零碎变得越来越简单,架构在前端的作用也变得越来越重要。MVC 满足不了开发人员的需要,于是采纳了组件化架构。而组件化 + MV 也无奈应答大型的前端利用,微前端便又呈现在咱们的背后,它解决了以下问题: 跨框架。在一个页面上运行,能够同时应用多个前端框架。利用拆分。将一个简单的利用拆解为多个渺小的利用,相似于微服务。遗留零碎迁徙。让旧的前端框架,能够间接嵌入现有的利用运行。简单的前端利用倒退了这么久,也呈现了一系列须要演进的利用:思考重写、迁徙、重构,等等。 本文由博客一文多发平台 OpenWrite 公布!

August 2, 2020 · 1 min · jiezi

关于小程序:前端架构发展史

最后,前端是没有架构的,因为性能简略的代码毫无架构可言。通过一个简略的jQuery库操作DOM就能实现的工作,无需简单的设计模式和代码管理机制,也就不须要架构来反对起利用。 前端开发的倒退历史分为以下几个阶段: 古典时代:由后端渲染出前端HTML,用Table布局,用CSS进行简略的辅助动效时代:前端开始编写一些简略的JavaScript脚本来做动画成果,如轮播广告Ajax异步通信时代:2005年,Google在诸多Web利用中应用了异步通信技术如 Google地图,开启了Web前端的一个新时代一旦前端利用须要从后端获取数据,就意味着前端利用在运行时是动静地渲染内容的,这便是Model(模型)UI层解耦。jQuery可能提供DOM操作方法和模型引擎等。这时的开发人员须要做上面两件事: 动静生成HTML。由后端返回前端所须要的HTML,再动静替换页面的DOM页面。晚期的典型架构如jQuery Mobile,当时在前端写好模板与渲染逻辑,用户的行为触发后盾并返回对应的数据来渲染文件模板拆散。由后端用API返回前端所须要的JSON数据,再由前端来计算生成这些HTML。前端的模板再应用HTML,而是应用诸如 Mustache 这样的模板引擎来渲染HTML因为HTML的动静生成、模板的独立与拆散,前端利用开始变得复杂。后端的MVC架构进一步影响了前端开发,便诞生了一系列操起的MVC框架,如Backbone、Knockout等。与此同时,在 Ryan Lienhart Dahl等人开发了Node.js之后,前端的软件性能便一直地改善: 更好的构建工具。诞生了诸如 Grant 和 Gulp 等构建工具包治理。产生了用于前端的包管理工具 Bower 和 Npm模块治理。也呈现了AMD、Common.js 等不同的模块治理计划随着单页面利用的风行,前后端拆散框架也成为行业内的规范实际。由此,前端进入了一个新的时代,要思考的内容也越来越多: API 治理,采纳了诸如 Swagger 的 API 管理工具,各式的 Mock Server 也成为规范实际。大前端,由前端来开发跨平台挪动利用框架,采纳诸如 Ionic、React Native、Flutter 等框架。组件化,前端利用从此由一个个细小的组件联合而成,而不再是一个大的页面组件。零碎变得越来越简单,架构在前端的作用也变得越来越重要。MVC 满足不了开发人员的需要,于是采纳了组件化架构。而组件化 + MV 也无奈应答大型的前端利用,微前端便又呈现在咱们的背后,它解决了以下问题: 跨框架。在一个页面上运行,能够同时应用多个前端框架。利用拆分。将一个简单的利用拆解为多个渺小的利用,相似于微服务。遗留零碎迁徙。让旧的前端框架,能够间接嵌入现有的利用运行。简单的前端利用倒退了这么久,也呈现了一系列须要演进的利用:思考重写、迁徙、重构,等等。 本文由博客一文多发平台 OpenWrite 公布!

August 2, 2020 · 1 min · jiezi

关于小程序:微信小程序-wxrequest-载入数据提示-URL-不合法

在微信小程序筹备应用 wx.request 载入数据的时候提醒 URL 不非法的谬误。 提醒的内容是: 不在以下 request 非法域名列表中,请参考文档 解决问题你须要登录微信小程序的后盾。 抉择开发中的开发设置。 在界面中的服务器域名配置中,批改配置你的 Request 非法域名。 依据官网的指引,request 的非法域名须要应用 https 如果你的域名还没有 https CA 签名的话,请先进行 CA 签名。 而后保留退出。 在小程序开发工具中,你须要退出后,从新刷新页面。 当页面再次刷新后,你应该不会遇到域名谬误的提醒了。 https://www.ossez.com/t/wx-request-url/321

July 31, 2020 · 1 min · jiezi

关于小程序:记录一次逆推小程序的实现逻辑

偶尔见看到敌人分享的小程序,感觉做的不错,对他的实现比拟感兴趣,于是开始剖析他是怎么做的: 第一步:Charles抓包charles配置 windows版https://www.cnblogs.com/htybk... 可能是最好的Mac Charles 配置指南https://blog.csdn.net/u010296... Charles 抓包 Client SSL handshake failed - Remote host closed connection during handshakehttps://www.jianshu.com/p/993...https://www.neglectedpotentia... 通过以上链接胜利搞定Mac SSL证书和 手机端SSL证书,此时关上小程序 能够看到申请链接 第二步:拿到申请后剖析图床和视频库用什么实现的依据下面这张图片 能够发现vod_pic参数vod_pic": "http://puui.qpic.cn/qqvideo_ori/0/r3020nq7ixl_496_280/0", 域名为qpic.cn,于是我百度了下qpic搜寻发现是腾讯图床,此时我看到content参数只有:"content": "r3020nq7ixl", 于是就有个疑难:视频怎么做到的;此时我看了下视频播放时 存在如下申请:域名竟然是tc.qq.com我想会不会是腾讯视频,于是我关上腾讯视频轻易找了一个短视频关上,看到地址链接为:https://v.qq.com/x/page/o3125... 此时我就想把 "content": "r3020nq7ixl" 改为 https://v.qq.com/x/page/r3020...果然申请对应上了,视频资源也对上了。 阐明这老哥的小程序图床和视频库资源是基于腾讯视频,同时播放器我看了下小程序示例,就是原生的播放器 第三步:日常怎么经营保护资源的而后我在想:如果本人经营的话,天天搬砖也挺累的,就随机看了他几个板块的视频 对应到腾讯视频的发布者,发现不是同一个人,此时明确了,这老哥可能采纳关键词爬虫腾讯视频或者本人有一个后盾管理系统日常更新对应类型的视频地址到本人的数据库中; 以上是整个逆推过程,如果感觉有意思,能够点赞哈,谢谢~

July 30, 2020 · 1 min · jiezi

关于小程序:记录一次逆推小程序的实现逻辑

偶尔见看到敌人分享的小程序,感觉做的不错,对他的实现比拟感兴趣,于是开始剖析他是怎么做的: 第一步:Charles抓包charles配置 windows版https://www.cnblogs.com/htybk... 可能是最好的Mac Charles 配置指南https://blog.csdn.net/u010296... Charles 抓包 Client SSL handshake failed - Remote host closed connection during handshakehttps://www.jianshu.com/p/993...https://www.neglectedpotentia... 通过以上链接胜利搞定Mac SSL证书和 手机端SSL证书,此时关上小程序 能够看到申请链接 第二步:拿到申请后剖析图床和视频库用什么实现的依据下面这张图片 能够发现vod_pic参数vod_pic": "http://puui.qpic.cn/qqvideo_ori/0/r3020nq7ixl_496_280/0", 域名为qpic.cn,于是我百度了下qpic搜寻发现是腾讯图床,此时我看到content参数只有:"content": "r3020nq7ixl", 于是就有个疑难:视频怎么做到的;此时我看了下视频播放时 存在如下申请:域名竟然是tc.qq.com我想会不会是腾讯视频,于是我关上腾讯视频轻易找了一个短视频关上,看到地址链接为:https://v.qq.com/x/page/o3125... 此时我就想把 "content": "r3020nq7ixl" 改为 https://v.qq.com/x/page/r3020...果然申请对应上了,视频资源也对上了。 阐明这老哥的小程序图床和视频库资源是基于腾讯视频,同时播放器我看了下小程序示例,就是原生的播放器 第三步:日常怎么经营保护资源的而后我在想:如果本人经营的话,天天搬砖也挺累的,就随机看了他几个板块的视频 对应到腾讯视频的发布者,发现不是同一个人,此时明确了,这老哥可能采纳关键词爬虫腾讯视频或者本人有一个后盾管理系统日常更新对应类型的视频地址到本人的数据库中; 以上是整个逆推过程,如果感觉有意思,能够点赞哈,谢谢~

July 30, 2020 · 1 min · jiezi

关于小程序:小程序图片下载实用

以下内容 间接放入即可 亲测无效单张下载<!-- HTML --><div @click="saveImage"> 下载图片 </div>/* methods */saveImage() { wx.downloadFile({ url:'http://upload.jianshu.io/admin_banners/web_images/4435/c1d3ca63353c8bd527f0d781605516cb5b266d02.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/1250/h/540', success: function(res) { if (res.statusCode === 200) { let img = res.tempFilePath; wx.saveImageToPhotosAlbum({ filePath: img, success(res) { console.log('胜利') }, fail(res) { console.log('保留失败') } }); } } }); }多张下载<!-- HTML --><div @click="saveImage"> 下载图片 </div>/* methods */saveImage() { let picArr=['http://upload.jianshu.io/admin_banners/web_images/4435/c1d3ca63353c8bd527f0d781605516cb5b266d02.jpg','http://47.102.105.248:8805/img-api/202007/24/1595585519996221273.png'] this.xiazaiTupian(picArr) }, //下载内容 xiazaiTupian: function(picArr,index) { let that=this; index=index||0; console.log(picArr[index]) wx.downloadFile({ url: picArr[index], success: function (res) { var temp = res.tempFilePath console.log(index) console.log(temp) wx.saveImageToPhotosAlbum({ filePath: temp, success: function () { index+=1; if (index < picArr.length){ that.xiazaiTupian(picArr, index); }else{ wx.showToast({ title: '下载实现', }) } }, fail: function () { index += 1; if (index < picArr.length) { that.xiazaiTupian(picArr, index); } else { wx.showToast({ title: '下载实现', }) } wx.showToast({ title: '第' + (index+1) + '下载失败', }) } }) }, fail: function (res) { wx.showToast({ title: '下载失败', }) } }) },

July 27, 2020 · 1 min · jiezi

关于小程序:解决小程序downloadFile下载图片返回临时路径后缀为unknown的问题

在开发过程中我发现,微信开发工具中调用wx.downloadFile返回的长期门路时没有任何问题,,然而在安卓真机调试的时候发现返回的长期门路居然是一个后缀为.unknown的链接,这也就是保留到相册失败的起因针对这个问题,咱们须要自定义图片名称,并且传入filePath指定文件下载后存储的门路。 let fileName = new Date().valueOf() let filePath = wx.env.USER_DATA_PATH + '/' + fileName + '.png' const downloadTask = wx.downloadFile({ url: "https://example.com/audio/123", filePath: filePath, success: (res) => { if (res.statusCode === 200) { wx.saveImageToPhotosAlbum({ filePath: filePath, success: (data) => { wx.showToast({ title: '保留胜利', icon: 'success', duration: 2000 }) }, fail: err=>{ console.log(err) } }) } } })快来试试吧

July 25, 2020 · 1 min · jiezi

关于小程序:小程序开发注意事项

1. 开发小程序时,每个页面肯定要在app.json文件中注册,页面文件夹和其蕴含的四个文件的名字要保持一致。 2. 小程序发动的都是HTTPS网络申请,在开发调试的过程中能够不校验协定和TLS版本,但在实际上线后必须进行HTTPS协定通信。 3. 小程序能够进行组件化开发以及数据绑定,所有对于DOM的操作都是基于数据驱动的,并没有间接进行DOM操作的做法,换言之,小程序内没有document对象,原生js和jQuery里的DOM操作思维要舍弃掉。 4. 小程序的网络申请wx.request()是不自带Cookies的,这和浏览器上的网络申请不同,因而基于Cookies实现的会话治理不适用于小程序。 5. 小程序的脚本文件中,内置对象是page,而非传统浏览器里的window,因而所有基于window对象来写的库(例如jQuery)都不适用于小程序。 6. 小程序提供模板性能,模板领有本人的作用域,它只能应用从data属性传入的数据。 7. 每一个页面文件夹下的.json文件是用来写配置项的,如果该页面无需增加相干配置,.json文件也要写上一对大括号(“{ }”),否则会报错。 8. 在同一个tab里的页面能够跳转,并且容许携带参数。不同tab的页面之间无奈跳转,应用wx.navigateTo()接口会报错。同时,tab之间的跳转能够用wx.switchTab()实现,然而门路后不能带参数。 9. 脚本文件里data的数据,在更新的时候要通过this.setData()办法来更新,而不能间接用“=”来做。 10. 在组件标签里,能够通过“data-属性值”的形式绑定咱们须要的数据,而后在事件内置event对象里进行获取。 11. 小程序里也存在事件的冒泡,具体的冒泡事件能够参考官网文档,如果心愿事件向上冒泡,则应用bind来绑定事件,若心愿阻止事件冒泡,就应用catch来进行事件绑定。 12. 小程序反对文件援用,有import和include两种形式,import有作用域,也就是引入的指标文件里import的模板不会被引入;而include等于是将指标文件除<template />以外的整个代码进行引入。 13. wx.login()和wx.getUserInfo()是两个独立的接口,前者能够实现用户登录,这个过程是悄无声息的,不须要用户受权,登录后能够拿到用户的openid和session_key;而wx.getUserInfo()能够拿到用户的具体信息,这个过程须要取得用户的受权,开发时也必须思考用户回绝受权的场景。 14. 目前小程序能够分享给微信好友和微信群,但小程序默认是没有这个性能的,只有在Page里定义了onShareAppMessage事件处理函数,点击小程序右上角才能够看到分享按钮。 15. 微信小程序还在一直的成长中,定期会有相干的API批改和减少、以及废除,开发者须要及时关注每一次重大的版本更新,同时对于一些新出的API要进行兼容解决,思考兼容的场景,因为某些API只在高版本的微信app里无效。

July 23, 2020 · 1 min · jiezi

关于小程序:答题小程序PHP版

简介智汇答题Plus小程序实用于考核,评测等场景,分为五大性能:练习,考试,错题,珍藏,排名; 练习性能分为程序答题和随机答题,模式分为答题模式和背题模式,答题模式能够在答完题目显示正确答案和帮忙提醒,能够进行跳题作答,背题模式能够间接查看正确答案和帮忙提醒,实时查看答题卡,统计答题状况,记忆性能,可能持续上次答题,也能够革除答题记录,从新答题。 考试性能次要包含倒计时性能,随机取题性能,可独自对每个分类设置取题数量,答题工夫,能够进行跳题作答,交卷评分,倒计时主动提醒交卷;记忆性能,保留可下次持续做题。 错题集性能次要是针对练习和答题两大模块的作答错题进行分类收集,可像练习性能一样进行答题模式和背题模式的作答形式,可移除错题,具备针对性的答题。 珍藏性能能够针对重点题目,谬误题目进行珍藏,而后从新重点练习;排名性能能够对每套试卷的作答人员进行分数等排名;答题记录能够随时查看用户的测试记录;针对部门考核,能够开启信息审核性能,只有通过审核的人员才可进入答题。反对开启和禁用练习性能。 本程序还搭配治理后盾,治理用户,零碎设置,后盾审核用户信息,发送模板音讯告诉用户,能够随时减少套题,减少题目,编辑题目,删除题目,以及应用模板批量的导入题目,查看答题记录,查看反馈意见等,十分不便实用!还附带阐明残缺的部署操作文档,以及小程序上线操作。 运行环境PHP >=5.5.9 && PHP <=7.2MySQL >=5.1Apache、IIS、Nginx留神域名必须备案小程序必须应用https协定 443端口效果图

July 23, 2020 · 1 min · jiezi

关于小程序:小程序分享朋友圈开启新流量市场

小程序开启分享性能,接入微信朋友圈流量入口背景2020年7月8日之前,百度搜寻小程序分享朋友圈,各个平台简直都是生成二维码之后的图片分享案例文章。而在2020年7月8日凌晨,微信正式开启了小程序分享朋友圈性能,并在7月8日开始进行公测。公测告诉发放至各个经营良好的小程序平台后盾。 初期仅开发者可分享小程序到朋友圈,之后在7月16日时灰度测试安卓用户——遵循常例苹果端前期上线同类型性能。 7月8日凌晨,微信外部研发者发送出一条小程序分享朋友圈的音讯,标记着小程序分享朋友圈性能的推出,小程序终于关上了朋友圈这条呼声已久的“电商微商流量池”。 音讯刚出便引起各界关注和媒体报道。微信系产品在用户眼里是一个继续关注用户体验、不断更新的社交工具,现在国人简直都离不开这个工具。而小程序自问世以来从不被看好到追随O2O业务方兴未艾再到近期小程序直播的衰亡,现在买通了“微信内最大的流量入口”朋友圈,是发力愈来愈狠的节奏。百度、阿里也见好相继推出了小程序业务,甚至国外也开始倒腾相似小程序的技术。此次分享朋友圈性能的呈现对电商、内容类小程序影响极大,取得内测告诉几小时后,相干电商及内容小程序平台纷纷上线了“分享朋友圈”性能。电商类小程序比方糖纸,玩物志好物商店、内容型小程序如亿邦APP、工具类小程序如有赞的“抽奖助手”,都第一工夫上线了该性能。 上线办法小程序分享朋友圈性能见文档https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html。相干代码、注意事项、经营标准都很明确。整体从开发到上线最快三四个小时可实现。须要留神的是:小程序为躲避歹意分享,不容许账号信息、诱导分享类信息分享朋友圈。因而滥用该性能的游戏类的小程序审核会更加严格。而小程序本身也制订了凋谢标准:朋友圈点击后不会间接进入小程序,而是进入小程序卡片页——单页模式,点击右下角“返回小程序”才能够真正进入该小程序。这一动作很好地保障了用户体验,推动更多精品小程序良性倒退。 小程序分享朋友圈性能暂未全副凋谢,目前仅限安卓用户(且在灰度测试中),但对小程序运营者无疑是个大利好消息,能够预感将来朋友圈中会多出很多带小程序符号的小程序页面分享,咱们能够更高效地理解一个小程序产品的风貌。 二次验证码小程序,一键分享朋友圈二次验证码小程序作为小众的平安工具利用,2016年随小程序内测呈现上线的产品,受到百万忠诚用户拥趸。便捷、牢靠的防黑客撞库攻打办法从同类利用中怀才不遇。并在未做经营状况下用户自主疯长至百万。此次分享朋友圈性能,二次验证码小程序可分享【首页】、【备份&复原】、【云服务】页面。别离对应密钥的增加、复原、找回。 二次验证码小程序优于同类利用之处,除了作为小程序比APP轻便,即搜即用——它作为双因素验证工具,应用RFC6238协定的基于工夫、密钥、事件三因素的TOTP算法,还能够找回失落的验证码。该云服务性能可找回丢手机、换手机、刷机、手机故障、移除/删除小程序、误删数据等状况造成的验证码遗失问题。该性能极大地解决了失落验证码的用户想要及时登陆平台的问题。因为云服务性能须要安防保护,二次验证码小程序采纳了AES256算法,使得黑客暴力破解简直不可能;采纳CSPRNG加不可预测的随机盐,辅以高级加密技术:100000轮PBKDF2-SHA256算法,即使是公司后盾技术研发,也无奈破解到用户信息。 二次验证码用户遍布政府、媒体、企业、游戏、区块链等行业,在开启一键分享朋友圈性能后,将更加不便用户自发流传应用。有了每30秒主动变动一次的二次验证码,即使有人获取了用户的账号、明码,截获了用户的手机、邮件验证码,他们仍然无奈进入平台。 二次验证码,为用户信息资产保驾护航。

July 22, 2020 · 1 min · jiezi

关于小程序:微信小程序上拉加载与下拉刷新

上拉加载利用场景:微信内容页上拉加载,拉到最底部呈现提醒文案 思路:1.初始页号为12.应用微信自带的办法onReachBottom检测滚动到底部,页号pageNo+1,而后去申请后盾接口,把最新返回的后果增加到原来的数组里,从新渲染思路有了那么咱们开始上代码把3.当你调取的接口里的数据length<pageSize Page({ data: { page: 1, pages: 0, articles: [] }, onLoad(options) { // 页面首次加载,申请第一页数据 this.getInfoListData(1) }, onReachBottom() { // 下拉触底,先判断是否有申请正在进行中 // 以及查看以后申请页数是不是小于数据总页数,如符合条件,则发送申请 if (!this.loading && this.data.page < this.data.pages) { this.getInfoListData(this.data.page + 1) } }, getInfoListData(pageNo) { this.loading = true // 向后端申请指定页码的数据 return getArticles(pageNo).then(res => { const articles = res.items this.setData({ page: pageNo, //以后的页号 pages: res.pages, //总页数 articles: this.data.articles.concat(articles) }) }).catch(err => { console.log( err) }).then(() => { this.loading = false }) }})下拉刷新1.配置json ...

July 21, 2020 · 1 min · jiezi

微信小程序滑动切换导航-导航栏跟随滚动导航-顶部tab导航

前言很多App都有这种设计,例如淘宝、爱奇艺、今日头条、知乎等都有用到,大部分的App都会用到这种设计,十分支流。 tab导航栏应用<scroll-view>标签,内容应用<swiper>,不多说,间接上代码,为了更实在展现实例的应用,我间接就配置了服务器来取数据进行渲染。 index.wxml<view class="container"> <!-- tab导航栏 --> <!-- scroll-left属性能够管制滚动条地位 --> <!-- scroll-with-animation滚动增加动画过渡 --> <scroll-view scroll-x="true" class="nav" scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}"> <block wx:for="{{navData}}" wx:for-index="idx" wx:for-item="navItem" wx:key="idx"> <view class="nav-item {{currentTab == idx ?'active':''}}" data-current="{{idx}}" bindtap="switchNav">{{navItem.text}}</view> </block> </scroll-view> <!-- 页面内容 --> <swiper class="tab-box" current="{{currentTab}}" duration="300" bindchange="switchTab"> <swiper-item wx:for="{{yxlist}}" wx:for-item="tabItem" wx:for-index="idx" wx:key="idx" class="tab-content"> <view>{{tabItem.yxname}}</view> <image src="{{tabItem.yxlogo}}" style="width:100px;height:100px;"></image> </swiper-item> </swiper></view>index.wxss/**index.wxss**/page{ width: 100%; height: 100%;}.container{ width: 100%; height: 100%;}.nav { height: 80rpx; width: 100%; box-sizing: border-box; overflow: hidden; line-height: 80rpx; background: #f7f7f7; font-size: 16px; white-space: nowrap; position: fixed; top: 0; left: 0; z-index: 99;}.nav-item { width: 20%; display: inline-block; text-align: center;}.nav-item.active{ color: red; font-weight: bold;}.tab-box{ background: #fff; padding-top: 80rpx; height: 100%; box-sizing: border-box;}.tab-content{ overflow-y: scroll;}index.js//index.js//获取利用实例const app = getApp()Page({ data: { motto: 'Hello World', userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo'), navData:[ { text: '广科' }, { text: '广东理工' }, { text: '广石油' }, { text: '广东工商' }, { text: '广州科技' }, { text: '白云' }, { text: '肇庆' }, { text: '嘉应' }, { text: '华商' } ], currentTab: 0, navScrollLeft: 0 }, //事件处理函数 onLoad: function () { var that = this; //向后端服务器发动申请数据 wx.request({ //URL url: 'https://www.likeyun.cn/api/yxlist.json', //发送的数据 data: {}, //申请的数据时JSON格局 header: { 'Content-Type':'application/json' }, //申请胜利 success: function (res) { //控制台打印(开发调试用) console.log(res.data) //把所有后果存进一个名为yxlist的数组 that.setData({ yxlist: res.data.yuanxiaolist, }) } }) wx.getSystemInfo({ success: (res) => { this.setData({ pixelRatio: res.pixelRatio, windowHeight: res.windowHeight, windowWidth: res.windowWidth }) }, }) }, switchNav(event){ var cur = event.currentTarget.dataset.current; //每个tab选项宽度占1/5 var singleNavWidth = this.data.windowWidth / 5; //tab选项居中 this.setData({ navScrollLeft: (cur - 2) * singleNavWidth }) if (this.data.currentTab == cur) { return false; } else { this.setData({ currentTab: cur }) } }, switchTab(event){ var cur = event.detail.current; var singleNavWidth = this.data.windowWidth / 5; this.setData({ currentTab: cur, navScrollLeft: (cur - 2) * singleNavWidth }); }})成果演示 ...

July 12, 2020 · 3 min · jiezi

记一次小程序开发的踩坑之旅

问题最近跟着慕课网上的课程在做一个网易云音乐小程序,遇到了一个进度条回跳的 bug,这里记录一下踩坑和解决的过程。 具体情况见下图: 预期行为:在拖拽进度条之后,间接达到拖拽之后的地位 理论行为:在拖拽进度条之后,会首先回跳到拖拽之前的地位,而后再跳到拖拽之后的地位。 模仿调试的 bug代码逻辑无论如何,先来看一下代码的逻辑: 页面构造如下,左右两个 text 显示工夫就不说了,次要是两头的进度条。这个进度条没有应用小程序原生提供的 slider 来做,而是采纳 movable-area 和 movable-view 相结合的形式,movable-area 划出了一块可供滑动的区域,而 movable-view 则是两头能够拖拽的滑块。拖拽滑块的时候会有个 x 来记录拖拽间隔,同时绑定 onXChange 事件监听 x 的变动,绑定 onTouchEnd 事件监听拖拽松手的动作。另外,上面还有一个 progress 组件,这个是用来显示进度的,曾经播放的进度给个红色款式。 <view class="container"> <text class="time">{{showtime.currentTime}}</text> <view class="control"> <movable-area class="movable-area"> <movable-view class="movable-view" direction="horizontal" damping="1000" x="{{movableDist}}" bindchange="onXchange" bindtouchend="onTouchEnd"> </movable-view> </movable-area> <progress percent="{{progress}}" stroke-width="4" backgroundColor="#969696" activeColor="#fff"></progress> </view> <text class="time">{{showtime.totalTime}}</text> </view>一旦确定 x 的变动来源于用户的拖拽,就在onXChange 里依据比例关系设置好进度。这里要留神的是,在用户拖拽没松手的时候先不进行 setData 渲染视图层的操作 —— 因为用户可能会频繁进行拖拽,咱们要防止频繁的 setData 带来的性能损耗。所以,这里只是把数据保留下来,期待渲染。 onXchange(event){ if(event.detail.source == "touch"){ ratio = event.detail.x / (movableAreaWidth - movableViewWidth) this.data.progress = ratio * 100 this.data.movableDist = event.detail.x }},用户一旦松手,根本就能够确定他曾经把滑块拖拽到了指标地位,这时候就进行正式的 setData 操作,同时调用 seek 办法让歌曲跳转到对应的地位去播放 ...

July 11, 2020 · 2 min · jiezi

微信小程序开发工具提示-Login-不能获得-ID-的问题解决

在对微信小程序进行调试的时候,遇到取得 ID 的谬误。 错误信息如下: mp-openid-01830×645 34.6 KB 这时候,你可用尝试将 cloudfunctions下的login 文件夹创立并部署,装置云依赖。 这句话的英文切实是太难了解了。 其实要求的是将你程序代码中的 cloudfunctions 下的文件夹。 如下图所标识的地位。 对应的英文环境,应该是下面的选项。 当上传实现后,将会在右上角提醒你的上传状态。 校验 ID而后你可用回到首页,而后从新刷新后取得 OpenID。 如果一切正常,你应该能够看到取得后的 OpenID。 下面的内容就是曾经取得的 OpenID。 https://www.ossez.com/t/login-id/254

July 11, 2020 · 1 min · jiezi

微信小程序开发工具初始化代码仓库

微信小程序开发工具应用 Git 来进行治理的。 你可用应用微信的 Git 服务。 单击下面的 代码管制。 如果是第一次应用的话,将会要求你对本地代码仓库进行初始化。 当你初始化实现后,你会看到上面的界面: 下面显示的是本地代码仓库曾经初始化实现了。 然而你的代码还没有上传到服务器上。 单击下面的链接,将会进入网页版本的代码治理中。 如果是第一次的话,你须要对你的账号初始化。 而后你能够设置账号保留。

July 11, 2020 · 1 min · jiezi

微信小程序开发如何初始化远程仓库并-PUSH

你须要先初始化近程仓库,一般来说你能够间接用微信的 Git,你也能够用其余的 Git。 假如咱们这里应用微信自带的 Git。 拜访的地址为:https://git.weixin.qq.com/ 如果你没有受权的话,你首先须要进行受权,如果曾经受权的话。 你可用进入你的项目组。 在这里你可用看到你曾经领有的项目组,Git 遵循的构造是项目组 > 我的项目。 你的微信小程序我的项目,必须要属于一个项目组。 抉择你心愿进入的项目组。 创立我的项目在首页中,你可用抉择创立我的项目。 在后续的页面中,输出你心愿创立的项目组名称和你的项目名称,而后单击创立后持续。 在后序的我的项目中,你可用找到你的创立的我的项目的地址。 拷贝这个地址信息. 在开发环境中设置近程地址当你曾经有我的项目的近程地址后,你能够在你的本地我的项目中设置你近程仓库地址。 右键后抉择增加 输出名字和地址后保留。 这里的名字其实是仓库的名字,你可用选你的名字,很多时候 Git 默认会应用 origin 为规范的名字,感觉开发工具这里名字这里有点绕。 而后你可用保留退出。 推送 PUSH当所有都配置好当前,你可用抉择 Push 进行推送到近程。 在弹出的对话框中,上面须要你手动写近程的分支的名字,如果你想和你本地统一,你可用应用 master。你也能够应用不同的分支名字。 这里是手动输出的,有点绕。 Push 提醒受权失败如果你提醒受权失败,你须要进入微信的 Git 网站中,设置一个明码。 你也能够在账户设置的门路下设置明码。 如何还是提交失败的话,你能够在你本地仓库中的受权设置中设置用户名和明码。 微信开发工具中自带的这个 Git 性能,切实是有点蹩脚,不倡议你应用这个工具,你可用应用其余的一些可视化工具,比这个好很多很多。 这是你在最先开始开发的时候可能遇到的一个坑。 https://www.ossez.com/t/push/250

July 11, 2020 · 1 min · jiezi

苹果小程序App-Clips-和微信小程序区别在哪我们做了一次上手实操

作者|何世友、彭权华阅读原文 6 月 23 日,Apple Park 的观众席上空无一人,但此时一场特别的「科技春晚」正在上演。 在 2020 年的 WWDC 大会中,自 iOS 7 以来变动最大的一次更新——iOS 14 来了,AirPods Pro 有了黑科技,ARM Mac 也来了。但对小程序开发者来说,他们最关心的应该还是此次 WWDC 发布的 App Clips 了。 「一个无需下载应用,就能使用 app 的功能。」这听上去是不是和小程序有点相似,但这是 App Clips,也被一部分人称为「苹果小程序」。它是什么?它和小程序有什么不同?我们该怎么开发 App Clips? 别急,一篇文章给你解答。 App Clips 从哪里来?App Clips(应用片段) 作为 WWDC2020 上最值得关注的特性之一,由于缺乏官方示例,是用户感知度最低的新功能。同时,因为和微信小程序过于相似的产品形态设定,也被部分开发者冠以「苹果牌小程序」的昵称。 官方对其的定义是—— App clips are a great way for users to quickly access and experience what your app has to offer. An app clip is a small part of your app that’s discoverable at the moment it’s needed. App clips are fast and lightweight so a user can open them quickly.应用片段让用户可以快速体验应用。一个应用片段是应用的一小部分,可以在需要的时候被发现。应用片段快速而轻巧,因此用户可以快速打开它们。 ...

July 8, 2020 · 2 min · jiezi

wxParse无法解析html

第一步错误代码: <span style="color:red;font-family:" serif",tahoma,verdana,helvetica;font-size:12px;font-style:normal;font-weight:400;text-decoration:none;"="" sans="">XXXX</span> 一直以为是多个双引号引起的bug。最终发现是font-family后面多了个空格导致的。 第二步找到wxParse.js文件,把style后有空格的去掉,问题就解决 var arr1 = data.split('style=')var ping = arr1[0] + "style=" + arr1[1].replace(/\s/g, "") ;

July 3, 2020 · 1 min · jiezi

添加到我的小程序提示组件

Mini-add-tips 用于提示用户首次进入小程序时,点击右上角菜单进行【添加到我的小程序】操作特性与支付宝原收藏组件(添加到首页)保持样式一致,支持在自定义导航栏场景下保持一致效果。 预览截图 样例在开发者工具预览 安装使用1. 获取组件下载release(稳定)latest release master(最新)git clone https://github.com/MakerGYT/mini-add-tips.git将项目中components/add-tips文件夹拷贝到组件路径下 2. 引入组件在使用该组件的页面对应json文件中添加: { "usingComponents": { "add-tips":"/components/add-tips/index" }}3. 使用组件<!-- index.wxml --><add-tips name="示例"/>自定义导航栏请参考/pages/index 属性列表属性类型默认值必填说明nameString测试否小程序名称logoString<img src="https://imgkr.cn-bj.ufileos.com/c958e4cd-6bab-43ed-93aa-697207cf33a5.png" width=50/>否小程序LogodurationNumber10否持续显示时间(s)delayNumber2否进入页面延迟时间(s)开始显示customBooleanfalse否当前页面是否{"navigationStyle": "custom"}开发说明鉴于目前微信基础库的设计: 收藏操作与添加到我的小程序对于用户容易混淆,但效应一样,故没必要具体引导用户。目前只有监听用户点击右上角菜单“收藏”按钮的行为,但实际上兼听不到收藏行为,只能定义收藏内容无法获知是否已经收藏、是否已经添加到我的小程序,故提示可能对用户造成干扰。目前没有可以调起添加小程序的api、button,或许出于"降低干扰度"的考虑,但就迫使手动设置引导,又会造成如2中所述干扰。即便已经设置{"navigationStyle": "custom"},其导航栏相关的api依然调用是有效的,无论组件还是页面内均无法据此获知导航栏是否custom,只能由外部传入。Todo[ ] 根据用户使用小程序频次、收藏等行为,智能控制显示区间及显示时机。LicenseMIT © MakerGYT

July 2, 2020 · 1 min · jiezi

如何使用top查看程序的内存占用情况

RT 19    0.00   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 20    0.01   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 21    0.00   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 22    0.01   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 23    0.00   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 32    0.00   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 33    0.02   0.2%   0.0%   0.0%  99.8%   0.0%   0.0%   0.0%   0.0% 34    0.87  92.0%   0.0%   2.0%   6.0%   0.0%   0.0%   0.0%   0.0% 35    0.02   2.2%   0.0%   0.0%  97.8%   0.0%   0.0%   0.0%   0.0% 36    0.00   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 37    0.03   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 38    0.03   0.0%   0.0%   0.0% 100.0%   0.0%   0.0%   0.0%   0.0% 39    0.02   0.2%   0.0%   0.0%  99.8%   0.0%   0.0%   0.0%   0.0% ---   ----  -----  -----  -----  -----  -----  -----  -----  ----- avg   0.04   3.8%   0.0%   0.2%  96.0%   0.0%   0.0%   0.0%   0.0% System Page Size: 4Kbytes Memory: 71911060K (17913792K) real, 75552736K (19746536K) virtual, 15590520K free  Page# 1/43 CPU TTY  PID USERNAME PRI NI   SIZE    RES STATE    TIME %WCPU  %CPU COMMAND 34   ? 17731 bill     234 20   309M   216M run     42:58 95.48 95.31 fileinstore 33   ?   132 root     152 20 62712K 55744K run    147:17  2.56  2.55 vxfsd 39   ? 18842 billtest 168 20 94296K 11656K sleep   45:43  1.91  1.91 GuardMain 19   ?  4192 bill     168 20   105M 23456K sleep   57:38  1.91  1.90 GuardMain 34   ?   136 root     152 20  4608K  4096K run      4:26  1.25  1.25 pagezerod 只能看到五个进程 使用top -s10 -d20|grep 我的程序pid 什么都不显示 hp-un

July 1, 2020 · 1 min · jiezi

关于新媒体运营技术的一点简要思考

最近这几年新媒体运营非常火爆,而且大部分的公司和企业都对新媒体这一块非常重视。因为通过新媒体这块给他们带来的利润确实是很高的,所以他们尝到甜头之后就会更加重视这方面。而且现在不管什么行业都会新媒体运营这一职位所以现在新媒体时代已经来到了我们的身边。 可能现在还是会有很多人对于新媒体不太了解,不知道这个新媒体是干什么的,为什么就能带来这么多的利润的为公司或者是企业。其实说白了就是我们平时玩的微信、微博、论坛、社区等等这些都是属于新媒体的一种。 在你的微信里面你肯定会看到很多刷朋友圈的人,没事发个心情或者广告之类的,如果你要看到之后,有什么需要的话就会去咨询他们,如果你觉得合适的话就会买,买了之后如果你用的效果还不错你肯定就会介绍给身边的朋友,这样就形成了一连串的消费,自然而然的也就给公司和企业带来了很大的利润。所以这个也是新媒体运营现在如此火爆的一个最主要的原因之一。 运营者通常希望粉丝越多越好,用户数越多越好。对于大平台/公司来讲确实这样,比如电商平台有足够多的商品,外面平台有足够多的美食,同时大公司也拥有足够的能力来运营。 但新媒体行业有所区别,很难让所有人都依赖一个公众号,比如仅仅新闻领域,就可以分成生活新闻、娱乐新闻、农业新闻、科技新闻、教育新闻等几十种类型。 每个人的兴趣爱好都是有范围的,有领域,是标签化的。所以一个公众号,只需要满足小部分的人群就行,而且也只能解决小部分人的需求。 大白话叫做,讨好你想讨好的那群人。 这里面会涉及到供需关系,作为运营者只能提供到某种体量的信息给用户,超出这个体量就不在运营者的掌控范围内了。 互联网公司解决这种问题的办法,通常是拆分公司、拆分项目、独立运作等,比如域名地址不一样,运营不同的APP等。 粉丝不需要多,精准,活跃就好。新媒体运营就是指利用微信微博等自媒体平台进行品牌推广,产品营销;策划品牌相关的、优质、有高度传播性的内容和线上活动。 我们可以从新媒体运营的岗位职责出发,从需求入手打造符合企业需要的运营: 1、负责移动互联网自媒体平台(微信、微博、手机终端为主)的日常运营及推广工作; 2、负责能够独立运营微信公众号,为粉丝策划与提供优质、有高度传播性的内容,定期福利,如智汇返佣https://www.kaifx.cn/broker/t... 3、负责策划并执行微信营销线日常活动及跟踪维护,根据项目发送各种微信内容; 4、负责增加粉丝数,提高关注度和粉丝的活跃度,并及时与粉丝互动; 5、挖掘和分析网友使用习惯、情感及体验感受,及时掌握新闻热点,有效完成专题策划活动; 6、紧跟微信发展趋势,广泛关注标杆性公众号,积极探索微信运营模式; 7、充分了解用户需求,收集用户反馈,分析用户行为及需求。

June 30, 2020 · 1 min · jiezi

手把手教你从零开发到上线一个答题微信小程序项目实战教程之02开发题目分类页

项目搭建参考上一节内容 开发试题分类页面pages目录下新建home目录,并添加4个文件,如图所示: 其中:home.js // pages/home/home.jsPage({ data: { }, onLoad: function (options) { }, toTestPage: function(e){ let testId = e.currentTarget.dataset['testid']; wx.navigateTo({ url: '../test/test?testId='+testId }) }})home.wxml <!--pages/home/home.wxml--><view class="page"> <view class="page-title">请选择试题:</view> <view class="flex-box"> <view class="flex-item"><view class="item bc_green" bindtap="toTestPage" data-testId="18">IT知识</view></view> <view class="flex-item"><view class="item bc_red" bindtap="toTestPage" data-testId="15">游戏知识</view></view> <view class="flex-item"><view class="item bc_yellow" bindtap="toTestPage" data-testId="21">体育知识</view></view> <view class="flex-item"><view class="item bc_blue" bindtap="toTestPage" data-testId="27">动物知识</view></view> <view class="flex-item item-last"><view class="item bc_green" bindtap="toTestPage" data-testId="0">综合知识</view></view> </view></view>home.json { "navigationBarTitleText": "试题分类", "usingComponents": {}}home.wxss /* pages/home/home.wxss */.page-title { padding-top: 20rpx; padding-left: 40rpx; font-size: 16px;}.flex-box { display: flex; align-items:center; flex-wrap: wrap; justify-content: space-between; padding: 20rpx; box-sizing:border-box;}.flex-item { width: 50%; height: 200rpx; padding: 20rpx; box-sizing:border-box;}.item { width:100%; height:100%; border-radius:8rpx; display: flex; align-items:center; justify-content: center; color: #fff;}.item-last { flex: 1;}修改app.json,注意:pages/home/home一定要放到pages数组的最前,以成为首页。 ...

June 29, 2020 · 1 min · jiezi

手把手教你从零开发到上线一个答题微信小程序项目实战教程之01开发环境搭建微信小程序helloworld

上线项目演示微信搜索[放马来答]或扫以下二维码体验: 项目大纲1.开发环境搭建,微信小程序helloworld2.题目分类页3.答题页mock数据4.答题页请求真实数据(pay)5.答题页记录错题6.结果得分页(pay)7.展示错题(pay)8.记录考试结果(pay)9.小程序上线 1.注册微信小程序点击立即注册,选择微信小程序,按照要求填写信息 2.登录小程序并完善信息填写小程序信息,完善信息。 3.下载小程序开发工具完善信息后点击文档,工具,下载,选择稳定版的对应平台的安装包下载,下载完后点击安装即可 4.建立小程序项目扫码登录,选择小程序,并点击加号,填写相关信息,APPID位置于下方截图所示。 5.小程序代码结构介绍如下图所示的四个文件,主要用于注册和配置微信小程序,其包含的是全局配置信息。 app.js:用于注册微信小程序应用。app.json:小程序的全局配置,比如网络请求的超时时间,以及窗口的属性app.wxss:小程序全局样式project.config.json:包含了小程序的整体配置信息,即使是换了开发设备,亦或是换了项目,只要将该文件保留,每个开发者的个性化设置就都将保留。 如下图所示,还有两个目录, pages:每一个子文件夹代表了小程序的一个页面,比如index,和logs分别代表了两个页面。每个页面又由四个文件组成:index.js:处理页面逻辑和数据交互。index.json:对应页面的配置信息。index.wxml:展示页面的内容和元素。index.wxss:设置用wxml展示元素的样式。utils:存放的是一些工具代码,实现代码复用的目的。 6.小程序helloworld 参考:https://www.jianshu.com/p/ae8...

June 29, 2020 · 1 min · jiezi

视频-在小程序竞争激烈的今天淘票票如何脱颖而出

作者:丰安 相信大家还记得曾引起现象级风波小飞机和跳一跳这两个小程序。 2018年是小程序爆发之年,从国内手机厂商到BAT等公司,纷纷推出或推广小程序平台。为什么这个多企业愿意投入小程序,它的核心业务价值究竟是什么? 从产品和业务的角度上来看,小程序的核心的特点是在于场景融合,也就是说小程序本身的一些功能跟它所在的平台应用进行一些融合,借助平台的流量,把DAU等各方面也好做大做强。 对于平台来说,小程序可为平台拓展更多的使用场景,形成更多闭环,同时增加平台的用户粘度。 所以小程序和其所在的平台是一个共赢的关系。 阿里文娱技术团队相继上线了淘票票的支付宝小程序、手淘轻应用、快应用、字节跳动小程序、百度小程序,微信小程序。 为什么淘票票上线这么多小程序?小程序这个领域里面应该怎么去玩,去突破?阿里文娱高级技术专家丰安为你分享他在小程序领域探索的经验,包括小程序实践、跨端架构演进路线、工程化技术经验等,必让你大受启发,戳我观看!

June 24, 2020 · 1 min · jiezi

Color-Hunt-漂亮炫酷的配色小程序

利用自己的业余时间,开发了一款颜色配色方案的小程序 - Color Hunt。 小程序主要参考 Color Hunt 这个网站,这个网站设计真的很棒,个人也经常用,所以小程序也秉承网站的风格,没有做调整,不想改头换面,因为这个网站已经做的足够好,所以没有藏着掖着。只是手机上用不方便,每次用 pc 选择配色比较麻烦,想想其他人应该也有这个需求,才想做一个小程序。 那么 Color Hunt 是什么? 摘自:http://www.fly63.com/nav/1347 Color Hunt 包含了一系列漂亮炫酷的色彩组合,每天更新配色方案,并且根据浏览数排列出最漂亮的配色方案。Color Hunt 是一个收录许多配色和色码卡的收集本,为什麽需要这样的小呢?有些时候我们可能需要某些颜色,但又不太清楚怎样搭配比较好看、合适;或者你曾经看过某种颜色呈现,但却不是很瞭解这个颜色的实际。我们自己开发网站,开放app,制作宣传图的时候,就可以使用Color Hunt选取合适的颜色搭配。 我们先来看看 Color Hunt 的网页版效果: 小程序版本的效果图: 颜色详情页面: 喜欢哪些颜色可以收藏: 通过微信扫描二维码体验小程序或者通过微信搜索Color Hunt也可以体验: 也欢迎各位老铁,有什么意见或者建议,可以提出来,继续改进,感谢!

June 18, 2020 · 1 min · jiezi

小程序进阶之路跨平台开发避坑指南

简介: 小程序的开发不可避免的会面临跨平台开发的问题。各小程序平台有哪些特点?如何处理各平台的差异?本文分享淘票票在跨平台开发上的经验总结,包含了技术演进及差异控制策略,希望能帮助同学们提前避坑。 在 2019 年,阿里巴巴文娱的淘票票几乎涉足了当时市面上所有的小程序,其中在不少平台上,我们是阿里第一批吃螃蟹的技术团队。回顾过往,我们做过很多尝试,也踩过很多坑。 我们特别整理了支付宝小程序、百度小程序、字节跳动小程序、快应用的开发经验,希望为你带来启发。 一 支付宝小程序支付宝内的淘票票用户主要是以购票为主,工具属性比较明显。淘票票入口众多,均引导跳转到小程序,引导用户在小程序内进行购票、娱乐消费、收藏、添加到首页/桌面、分享等行为。 淘票票支付宝小程序,经历了近一年的起步开发,以及一年多的版本迭代,业务开发涵盖了购票、视频、资讯、社区等多个场景。 1 小程序开发1) 在核心业务中慎用 web-view 实际项目线上运行情况及用户反馈表明:web-view 初始化较慢、易受网络干扰、性能差(对比离线包及普通 H5 页面)、问题较多,建议不要在核心业务中使用 web-view 进行承载。 2) 自有城市体系与支付宝城市组件的适配技巧 由于支付宝的城市组件是基于自身城市体系的,淘票票拥有独立的城市体系,所以需要城市选择组件适配不同城市体系的场景。经过几轮推动迭代,淘票票线上已使用城市选择组件,已支持复写当前定位城市、历史访问城市、热门城市、城市列表信息等。使用my.chooseCity、my.onLocatedComplete、my.setLocatedCity 三个 JSAPI 可实现对应效果。 3) 如何实现沉浸式效果(透明导航栏)? 首先在 page.json 配置 “transparentTitle” 为 “auto” 属性,开启沉浸式布局。其次,页面布局适配沉浸式顶部透明导航栏即可,通过 my.getSystemInfo 获取 titleBarHeight 及 statusBarHeight 可计算出顶部透明高度。注意:Android 5.0 以下由于不支持沉浸式状态栏,所以页面会从状态栏下开始布局。 4) 小程序 tabBar 换肤、红点 主要使用的JSAPI及event:my.setTabBarStyle、my.setTabBarItem、page.onTabItemTap,参数参考官方文档即可。注意事项如下: 小程序触发 relaunch 时,tabBar 的样式会被清除,需要再次设置,目前建议在 app.onShow 里多次触发设置逻辑。尽量使用本地图片,在线图片有个下载的过程,体验不太好,且弱网下图片载入可能失败。my.setTabBarItem 的参数每一项均需要赋值,否则 Android 可能会报 “invalid parameter”。2 小程序开发注意事项不要使用 tnpm 安装依赖,tnpm 软连接目前支持有问题。devDependencies 和 dependencies 需要分开,将 devDependencies 移到项目代码外层,否则会额外增加包大小。设置 transparent/pullRefresh 等 window 配置时,跳转别的页面会被继承,需要在 app.json 初始化此类配置信息规避。web-view 里面的页面会失去下拉刷新、resume 等特性。Android 低版本不支持 sticky 属性。某个值控制 dom 是否渲染,下次更新时此值若为 undefined 时不会销毁掉会被忽略掉。window.atob、window.btoa 需要第三方库来替代。lodash 某些方法不能直接使用,因为小程序构建时无 global 对象。3 小程序监控使用阿里云的 ARMS 平台,参考官方文档接入即可。 ...

June 18, 2020 · 3 min · jiezi

lottie-动画库适配小程序的版本

lottie-miniprogramlottie 动画库适配小程序的版本。 lottie 的相关介绍与动画生成方法等请参考 官方说明依赖小程序基础库版本 >= 2.8.0 的环境 https://developers.weixin.qq....可参考该代码片段:https://developers.weixin.qq.com/s/2TYvm9mJ75bF。 制作lottie要使用的json包不会AE也不怕,阿里提供了一个在线制作lottiejson的网站:https://design.alipay.com/emo...普通开发者也可以做出精美的动画。通过上面那个连接制作完动画后,导出为json即可。如果有服务器的,可以将json文件保存到服务器,这样就可以减轻小程序的体积了。 具体代码使用步骤如下:通过 npm 安装:npm install --save lottie-miniprogram传入 canvas 对象用于适配1. <canvas id="canvas" type="2d"></canvas> 2. <button bindtap="click">点我预览动画</button>import lottie from 'lottie-miniprogram'click() {//按键点击事件 wx.createSelectorQuery().select('#canvas').node(res => { const canvas = res.node const context = canvas.getContext('2d') canvas.width = 300//设置宽高,也可以放到wxml中的canvas标签的style中 canvas.hight = 300 lottie.setup(canvas)//要执行动画,必须调用setup,传入canvas对象 lottie.loadAnimation({//lottie给的接口 loop: false,//是否循环播放(选填) autoplay: true,//是否自动播放(选填) path:'https://cdn.你的域名.com/aaa.json',//lottie json包的网络链接,可以防止小程序的体积过大,要注意请求域名要添加到小程序的合法域名中 rendererSettings:{ context//es6语法:等同于context:context(必填) } }) }).exec() }示例效果如下 lottie 主要接口如下:lottie.setup(canvas)lottie.loadAnimation({ ...})https://developers.weixin.qq....目前提供两个接口: lottie.setup(canvas) 需要在任何 lottie 接口调用之前调用,传入 canvas 对象 lottie.loadAnimation(options) ...

June 18, 2020 · 1 min · jiezi

微信小程序连接蓝牙设备并传递数据体脂秤

流程流程图 分步详解wx.getSystemInfo(Object object) 获取系统信息 获取操作系统及版本 页面加载的时候(或者app.js中 )↓初始化蓝牙模块 wx.openBluetoothAdapter(Object object) 在用户蓝牙开关未开启或者手机不支持蓝牙功能的情况下,通过错误码(errCode=10001),提示打开蓝牙或蓝牙功能不可用。此时小程序蓝牙模块已经初始化完成,可通过 wx.onBluetoothAdapterStateChange监听手机蓝牙是否可用或是否在搜索状态。 关闭蓝牙模块wx.closeBluetoothAdapter。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后,以及onhide,onUnload。↓开始搜索蓝牙 wx.startBluetoothDevicesDiscovery(OBJECT) 开始搜寻附近的蓝牙外围设备,初始化完成或点击事件里调用。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery方法停止搜索,以及onhide,onUnload。↓监听寻找到新设备的事件wx.onBluetoothDeviceFound(CALLBACK)通过设备名(设备方提供)过滤设备,deviceId一般不作为判断条件,因为开发者工具和 Android 上获取到的deviceId为设备 MAC 地址;iOS 上则为设备 uuid。 但是如果附近有多个同名的设备时,就需要通过mac地址来匹配对应的蓝牙设备了。ios不同手机搜索到的设备deviceId经过处理后是不同的。如果需要处理这种情况可以联系蓝牙设备硬件方,将mac地址存入当前蓝牙设备的广播数据段中的 ManufacturerData 数据段中,我们通过res.devices.advertisData的值去匹配&连接蓝牙。 ⚠️ 安卓下部分机型需要有位置权限才能搜索到设备,需留意是否开启了位置权限↓连接低功耗蓝牙设备wx.createBLEConnection(OBJECT)  若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。  断开连接:wx.closeBLEConnection(),在onhide,onUnload时候;↓wx.onBLEConnectionStateChange(function callback) 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等↓获取蓝牙设备所有服务(service) wx.getBLEDeviceServices(OBJECT) 过滤出需要的service uuid,设备方提供,比如包含某一个字段↓获取蓝牙设备某个服务中的所有 characteristic(特征值)wx.getBLEDeviceCharacteristics(OBJECT) 过滤特征值,找到 用来写入/读取的特征值的 uuid 设备方提供   特征值是什么:每个服务都包含了一组特征值用来描述服务的一些属性,跟蓝牙通信时需要这些特征值ID来传递数据。↓启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值  wx.notifyBLECharacteristicValueChange(OBJECT),这里需要用来读取的特征值的 uuid 注意⚠️ :必须设备的特征值支持 notify 或者 indicate 才可以成功调用。↓写入wx.writeBLECharacteristicValue(OBJECT) 向低功耗蓝牙设备特征值中写入数据,需写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。↓wx.onBLECharacteristicValueChange 监听低功耗蓝牙设备的特征值变化事件(返回的多个数据包) 监听低功耗蓝牙设备的特征值变化事件。必须先启用 wx.notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。 BLE小程序蓝牙是搜索不到手机蓝牙的。 经典蓝牙和BLE(Bluetooth Low Energy)低功耗蓝牙的区别蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙3.0之前的BR/EDR蓝牙称为传统蓝牙,而将蓝牙4.0规范下的LE蓝牙称为低功耗蓝牙。区别于传统模块,最大的特点就是成本和功耗降低,应用于实时性要求比较高。 蓝牙低功耗(BLE)功能,是利用蓝牙低功耗特性新发展的技术。手机上要利用蓝牙低功耗技术,一般是通过 BLE 配件厂商发布的 BLE 配件和其配套 APP,配合使用。比如:BLE 运动手环、运动手表、体重计、计步器、智能腕带等。 二进制相关数据类型ArrayBuffer & TypedArrayArrayBuffer对象、TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口。ES6 将它们纳入了 ECMAScript 规格,并且增加了新的方法。它们都是以数组的语法处理二进制数据,所以统称为二进制数组。但是,二进制数组并不是真正的数组,而是类似数组的对象。 (1)ArrayBuffer对象:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。 (2)TypedArray视图:共包括 9 种类型的视图。比如Uint8Array, Int16Array, Float32Array数组视图等等。 Uint8Array 代表数组的每一项是无符号整型 8代表数据的每一项占 8 个比特位,即一个字节(8bits=1byte) ...

June 17, 2020 · 1 min · jiezi

快应用调试器功能使用说明

快应用调试器功能使用说明1. 如何 WIFI 调试确保手机与电脑处于同一局域网内。 1.1 使用快应用 IDE 调试:点击 IDE 右上角二维码图标,使用手机快应用调试器扫描生成的二维码(二维码信息为本机 dev-server 地址,也可根据该地址用这个网站手动生成二维码)。 若出现如下界面,请点击右上角 menuBar ,设置,删除服务器地址最后的 /bundle。 点击右上角 menuBar ,打开调试模式,重启后打开 demo 即进入调试模式。此时点击右下角齿轮图标可打开手机控制台查看日志信息。关闭 demo ,打开快应用调试器,点击右下放开始调试,可进入远程调试,电脑浏览器会弹出调试界面,调试方式与调试 node.js 类似。可在 js 源码中使用 debugger 或在调试界面的 source 面板设置断点(可设置条件断点)。在下图位置 source 面板查看 demo 源码。 1.2 使用命令行调试:注意: 需要全局 joyful ,目前 joyful还未发布。项目根目录下 joy serve 或任意目录下 joy serve 项目根目录。 打开快应用调试器,点击右上角 menuBar ,设置,服务器地址填上图所示本机 dev-server 地址,点击在线更新,进入 demo 界面。也可通过 dev-server 地址生成对应的二维码,使用扫码安装。也可通过 joy pack 生成 app.rpk,将该 rpk 发送到手机上,使用本地安装打开 demo。2. 如何 USB 调试项目根目录下 joy serve ,或者通过上面所说的扫 IDE 的二维码,确保手机调试器设置里面的服务器地址正确,点击开启 USB 调试的按钮,点击在线更新,最后点击开始调试。(此时仍然需要连接 WiFi) ...

June 10, 2020 · 1 min · jiezi

百度智能小程序性能文档升级重磅来袭

页面白屏了?加载时间长?点击没反应?性能有问题!智能小程序性能文档升级,重磅来袭,带你进入不一样的性能新世界!更多内容查看开发者社区/更多招聘信息 近期为帮助开发者提升小程序性能,百度智能小程序上线了 Page.onInit 、xxx(如有其它请补充)等新增功能;同时全面升级了开发者性能文档,从基本原理开始由浅入深,为您解锁各种性能提升新技能! 更多性能优化方案文档升级后,围绕小程序首屏渲染流程,针对收集 initData、请求主数据环节,和优化渲染速度的角度,为开发者提供了更多性能优化方案。 收集 initData在收集 initData 这个环节,开发者可通过使用分包、合理使用动态库、合理使用 App.onLaunch 的方式,缩短耗时,从而优化首屏渲染时长。 使用分包包下载与解析是整个启动过程中的一个重要阶段,该阶段耗时与小程序页面所属包大小呈正相关,将直接影响到 initData 完成收集的时间,从而影响首屏渲染。开发者可根据实际情况,选择使用下述分包方式: 分包加载:在智能小程序的打包中,默认会有一个主包,主包中包含了启动页面,和所有分包都会用到的公共资源/JS 脚本,根据开发者的配置划分分包。独立分包:独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。从独立分包中页面进入小程序时,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。分包预下载:开发者可以通过配置,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度。合理使用动态库动态库,是指可被添加到小程序内直接使用的功能组件。由于动态库的独立资源将在逻辑和渲染层分别进行加载,在此过程中将会加载动态库的全部代码(逻辑和样式),然后解析执行。此时如果引用的动态库中包含大量未使用的逻辑,导致加载过程中大量资源的浪费,从而阻塞 initData 的收集时间,进而直接影响到页面渲染。 因此建议开发者合理使用动态库。 合理使用 App.onLaunchApp.onLaunch是进入小程序的第一个生命周期函数,很多开发者会在App.onLaunch中执行一些初始化操作。如果使用不当,会显著影响首屏显示速度。因此建议您在使用中注意如下事项: 避免在 App.onLaunch 中执行耗时很长的任务,尽可能将任务推移到页面显示完成后执行。减少、避免在 App.onLaunch 中调用一些同步 API。使用异步 API 代替同步,并尽量减少、延后首页面显示非必需的 API 调用。将 App.onLaunch 中的页面请求放在 Page.onInit 生命周期中请求主数据在请求主数据环节,开发者可通过在 onInit 请求首屏主数据、数据前置获取、数据持久化的方式缩短数据加载时间,从而优化首屏渲染时长。 在 onInit 请求首屏主数据onInit是小程序提供的一种生命周期,执行时机介于 App.onLaunch 和 Page.onLoad 之间。在 setInitData 之后立即执行Page.onInit(),把主数据请求从 Page.onLoad 转移到 Page.onInit 中,将极大提升小程序的页面加载性能。 数据前置获取通过数据前置获取,可以把关键页面的数据放在入口页面获取,页面跳转至关键页面时,将数据以页面参数的形式传输给落地页。在一些商业线索类页面中,用户进入页面后将立即看到线索相关信息,无需等待。 数据持久化数据持久化指从服务端获取到的数据,通过swan.setStorage方法保存在本地,页面渲染时直接从本地获取所需数据的这一行为。将固定 banner、筛选、导航等低时效性数据存在本地,页面加载时直接从本地读取、渲染数据,将大幅减少页面上的留白时间,提升用户体验,降低白屏率。 优化渲染速度开发者可合理使用自定义组件、合理使用 view 和 text 组件、优化图片使用方式、按需渲染优化等方式,有效优化渲染层渲染速度。 合理使用自定义组件开发者可以将页面内的功能模块抽象成自定义组件,在智能小程序的各个页面中进行使用,提升代码复用度,节省开发成本。 合理使用 view 和 text 组件框架默认使用高性能的view和text组件,但开发者在组件上使用一些特定属性和任一事件时,会退化为低性能组件。在开发过程中请谨慎使用animation、style、 dataset、hidden等内容,详情查看合理使用 view 和 text 组件。 ...

June 9, 2020 · 1 min · jiezi

微信小程序问题-其一

问题详情:在向后端发送数据时,header中的cookie和Authorization未向后端发送问题 解决方法: wx.request({ url: '', method: '', data: { }, header: { 'cookie': wx.getStorageSync("cookies"), 'Authorization': wx.getStorageSync("Authorization") }, success (res) { console.log(res.data) } })在header中直接调用 wx.getStorageSync("key") 方法取值即可在header里不能直接取data里的值,这样会无法取到值,进而导致数据没发送问题

June 7, 2020 · 1 min · jiezi

记录一下微信小程序图片拖拽放大位移效果实现

因为需求需要对图片进行操作,放大,位移,旋转等思路也是参考别的博客这个写的比较全https://blog.csdn.net/king096...我看的第一篇是这个https://www.jb51.net/article/... 实现思路1 在一个区域里绘制图片,2 记录所有图片的坐标,旋转角度,尺寸,中心点,缩放比例3 创建cavnas画布,白底色,然后根据记录的图片的一些状态绘制4 根据canvas生产出图片 先上效果蓝框为拖拽区域红框为cavnas绘制部分贴代码wxmlcanvas标签正常情况下应该是隐藏或者让他定位到十万八千里外因为需要展示效果,所以就没有隐藏,实际上线可以自己隐藏掉 <view class="container"> <button class="mini-btn" bindtap="generate" type="primary" size="mini">生成图片</button><block wx:for="{{materialList}}" wx:key="index"> <image class="img-list" bindtap="addImg" data-index="{{index}}" mode="aspectFit" src="{{item.image}}"></image></block>{{itemList.length}} <view class="img-box" id="img-box"> <!-- *************操作区域************* --> <block wx:for="{{itemList}}" wx:key="index"> <!-- 圆心坐标 <text style='position:absolute;top:{{item.y}}px;left:{{item.x}}px;width:2px;height:2px;background-color:yellow;z-index:500'></text> --> <!-- {{item.scale}}---{{item.r}} --> <view class='touchWrap' style='transform: scale({{item.scale}});top:{{item.top}}px;left:{{item.left}}px; '> <view class='imgWrap {{item.active? "touchActive":""}}' style="transform: rotate({{item.angle}}deg);"> <view> <image style="width:{{item.height}}px; height:{{item.width}}px" class="item-img" src='{{item.image}}' bindload='loadImg' data-index="{{index}}" data-id='{{item.id}}' bindtouchstart='wraptouchStart' bindtouchmove='WraptouchMove'></image> </view> <!-- <image src='{{item.image}}' bindload='loadImg' bindtouchend='WraptouchEnd'></image> --> <image class='x' hidden="{{!item.active}}" bindtap="hiddenImg" data-index="{{index}}" src='../../assets/img/wqy-close.png' style='transform: scale({{item.oScale}});transform-origin:center;' data-id='{{item.id}}'></image> <image class='o' hidden="{{!item.active}}" data-index="{{index}}" src='../../assets/img/wqy-stretch.png' style='transform: scale({{item.oScale}});transform-origin:center;' data-id='{{item.id}}' bindtouchstart='touchStart' bindtouchmove='touchMove'> </image> </view> </view> </block> </view> <canvas class='maskCanvas' canvas-id="maskCanvas" style='width:{{canvasWidth}}px; height:{{canvasHeight}}px;'></canvas></view>js部分 /* * @Description: * @Author: 冷山冷杉 <wqy.mail@foxmail.com> * @Date: 2020-06-04 11:58:14 * @LastEditTime: 2020-06-05 16:14:51 * @LastEditors: 冷山冷杉 <wqy.mail@foxmail.com> * @FilePath: \mini-fullalumni\pages\photoTest\photoTest.js */const app = getApp()const maskCanvas = wx.createCanvasContext('maskCanvas', this)let items = []Page({ data: { itemList: [ ], materialList: [ { id: null, image: 'https://img3.doubanio.com/view/subject/m/public/s9074663.jpg',//图片地址 top: 0,//初始图片的位置 left: 0, x: 0, //初始圆心位置,可再downImg之后又宽高和初始的图片位置得出 y: 0, scale: 1,//缩放比例 1为不缩放 angle: 0,//旋转角度 active: true //判定点击状态 }, { id: null, image: 'https://img9.doubanio.com/view/subject/m/public/s3893375.jpg', top: 0, left: 0, x: 0, y: 0, scale: 1, angle: 0, active: false } ], canvasWidth: null, canvasHeight: null }, onReady() { const query = wx.createSelectorQuery() query.select('#img-box').boundingClientRect() query.selectViewport().scrollOffset() query.exec((res) => { this.setData({ canvasWidth: res[0].width, canvasHeight: res[0].height }) }) // wx.getSystemInfo({ // 获取系统信息 // success: sysData => { // this.sysData = sysData // // 设置画布宽高,this.sysData.windowWidth为屏幕的宽度 // this.setData({ // canvasWidth: this.sysData.windowWidth, // 如果觉得不清晰的话,可以把所有组件、宽高放大一倍 // canvasHeight: this.sysData.windowWidth // }) // } // }) }, addImg(e) { let index = e.currentTarget.dataset.index let materialList = this.data.materialList let itemList = this.data.itemList if (itemList.length) { materialList[index].id = itemList[itemList.length - 1].id + 1 } else { materialList[index].id = 1 } itemList.push(JSON.parse(JSON.stringify(materialList[index]))) this.setData({ itemList }) }, loadImg(e) { let index = e.currentTarget.dataset.index let itemList = this.data.itemList // x,y为圆心的距离, +25: 按钮定位的距离 + 按钮自身大小/2 itemList[index].width = e.detail.width itemList[index].height = e.detail.height itemList[index].x = e.detail.width / 2 + 25 itemList[index].y = e.detail.height / 2 + 25 this.setData({ itemList }) }, hiddenImg(e) { let index = e.currentTarget.dataset.index let itemList = this.data.itemList itemList.splice(index, 1) this.setData({ itemList }) }, wraptouchStart: function (e) { let items = this.data.itemList; for (let i = 0; i < items.length; i++) { //旋转数据找到点击的 items[i].active = false; if (e.currentTarget.dataset.id == items[i].id) { items[i].active = true; //开启点击属性 items[i].lx = e.touches[0].clientX; // 记录点击时的坐标值 items[i].ly = e.touches[0].clientY; } } this.setData({ //赋值 itemList: items }) }, WraptouchMove: function (e) { let index = e.currentTarget.dataset.index let items = this.data.itemList; //移动时的坐标值也写图片的属性里 items[index]._lx = e.touches[0].clientX; items[index]._ly = e.touches[0].clientY; //追加改动值 items[index].left += items[index]._lx - items[index].lx; // x方向 items[index].top += items[index]._ly - items[index].ly; // y方向 items[index].x += items[index]._lx - items[index].lx; items[index].y += items[index]._ly - items[index].ly; //把新的值赋给老的值 items[index].lx = e.touches[0].clientX; items[index].ly = e.touches[0].clientY; this.setData({//赋值就移动了 itemList: items }) }, // 触摸开始事件 items是this.data.itemList的全局变量,便于赋值 所有的值都应给到对应的对象里 touchStart: function (e) { //找到点击的那个图片对象,并记录 let items = this.data.itemList; let index = e.currentTarget.dataset.index for (let i = 0; i < items.length; i++) { items[i].active = false; if (e.currentTarget.dataset.id == items[i].id) { items[i].active = true; } } //获取作为移动前角度的坐标 items[index].tx = e.touches[0].clientX; items[index].ty = e.touches[0].clientY; //移动前的角度 items[index].anglePre = this.countDeg(items[index].x, items[index].y, items[index].tx, items[index].ty) //获取图片半径 items[index].r = this.getDistancs(items[index].x, items[index].y, items[index].left, items[index].top) }, // 触摸移动事件 touchMove: function (e) { let items = this.data.itemList; let index = e.currentTarget.dataset.index // items[index].x = e.detail.width / 2 // items[index].y = e.detail.height / 2 // this.setData({itemList: items}) //记录移动后的位置 items[index]._tx = e.touches[0].clientX; items[index]._ty = e.touches[0].clientY; //移动的点到圆心的距离 * 因为圆心的坐标是相对与父元素定位的 ,所有要减去父元素的OffsetLeft和OffsetTop来计算移动的点到圆心的距离 items[index].disPtoO = this.getDistancs(items[index].x, items[index].y, items[index]._tx, items[index]._ty) items[index].scale = items[index].disPtoO / items[index].r; //手指滑动的点到圆心的距离与半径的比值作为图片的放大比例 items[index].oScale = 1 / items[index].scale;//图片放大响应的右下角按钮同比缩小 //移动后位置的角度 items[index].angleNext = this.countDeg(items[index].x, items[index].y, items[index]._tx, items[index]._ty) //角度差 items[index].new_rotate = items[index].angleNext - items[index].anglePre; //叠加的角度差 items[index].angle += items[index].new_rotate; //用过移动后的坐标赋值为移动前坐标 items[index].tx = e.touches[0].clientX; items[index].ty = e.touches[0].clientY; items[index].anglePre = this.countDeg(items[index].x, items[index].y, items[index].tx, items[index].ty) //赋值setData渲染 this.setData({ itemList: items }) }, /* *参数1和2为图片圆心坐标 *参数3和4为手点击的坐标 *返回值为手点击的坐标到圆心的角度 */ countDeg: function (cx, cy, pointer_x, pointer_y) { var ox = pointer_x - cx; var oy = pointer_y - cy; var to = Math.abs(ox / oy); var angle = Math.atan(to) / (2 * Math.PI) * 360;//鼠标相对于旋转中心的角度 if (ox < 0 && oy < 0)//相对在左上角,第四象限,js中坐标系是从左上角开始的,这里的象限是正常坐标系 { angle = -angle; } else if (ox <= 0 && oy >= 0)//左下角,3象限 { angle = -(180 - angle) } else if (ox > 0 && oy < 0)//右上角,1象限 { angle = angle; } else if (ox > 0 && oy > 0)//右下角,2象限 { angle = 180 - angle; } return angle; }, getDistancs(cx, cy, pointer_x, pointer_y) { var ox = pointer_x - cx; var oy = pointer_y - cy; return Math.sqrt( ox * ox + oy * oy ); }, generate: function () { maskCanvas.save(); maskCanvas.beginPath(); //一张白图 maskCanvas.setFillStyle('#fff'); maskCanvas.fillRect(0, 0, this.data.windowWidth, this.data.canvasHeight) maskCanvas.closePath(); maskCanvas.stroke(); this.data.itemList.forEach((val, index) => { maskCanvas.save(); maskCanvas.translate(0, 0); maskCanvas.beginPath(); maskCanvas.translate(val.x, val.y); // 圆心坐标 maskCanvas.rotate(val.angle * Math.PI / 180); maskCanvas.translate(-(val.width * val.scale / 2) - 25, -(val.height * val.scale / 2) - 25) maskCanvas.drawImage(val.image, 0, 0, val.width * val.scale, val.height * val.scale); maskCanvas.restore(); }) maskCanvas.draw(false, (e) => { wx.canvasToTempFilePath({ canvasId: 'maskCanvas', success: res => { this.setData({ canvasTemImg: res.tempFilePath }) console.log(res.tempFilePath); } }, this) }) }})css ...

June 5, 2020 · 5 min · jiezi

玩转AR图形识别小程序

玩转AR图形识别小程序这些年深度学习炙手可热,人脸识别,图像分类,目标检测等技术已经应用到我们生活的方方面面。作为一个时刻保持好奇心的程序猿想入门深度学习,但又苦于门槛较高,难以获得理想的学习成果。好在一些大厂已经推出了深度学习云平台,让我们前端小白也能体验深度学习的乐趣。 这次我们基于百度AI开放平台EasyDL来实现一个logo图像识别小程序,半天时间轻松搞定客户BABA的需求。 logo目标检测演示 1: 创建训练模型 要实现logo识别的功能,我们先要创建一个物体检测模型。 访问百度EasyDL地址 https://ai.baidu.com/easydl 在操作平台菜单中,选择物体检测选项。 1.1 选择创建模型 1.2 为模型命名,模型归属选择个人。 2: 创建训练数据集 模型创建好以后,我们要为模型提供训练数据,所谓训练数据就是我们要识别的logo图片。 模型就像一个懵懂的孩子,我们要用训练数据教他识别图片中的logo,让他能举一反三,以后遇到不在数据集中的图片也能准确的识别出来。 2.1 准备训练数据 为了提高识别精度,我们需要用手机拍摄不同的光线,角度,背景下的logo图片上传,图片数据越多,越有助于提高模型的识别精度,一般建议上传40张左右。 2.2 标注数据 上传后,用鼠标拖拽矩形区域标注出logo图形位置,并设置统一的标签名,然后点击左下角的保存按钮。如果嫌手动标注麻烦,也可以尝试右下角的智能标注。 2.3 开始训练 训练时间和数据集大小成正比,以我30多张的训练数据为例,大概需要20分钟左右,已经很快啦,如果是在本地单机上训练可能要几小时的时间,这就是云服务分布计算的好处。 2.4  校验模型 训练结束后,我们需要对模型进行校验,看看模型的识别精度是否符合预期。 上传几张不在数据集中的照片来检验结果,如果效果满意,我们就可以进行下一步,发布模型。 3: 发布模型 3.1  提交申请 发布模型前需要提交审核,填写服务名称和接口地址,提交申请。 审核成功后,在操作列表中点击服务详情->立即使用。 3.2  创建应用 在使用接口前,我们还需要创建一个应用,应用可以理解为一个容器,一个应用可以包含多个接口,为这些接口提供访问键值,秘钥等参数。 应用创建结束后,会看到分配的API Key和Secret Key,这些都是接口调用需要携带的参数。 4: 在小程序中调用识别接口 4.1 接口token验证 在调用识别接口前先要拿到access_token令牌,这是所有接口调用的前提条件。 wx.request({ url: API_AUTH_URL, //token授权地址 method: 'GET', data: { grant_type: 'client_credentials', client_id: CLIENT_ID, //API Key client_secret: CLIENT_SECRET //Secret Key }, success: (res) => { _access_token = res.data.access_token this._getImageData() }})4.2 调用接口 ...

June 4, 2020 · 1 min · jiezi

在Gitee获85k-Star做微信小程序商城看这一个开源项目就够了

商城系统是小程序中比较热门的类型,许多开发者在寻找商城类小程序项目时,都会遇到一些声称「开源」但是并不是完全开源,有时候还会收费的项目。今天 Gitee 介绍的这款微信小程序商城项目就是一款从前端到后台完全开源的商城系统。 项目名称:Open-Shop 项目作者:老花生 开源许可协议:Apache-2.0 项目地址:https://gitee.com/old-peanut/wechat_applet__open_source 项目特点免费完整开源:基于MIT协议,源代码完全开源,无商业限制;无BUG:经过严格测试,开箱即用;编码优雅:代码结构清晰,注解非常详细,方便小伙伴们学习和使用。;持久更新:会定期公布开发计划。并按计划提交新的功能;活跃的社群:官方QQ群有专人回复,及时耐心的解答问题。面向对象Open-Shop是企业在创立初期很好的技术基础框架,加快公司项目开发进度,当然也可以对现有的系统进行升级;个人开发者也可以使用Open-Shop承接外包项目;初学JAVA的同学可以下载源代码来进行学习交流。技术框架核心框架:Spring Framework 4安全框架:Apache Shiro 1.2视图框架:Spring MVC 4持久层框架:MyBatis 3数据库连接池:Alibaba Druid 1.0日志管理:SLF4J 1.7、Log4jJS框架:Vue 2.5.1,iview,layer 3.0.3,jquery 2.2.4,jqgrid 5.1.1CSS框架:Twitter bootstrap3.3.7。富文本:froala_editor1.2.2后台界面 小程序界面 如果你喜欢这个项目,记得去项目主页点一个 Star 哦:https://gitee.com/old-peanut/wechat_applet__open_source

June 3, 2020 · 1 min · jiezi

小程序遇到map-is-not-defined的问题

*用的是taro框架写的小程序最近写小程序老是出现一些问题,比如说我要遍历一个数组,我的数组在打印的时候明明是有值的,但是就是报.map的错误,我在state里面是这样声明的: this.state = { obj:{}}然后我在请求后台数据,往obj里面添加值,然后在render里面遍历 render(){ obj.main && obj.main.length > 0 ? obj.main.map((v,i) =>{ return <View taroKey={i}>{i}</View> }) : ''}这样写的话,在html里面判断是没有问题的,但是在小程序就.map的问题 解决方案: 在state里面这样声明变量,把你遍历的数组先申明一下就可以la~,这个问题居然找了这么长时间? 希望看到的朋友对你有所帮助 this.state = { obj:{main:[]}}

June 2, 2020 · 1 min · jiezi

产业安全专家谈-银行业小程序安全防护的实践路径

当前,随着网络业务与移动业务的兴起,银行业已经进入智能化、数字化的新时代。网上银行、移动客户端、小程序相继成为各个银行实现数字化转型的重要载体。 其中,小程序凭借开发门槛低、上线速度快、平台覆盖率高等特点成为现阶段银行服务用户的重要移动渠道。然而小程序面向海量的用户和复杂的跨网交换,其承载的金融数据更是时刻遭受不法黑客的攻击威胁;此外,部分开发者使用的第三方SDK服务也有可能存在安全风险,威胁企业和用户的财产安全。 银行小程序主要面临的安全风险都有哪些?如何确保小程序在研发、上线、运营阶段的稳定应用?如何预防小程序中的用户信息泄露?由腾讯安全联合云+社区打造的「产业安全专家谈」第二十期,邀请到了腾讯安全资深架构师徐涛,为大家分享银行小程序安全防护的实践路径。 Q1:随着金融服务向移动互联网逐渐倾斜,银行业主要面临的安全问题有没有发生改变? 徐涛:伴随金融服务和营销手段线上化的进程发展,互联网金融所带来的信息安全风险日渐提高,数据泄露事件层出不穷。在资金体量庞大、用户信息集中、信息价值具有强变现能力的金融领域,安全问题所造成的影响力相较于其他行业更为明显。 最早银行业提供的移动金融服务主要以网上银行为主,最主要的安全问题就是安全漏洞。在2016年金融行业安全漏洞类型分布中,涉及安全漏洞类型多样化,且高危漏洞占比达总漏洞数的94.56%。而随着移动客户端的逐渐普及,黑灰产也开始将攻击重点转移到了各个银行的移动客户端之上,2018年就曾有黑客利用某银行APP软件中业务存在的安全漏洞,非法获利近2800余万元。 通过金融行业中安全漏洞数据和过往案例不难看出,金融行业急需构建完善的安全体系,来实现对安全漏洞风险的提前检测、暴露和解决,帮助业务方规避经济损失以及不可估量的口碑影响。 如今,随着微信小程序市场的持续拓展,用户规模和渗透率的逐渐提升,微信小程序已经成为了各行业拓展线上服务的新载体,各大银行也纷纷开始通过小程序来实现移动端金融服务的功能。在此背景下,小程序不只要应对与APP同样的安全风险,还要面对源代码的逆向风险和调试风险,这些安全隐患所带来新的问题。 Q2:小程序相较于APP具备哪些优势?主要的安全问题有哪些? 徐涛:对于开发者而言,小程序的开发成本更低、成型快、项目上手更快,而且开发一个版本就能覆盖安卓和iOS两个系统;另外,小程序在服务功能迭代和升级的速度上也明显优于APP,非常适合用来快速实现场景化服务,进一步验证客户的需求。而对于用户而言,小程序无需下载安装、即用即走、接近原生的体验度也获得了用户的广泛欢迎。 随着微信小程序用户规模的不断扩大,各个银行也纷纷开发了专属的小程序作为服务用户的重要渠道,相应的安全隐患也随之而来。不法分子利用小程序进行作弊欺诈、恶意植入木马或病毒、篡改业务数据、盗取用户隐私信息等行为,为企业的业务安全带来了严重的威胁。 Q3:银行在开发小程序的过程中,主要面临的安全风险是什么?有哪些解决方案? 徐涛:随着互联网与移动应用的普及和不断发展,银行的互联网金融业务模式不断壮大,在黑灰产业攻击逐渐产业化、技术化、精准化的背景下,针对银行的攻击呈现出愈演愈烈的趋势。同时,随着用户习惯越来越轻量化,app所面临的风险也体现在小程序中。主要的安全风险有以下几个: ■ 薅羊毛 一些银行在产品开发设计上未妥善考虑安全问题,直接在小程序上进行红包、优惠券等形式的营销,就会给黑灰产带来可乘之机。比如不法分子可以通过恶意下单等方式来“薅羊毛”,让银行的营销引流效果大打折扣,更有甚者会使50%-80%的营销资金因此而浪费。 有一些商家在设计支付流程时存在不当设置,让用户主动提供支付账单金额,黑灰产业在发现直接改小账单金额也可完成交易后,羊毛党蜂拥而至,让商家蒙受了严重的经济损失。 ■ 仿冒、山寨小程序 由于小程序源码难以混淆加密,导致山寨小程序也大量出现。不法分子通过逆向等方式来窃取核心代码,仿冒伪造小程序,为小程序开发商带来业务危机,同时也让用户的隐私信息暴露在危险之下。 ■ 恶意数据爬取 尽管微信小程序具有天然的安全保护能力,但不当的开发依然会存在的接口数据泄露等隐患,容易带来信息爬取风险。如果核心数据被爬取并挪为他用,将会带着经济损失,甚至对银行的品牌影响力造成不可挽回的影响。过去曾有商家因在营销活动中没有仔细验证订单与会话身份的匹配,导致约3000万用户个人信息、订单信息泄露。 随着国家对于数据安全的重视程度逐渐增强,相关的法律法规和行业规范正逐步出台。中国人民银行在2019年颁发的第237号文《移动金融客户端应用软件安全管理规范》和《信息安全技术网络安全等级保护基本要求》中,分别明确规定了不同类型的软件包括资金交易类、信息采集类、资讯查询类软件都应该符合相应的安全管理要求,要求各机构的应用开发符合安全设计要求、提供风险监控能力、保护个人金融信息。 日趋严格的监管要求,加上呈上升势头的网络攻击浪潮,都要求银行小程序在程序设计、开发、运营等环节,需要提供切实有效且满足政策法规要求的解决方案。我们基于腾讯多年积累的移动安全实践经验和可靠的安全防护技术,为众多小程序运营者打造了小程序安全防护平台,能够从多角度、全方位洞悉黑产分子的攻击手段,为小程序提供安全管控、运行监测、异常监控等安全防御方案,保障银行小程序业务安全,降低安全隐患,起到降本增效的作用。 Q4:银行小程序如何构建金融级别的安全防护能力? 徐涛:银行是经营货币的行业,安全对于金融而言是头等大事。银行在通过小程序服务金融客户的过程中,会涉及包括用户隐私数据、企业商业数据在内的海量真实数据,极易成为黑灰产业的攻击目标。 构建金融级别的安全防护能力,意味着小程序要遵循金融监管的要求多措并举,包括打造小程序的安全管理架构,权责明确;构建覆盖全生命周期的管理机制,在小程序上线之前就对小程序进行全面扫描和加固,及时发现小程序中是否存在安全漏洞,同时加强小程序在设计、开发、发布、维护等环节的安全管理,并针对网络攻击采取有效的防范措施;加强合规意识,完善客户个人的隐私保护机制。只有做到这些,才能保障小程序安全、合规、稳定的运营。 Q5:从零开始构建银行小程序,如何做到最高效地安全防护?腾讯安全能够提供哪些帮助? 徐涛:建议先从业务场景入手,通过对具体业务场景进行深入了解和详细分析,逐步梳理出小程序在业务流程、程序设计、部署结构等环节中存在的安全隐患,再根据这些安全隐患对症下药,部署切实有效的安全解决方案。这样的方法看似笨拙,但实际上是能够确保小程序和业务的可用性和安全性最好、效率最高的方法。 考虑到银行是从零开始构建小程序安全防护体系的,开发和运营人员都可能存在经验不足的情况,在部署安全产品时容易“头痛医头,脚痛医脚”,让后续的安全防护工作无法顺利开展。这时可以考虑使用腾讯安全小程序安全防护平台,为小程序提供可持续高质量的开发流程、营销风控体系、运行监测系统等多功能全方位的安全解决方案,并通过敏捷设计开发、流程化管理、体系化监控,为银行小程序打造全面立体化的防护体系。 Q6:腾讯安全如何满足不同银行小程序中的各类安全需求? 徐涛:考虑到银行业务自身所具备的金融属性和高敏感性,在构建安全防护能力时首先明确的是合规问题。银行客户可以先通过引入腾讯安全金融小程序安全防护解决方案,从合规性角度梳理小程序的安全漏洞及隐患,再根据不同的业务需求来选择平台下相应的安全产品进行部署。 比如对于需要快速迭代服务功能的小程序,就可以选用小程序安全管控中的安全扫描功能,通过快速且自动化的测评检测小程序中的安全隐患,来满足银行小程序快速迭代、测试的持续测评需求。 如果银行自身安全体系中缺乏针对渗透攻击的防护手段,则可以通过渗透测试功能,深度挖掘小程序业务逻辑安全以及WEB框架中的安全漏洞;同时,渗透测试功能还能够以模拟黑客攻击的形式,对小程序业务系统进行渗透测试,发现可导致业务数据泄露、资产受损、数据被篡改等各类安全风险,帮助运营人员提早进行修复,避免因代码漏洞造成的安全风险及资产损失。 Q7:有没有在保障小程序实现快速功能迭代的同时,还能确保小程序安全的方法? 徐涛:目前各种各样的小程序开发周期都很短。疫情期间,大量小程序开发需要在1-3天的极限时间完成上线,并快速进行服务功能的迭代和升级,极短的交付时间给安全运营带来了极大的压力。 我们通过一套部署在云端的纵深产品体系,打造了覆盖“事前、事中、事后”全生命周期的安全方案,在保障小程序实现快速功能迭代和上线的同时,为其提供业务安全、运维安全、数据安全等五大保障。方案可有效支持小程序在开发阶段的安全测试、风险评估和加固。对于小程序前端代码的加密,接入该方案的开发者只需将代码(路径或文件)传递给加密工具,即可实现字符串加密、属性加密、调用转换、代码混淆等多项保护措施,提高攻击者分析H5前端代码逻辑的难度;针对小程序前端和后台WEB端,该方案提供整体自动化风险检测工具,覆盖前台代码安全和API使用规范,以及业务CGI和对WEB框架和的安全检测,基本覆盖当下主流Web攻击方式,可以让开发者在极限开发时间压力下,交付符合安全标准的小程序。

June 1, 2020 · 1 min · jiezi

小程序input框在安卓手机展示错误

今天在写小程序的时候需要一个这样的问题,在输入内容的时候想调出手机的软键盘,本人用的是苹果手机,一切都正常,但是俺们的产品同学用的是安卓手机,结果input框就展示不出来,一开始想的是背景颜色的问题,后来仔细看了看,是input的margin问题,只要把input的margin设置成0就可以la~,在此记录一下遇到的小程序坑

June 1, 2020 · 1 min · jiezi

小程序-setData-修改-data-中数组内不定对象的数据

小程序 setData 修改 data 中数组内不定对象的数据 普通变量的 setData()在某些时候,我们的小程序中存在的不只是像下面这样的简单的变量: 变量值这种形式 data: { name: 'Kyle', age: 28, mail: 'kylebing@163.com'}这种形式的数据,在需要修改的时候,只需要如下形式修改就可以了 this.setData({ name: 'Tina' })数组内部的 setData()有时候,里面会有对象数组,需要修改数组内部的变量,如下面的 people 数组: people: [ { name: 'Kyle', age: 24, products: [ {name: 'iPhone', price: 4550}, {name: 'AirPods Pro', price: 1999}, ] }, { name: 'Tina', age: 26, products: [ {name: 'Dell P2415Q', price: 1800}, {name: 'Macbook Pro', price: 8500}, ] }]像这种改变数组内部属性的值,需要不同于普通变量的 setData(),格式如下:方括号里接收的是字符串 this.setData({ [ 定位数据的字符串 ]: 数据})如: 修改 Kyle 的 age ...

November 4, 2019 · 1 min · jiezi

uniapp微信小程序登录并使用vuex存储登录态

微信小程序注册登录思路(这是根据自身的项目的思路,不一定每个项目都适用) 1.制作授权登录框,引导用户点击按钮2.uni.login获取code3.把code传给后端接口,后端返回如下数据 openid: "ogtVM5RWdfadfasdfadfadV5s"status: 1// 状态码:status==0(该用户未注册,需调用注册接口) status==1(该用户已注册)4.判断用户是否注册,并调用用户信息接口(1)若已注册则提示登录成功,并调用后台给的获取用户信息的接口,并把数据保存到vuex(2)若未注册则调用注册接口,注册成功之后调获取用户信息接口,并把数据保存到vuex 制作授权登录框我把它写到一个组件里,在需要调用的页面注册该组件authorization.vue组件 <template> <view class="pop"> <view class="pop-main"> <i class="iconfont cancel" @click="cancel">&#xe614;</i> <view class="pop-title">需要您的授权</view> <view class="pop-text"> <view>为了提供更好的服务</view> <view>请在稍后的提示框中点击允许</view> </view> <image class="pop-imgsize" src="../static/images/aut.png" mode=""></image> <!-- 微信小程序的引导按钮,可以获取到用户信息 getuserinfo函数调用请求下面会讲到--> <button type="primary" class="reserve-btn" open-type="getUserInfo" @getuserinfo="getuserinfo">我知道了</button> </view> </view></template><script> import app from '../common/config.js' export default { data() { return { }; }, methods: { getuserinfo(res) { // 调用封装在app的_getuserinfo函数,_getuserinfo函数执行用户获取code,传code给后台,调用注册接口 app._getuserinfo(res) }, cancel() { this.$emit('cancelChild',false) } } }</script><style scoped>.pop { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,.3); z-index: 9999; display: flex; justify-content: center; align-items: center;}.pop-main { width: 690upx; height: 800upx; box-sizing: border-box; background-color: #FFFFFF; border-radius: 20upx; position: relative; display: flex; flex-direction: column; align-items: center; font-size: 14px; padding: 64upx 0upx 40upx 0upx;}/* 删除按钮 */.cancel { position: absolute; top: 20upx; right: 20upx; font-size: 20px;}.pop-title { padding-bottom: 40upx; width: 100%; border-bottom: 1px solid #BFBFBF; font-size: 16px; letter-spacing: 2px; text-align: center;}.pop-imgsize { width: 484upx; height: 406upx;}.pop-text { width: 75%; text-align: center; font-size: 15px; margin: 30upx 0upx; letter-spacing: 1px;}button { background-color: #08BF00; color: #FFFFFF; text-align: center; height: 88upx; line-height: 88upx; font-size: 14px; border-radius: 50upx; width: 78%;}</style>在个人中心页注册该组件 ...

November 2, 2019 · 3 min · jiezi

解析并截取小程序二维码上的参数转载

小程序分享二维码思路:a分享二维码给b,二维码上带有a的标识ppidb接收a的二维码打开页面,将接收到的ppid传递给后台,后台就可以知道b是通过a的二维码打开的页面 1.在后台设置识别二维码进入的页面,这里用index页面。2.在index页面是接收二维码里面的参数,解析并截取获取。二维码的参数格式:scene=ppid:12 export default { data() { return { ppid: "", } }, onLoad(option) { // 解析二维码里面的参数获得ppid this.ppid = this.scene_decode(decodeURIComponent(option.scene)).ppid //封装的scene_decode() 方法 if(this.ppid) { //我这里是把ppid存进vuex,然后在b注册时,把ppid传给后台 this.saveppid(this.ppid)// ppid 存进vuex } }, methods: { // 截取ppid的方法 scene_decode(scene) { var _str = scene + ""; var _str_list = _str.split(","); var res = {}; for (var i in _str_list) { var _tmp_str = _str_list[i]; var _tmp_str_list = _tmp_str.split(":"); if (_tmp_str_list.length > 0&&_tmp_str_list[0]) { res[_tmp_str_list[0]] = _tmp_str_list[1] || null; } } return res; } }}vuex里面存ppid的方法 ...

November 2, 2019 · 2 min · jiezi

小程序-svg-评估

不支持 svg 标签web 可以,但是小程序不可以,只能使用 image 标签引用 svg 文件。 解决办法有第三方插件可以提供变相支持:https://github.com/Tencent/omi/tree/master/packages/cax 但有差异,存在风险,不建议使用。 不支持内嵌图片的 svg<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200" width="200"/></svg>svg 如果内部有 image,image 部分会显示“图裂”。 解决办法图片转 base64 可以展示。

October 18, 2019 · 1 min · jiezi

小程序技能进阶回忆录-也许你并不需要小程序框架

你也许并不需要小程序框架。 市面上不停的会有大的公司推出自己的小程序的研发库 / 框架,功能十分强大,也为小程序的开发带来了便利。但在一些积极的反馈中,我们也看到不一样的声音: @白小虫:又一个轮子。。@jsweber:小程序不用任何框架,开发体验也不错啊,本身就借鉴了 vue 和 react 的思想。@月月木子:现在中上流公司的前端都很热衷于造自己的轮子或者给别人的轮子换皮然后说是自己的轮子,疯狂垒高自身的技术壁垒,即有了给领导吹牛的资本,让新来的人肯定属于不熟练工,又可以给自身带来安全感,不知道到底是好是坏。@redbuck:轮子越造越多,我寻思下一个小程序要不转回原生算了。@fantasy525:感觉一次编码全端支持没多大必要,支持的越多就可能会出越多的bug,我们开发时会很难受,本来只解决一端的bug,多端我们又要解决其他端,还不如各司其职好。@肉很多:学不动了呀。。。。????上列评论从掘金用户评论中挑选。这几天公司校招,面了一些在校生,其中有两位同学让人印象深刻: 一、同学 A 面试接近尾声突然问起,你们被美团收购后,是不是都要必须使用 mpvue(美团早年推出的小程序框架)?当我回答不是后,同学 A 长舒一口气:那就好。他解释道:更偏向用原生去写小程序,因为微信团队更新节奏比较快,框架经常跟不上微信的节奏,导致新特性无法在项目中使用。 二、同学 B 在简历中写道精通 jQuery,我在想这年头了,jQ 在简历中出现的越来越少了,故意抓着这个问了下,果然比较了解。他说道:经常用 jQ 做一些网页 demo,因为上手比较容易,直接引入一个cdn js就行,都不用装 node 包。 em... 好像说的都挺在理。 在摩拜单车内部,我们封装了基于微信小程序原生语法进行扩展、对原生微信 API 支持友好的小程序基础库 - Mozzy。注意:其定位是基础库,而不是框架。只要在原生语法的小程序项目里引入一个 js 文件就可以使用,即便是开发到一半的小程序也可以快速引入。 记得刚做完这个项目在公司内部分享时,说到未来的愿景时最后一句是: 也许有一天,当使用了 Mozzy 开发的小程序,删除 mozzy.js 后,发现功能竟然一切正常。相信早些年用 jQ 做项目的时候很多同学都脑洞过,要是浏览器原生支持 jQ 的 api 多好,或者干脆浏览器直接集成 jQ,就不用在每个项目的 html 里都引入一段 jQ 代码了,毕竟 jQ 在当年几乎是网页开发必备基础库。 随着微信官方 api 的更新,Mozzy 的很多实现都有了官方支持。也许当时分享的未来愿景已经来了,最近要开启删(改造) Mozzy 行动,换种方式存在于千万行代码中。 拥抱变化。 接下来的一系列文章里,会记录下 Mozzy 甚至是整个摩拜单车小程序研发细节和心路历程,可称为小程序技能进阶回忆录。 主要内容目录如下,大部分已经写完,会不定期进行更新: ...

October 17, 2019 · 1 min · jiezi

微信小程序授权登录取消授权重新授权处理方法-附可用代码

微信小程序授权登录基本是小程序的标配了,但是官方的demo,取消授权后,就不能再重新点击登录,除非重新加载小程序才可以,这下怎么办? 我们可以先在首页引导用户点击,然后跳转到一个新的页面,在新的页面进行授权,然后新的页面授权成功,立马跳回首页,显示用户信息。 话不多说,直接上代码代码结构: index是首页login是授权页 首页代码index.wxml <!-- 未授权,只显示一个授权按钮 --><view wx:if="{{result==false}}"> <button bindtap="getinfo" class="loginbtn"> 授权登录 </button></view><!-- 授权后只显示头像和昵称 --><view elif="{{result==true}}" class="info"> <image src="{{head}}" class="headimg"></image> <text class="nickname">{{name}}</text></view>index.wxss /**index.wxss**/.loginbtn{ width: 150px; height: 45px; background: #06C05F; margin:100px auto 0; line-height: 45px; font-size: 15px; color: #fff;}.info{ width: 80px; height: 100px; margin:50px auto 0;}.info .headimg{ width: 80px; height: 80px; border-radius: 100%;}.info .nickname{ text-align: center;}index.js //index.jsPage({ data: { userInfo: {}, hasUserInfo: false }, //事件处理函数 getinfo: function () { wx.navigateTo({ url: '../login/index' }) }, onLoad: function (e) { let that = this; // 获取用户信息 wx.getSetting({ success(res) { // console.log("res", res) if (res.authSetting['scope.userInfo']) { console.log("已授权") // 已经授权,可以直接调用 getUserInfo 获取头像昵称 wx.getUserInfo({ success(res) { console.log("获取用户信息成功", res) that.setData({ name: res.userInfo.nickName, head: res.userInfo.avatarUrl, result: true }) }, fail(res) { console.log("获取用户信息失败", res) that.setData({ result: "取消授权" }) } }) } else { console.log("未授权") that.setData({ result: false }) } } }) }})授权页代码index.wxml ...

October 17, 2019 · 1 min · jiezi

填坑手册小程序PC版来了如何做PC端的兼容

微信宣布小程序将可以在PC端微信打开后,智库君就接到要求,需要兼容PC端小程序,一开始以为官方已经做了完美适配,不需要改什么,但当本人下载内测版开始测试的时候,才发现或许坑还挺多的~~~ 下面分享下本人“搬砖填坑”的全过程:(以下都是PC端小程序特有的问题,手机端正常) 先说下使用流程 微信开发者工具菜单栏点击 设置->通用设置,在自动预览部分勾选“启动 PC 端自动预览”。使用自动预览功能,点击 预览->自动预览->编译并预览,成功的话将在微信 PC 版上自动拉起小程序。 PC版打开后就横屏问题 { "pages": [], "resizable":false, //在这里设置false,使得小程序默认手机尺寸 "pageOrientation":"portrait", //这里默认设置即可 ...}PC版微信默认打开小程序是ipad版,这样就会出现各种形变,布局错乱,这个可以在app.json进行配置,静止自动旋转,默认手机竖屏样子打开。 页面找不到问题 这个问题本人也找了很久,一直很纳闷IDE工具和手机打开看都没什么问题,用PC打开小程序就出现页面找不到的情况,大致报错是: page[pages/XXX/XXX] not found.May be caused by :1. Forgot to add page route in app.json.2. Invoking Page() in async task.一般这种情况以往是 app.json没配,或者页面里面缺少page(),但这次诡异的地方是只有“PC版小程序”报这个错!后来分析问题发现是:目前PC版小程序不能直接支持ES6,必须转换成ES5,同时由于一些语法转化不够完善,特别是ES7中的await 和 async 导致转化二次报错,这里就需要打开 “增强编译” 配置。 打开有CSS报错 因为目前PC版小程序估计内核的机制问题,还只支持低版本的选择器,如果你直接写小程序的标签,它无法识别,比如 .popCont navigator{ //navigator 标签是小程序里的,PC端无法支持 width: 560rpx; height: 300rpx;}.popCont image{ //image 标签是小程序里的,PC端无法支持 width: 560rpx; height: 300rpx;}但这些写法,其实在手机小程序和IDE工具里是完全正常的,PC版需要做兼容,改成class选择器。 布局结构混乱如果遇到这种情况,会检查一下是否使用屏幕尺寸(rpx)来计算布局,PC 上屏幕尺寸比窗口尺寸大,应该使用窗口尺寸来计算。 ...

October 16, 2019 · 1 min · jiezi

uniapp-用户拒绝授权再次调起授权语音识别微信地址微信附近地址

小程序重构,采用 uniapp 框架。记录一下踩过的坑。关于用户拒绝再次调起授权,及如何识别语音识别、微信地址、附近地址的处理。语音识别 组件语音识别,小程序只有录音功能,若要识别录音文件,常规做法是把录音文件传递给后端,然后由后端调用百度或讯飞语音识别接口,然后返回结果。但是微信小程序官方提供了“同声传译”插件,支持前端直接识别。可参考:插件介绍、插件使用文档uniapp 插件配置,在 manifest.json 文件中,源码模式,加入:..."mp-weixin": { ... "plugins" : { // 语音识别 - 同声传译 "WechatSI" : { "version" : "0.3.1", "provider" : "wx069ba97219f66d99" } }}调用<template> <view @click="asrStart">语音识别</view> <view>{{arsRes}}</view> <!-- 语音识别 --> <wechat-asr ref="weixinAsr" @callback="asrResult"/></template><script>import WechatAsr from '@/components/wechatASR.vue';export default { components: {WechatAsr}, data () { return { arsRes: '' } }, methods: { // 语音识别 asrStart () { this.$refs.weixinAsr.show(); }, asrResult (res) { this.arsRes = res; } }}</script>编写组件,其中关于授权,用户若拒绝了,再次点击,本来是会一直进入失败的回调中,导致没法再次打开授权界面。所以先获取授权信息,针对没有授权、授权拒绝、授权成功,分别再次处理。若授权拒绝,需要打开授权设置界面,让用户再次授权处理。<template> <!-- 微信语音识别 --> <view class="mask" v-show="isShow"> <view class="weixin-asr"> <view class="title">语音识别</view> <!-- 动画 --> <view class="spinner"> <view class="rect rect1"></view> <view class="rect rect2"></view> <view class="rect rect3"></view> <view class="rect rect4"></view> <view class="rect rect5"></view> </view> <view class="tip">说出姓名、电话和详细地址</view> <button class="btn" type="default" @click="recordStop">说完了</button> </view> </view></template><script> const WechatSI = requirePlugin("WechatSI"); const ASRManager = WechatSI.getRecordRecognitionManager(); export default { data () { return { isShow: false } }, onReady () { // 录音开启成功回调 ASRManager.onStart = function (res) { _this.isShow = true; } const _this = this; // 识别错误事件 ASRManager.onError = (res) => { _this.isShow = false; console.log(res.msg); } // 录音停止回调 ASRManager.onStop = function (res) { if (res && res.result) { _this.$emit('callback', res.result); } else { uni.showToast({ icon: 'none', title: '抱歉,没听到您的声音哦' }) } } }, methods: { data () { return { isShow: false, } }, show () { const _this = this; // 获取是否授权信息 uni.getSetting({ success(res) { if (res && res.authSetting && res.authSetting.hasOwnProperty('scope.record')) { if (res.authSetting['scope.record']) { start(); } else { // 拒绝授权,打开授权设置 uni.openSetting({ success() { start(); } }) } } else { start(); } } }) function start () { ASRManager.start({ lang: "zh_CN" }); } }, // 录音停止 recordStop () { this.isShow = false; ASRManager.stop(); } } }</script><style lang="scss" scoped> .mask { position: fixed; top: 0; left: 0; z-index: 300; width: 100%; height: 100%; background: rgba(0, 0, 0, .54); } .weixin-asr { position: absolute; top: calc(50% - #{477upx / 2}); left: 0; right: 0; margin: 0 auto; width: 560upx; height: 477upx; background: #fff; text-align: center; transform: .5s ease-out .5s; .title { margin-top: 42upx; color: #000; font-size: 34upx; font-weight: 500; } .spinner { margin: 50upx; height: 100upx; } .tip { color: #787878; } .btn { margin-top: 28upx; width: 225upx; height: 82upx; background: $theme1; color: #fff; font-size: 34upx; line-height: 82upx; border-radius: 82upx; } } .spinner { text-align: center; } .spinner > .rect { background-color: #EDAA35; height: 100%; border-radius: 13upx; width: 13upx; display: inline-block; -webkit-animation: stretchdelay 1.2s infinite ease-in-out; animation: stretchdelay 1.2s infinite ease-in-out; & + .rect { margin-left: 15upx; } } .spinner .rect2 { -webkit-animation-delay: -1.1s; animation-delay: -1.1s; } .spinner .rect3 { -webkit-animation-delay: -1.0s; animation-delay: -1.0s; } .spinner .rect4 { -webkit-animation-delay: -0.9s; animation-delay: -0.9s; } .spinner .rect5 { -webkit-animation-delay: -0.8s; animation-delay: -0.8s; } @-webkit-keyframes stretchdelay { 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 20% { -webkit-transform: scaleY(1.0) } } @keyframes stretchdelay { 0%, 40%, 100% { transform: scaleY(0.4); -webkit-transform: scaleY(0.4); } 20% { transform: scaleY(1.0); -webkit-transform: scaleY(1.0); } }</style>微信地址、附近地址它们的处理,和上面逻辑一样,只是调用的 api 不一样。 ...

October 15, 2019 · 3 min · jiezi

小程序营销组件solweapp

前言小程序营销组件全面升级,添加说明文档,优化代码,让开发变得更简单。 Sol Weapp ????Sol Weapp 是一套简单、易用、业务化的商城营销组件库。预览扫描下方小程序二维码体验示例: 开始之前 ????使用 Sol Weapp 前,请确保你阅读过微信官方的 小程序简易教程 和自定义组件介绍 。 使用下载 GitHub Sol Weapp 的代码,然后将 dist/ 目录下你需要的组件拷贝到你的组件目录下 git clone https://github.com/sunnie1992/sol-weapp.git 红包雨红包雨,在规定时间内屏幕下落红包,点击获取随机金额。 红包发放模式分为两种 红包总金额有上限,比如:15 秒 100 块金额随机生成 10 个红包下落速度不可控制。红包总金额无上限,比如:15 秒红包雨,可设置速度,设置每个红包随机金额的最大值最小值。引入{ "usingComponents": { "sol-packet-rain": "/dist/packet-rain/index" }}使用<sol-packet-rain visible="{{visible}}" total="{{total}}" mode="{{mode}}" createSpeed="{{createSpeed}}" decimal="{{decimal}}" number="{{number}}" time="{{time}}" readyTime="{{readyTime}}" min="{{min}}" max="{{max}}" bind:finish="success"></sol-packet-rain>API参数类型描述默认值visibleBoolean是否开始展示游戏falsemodeNumber红包发放模式 1 :红包总金额有上限2 :红包金额无上限1createSpeedNumber红包下落速度,数值越小,速度越快。mode 为 2 时生效 。400timeNumber游戏时间,单位秒15readyTimeNumber倒计时准备时间,单位秒5totalNumber红包总金额 mode 为 1 时生效 100numberNumber红包个数 mode 为 1 时生效 1minNumber单个红包,最小金额0maxNumber单个红包,最大金额3decimalNumber金额小数点后位数0bind:finishFunction完成后的回调函数-效果展示 大转盘点击抽奖,转盘或指针转动,结束后弹出对应奖项 注意因为抽奖涉及到奖品, 应该是后端控制中奖奖项,前端只用于展示 引入{ "usingComponents": { "sol-wheel": "/dist/wheel/index" }}使用<sol-wheel award-numer="{{award}}" ready="{{ready}}" mode="{{mode}}" bind:start="wheelStart" bind:success="wheelSuccess"></sol-wheel>API参数类型描述默认值areaNumberNumber奖项个数6awardNumerNumber中奖区域 顺时针从 1 开始1readyBoolean开始执行抽奖动画falsespeedNumber旋转速度16modeNumber抽奖模式 1:转盘旋转 2:指针旋转1bind:startFunction点击开始抽奖触发函数-bind:successFunction成功后的回调函数-效果展示 ...

October 15, 2019 · 1 min · jiezi

前端小程序笔试面试题

前言随便打开一个招聘网站, 你会发现市场上对小程序的需求还挺高的,虽然小程序一部分开发起来还是挺简单ok的,但一些常用的东西还是需要了解一下,因此总结了一篇有关小程序的面试题,希望对你我都帮组。 1、微信小程序有几个文件<font color='red'>WXML(WeiXin Markup Language)</font>是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。内部主要是微信自己定义的一套组件<font color='red'>WXSS (WeiXin Style Sheets)</font>是一套样式语言,用于描述 WXML 的组件样式<font color='red'>js </font>逻辑处理,网络请求<font color='red'>json </font>小程序设置,如页面注册,页面标题及tabBar2、微信小程序怎样跟事件传值给 HTML 元素添加 data-*属性来传递我们需要的值,然后通过 <font color='red'>e.currentTarget.dataset</font> 或 <font color='red'>onload</font>的 <font color='red'>param</font>参数获取。但 <font color='red'>data - </font>名称不能有大写字母和不可以存放对象3、小程序的 wxss 和 css 有哪些不一样的地方?<font color='red'> wxss</font>的图片引入需使用外链地址<font color='red'>没有 Body</font>;样式可直接使用 import 导入4、小程序关联微信公众号如何确定用户的唯一性使用 <font color='red'>wx.getUserInfo </font>方法 <font color='red'>withCredentials</font> 为 true 时 可获取 <font color='red'>encryptedData</font>,里面有 <font color='red'>union_id</font>。后端需要进行对称解密 5、微信小程序与vue区别生命周期不一样,微信小程序生命周期比较简单数据绑定也不同,微信小程序数据绑定需要使用{{}},vue 直接:就可以显示与隐藏元素,vue中,使用 v-if 和 v-show 控制元素的显示和隐藏,小程序中,使用wx-if 和hidden 控制元素的显示和隐藏事件处理不同,小程序中,全用 <font color='red'>bindtap(bind+event)</font>,或者 <font color='red'>catchtap(catch+event) </font>绑定事件,vue:使用<font color='red'> v-on:event</font> 绑定事件,或者使用@event 绑定事件数据双向绑定也不也不一样在 vue中,只需要再表单元素上加上 v-model,然后再绑定 data中对应的一个值,当表单元素内容发生变化时,data中对应的值也会相应改变,这是 vue非常 nice 的一点。微信小程序必须获取到表单元素,改变的值,然后再把值赋给一个 data中声明的变量。6、小程序的双向绑定和vue哪里不一样小程序直接 this.data 属性是不可以同步到视图的,必须调用: this.setData({ // 这里设置})7、简述微信小程序原理微信小程序采用 <font color='red'>JavaScript、WXML、WXSS</font> 三种技术进行开发,本质就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口微信的架构,是数据驱动的架构模式,它的 UI 和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现小程序分为两个部分 <font color='red'>webview </font>和 <font color='red'>appService</font> 。其中 webview 主要用来展现 UI ,appService 有来处理业务逻辑、数据及接口调用。它们在两个进程中运行,通过系统层 <font color='red'>JSBridge</font> 实现通信,实现 UI 的渲染、事件的处理8、小程序的生命周期函数<font color='red'>onLoad </font> 页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数<font color='red'>onShow()</font> 页面显示/切入前台时触发<font color='red'>onReady()</font> 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互<font color='red'>onHide()</font> 页面隐藏/切入后台时触发。 如 navigateTo 或底部 tab 切换到其他页面,小程序切入后台等<font color='red'>onUnload() </font> 页面卸载时触发。如 redirectTo 或 navigateBack 到其他页面时9、哪些方法可以用来提高微信小程序的应用速度1、提高页面加载速度 ...

October 14, 2019 · 2 min · jiezi

小程序模板消息能力调整新的订阅消息将不受时间限制

昨日,微信在小程序模块消息能力方面公布了一项重大调整。原有的模块消息将升级为「订阅消息」,支持一次性和长期性订阅消息。而模块消息将于2020年1月10日下线,小程序将无法再使用原接口推送模板消息,因此开发者需要及时进行调整。 以往,模块消息作为服务进度提醒和召回用户的重要入口,受到了不少小程序运营者的青睐。但是,部分小程序利用「模板消息」推送营销广告甚至是虚假信息诱导点击。为用户带来骚扰,也影响了微信小程序生态的良好运行。 另一方面,模块消息需要在用户点击触发之后的7天内进行推送,但对于服务周期超过7天的小程序,「模板消息」无法满足它们的需求。 因此,微信对模板消息下发条件进行了调整,将小程序的推送进行场景化细分,每个推送模块都需要经过用户主动授权。用户只有根据需求进行订阅,才会收到小程序的服务通知,并且消息推送没有时间限制,部分公共服务场景还提供了长期订阅功能。 「订阅消息」消息类型新上线的「订阅消息」消息类型分为两种: 一次性消息推送 :用户订阅一次后,小程序可不限时间地推送一条订阅消息。如果用户想避免重复授权,可以勾选“总是保持以上选择,不再询问”并点击允许,以后便默认同意订阅这类消息,无须做多次选择。 长期性消息推送:用户订阅一次后,小程序可长期推送多条消息。目前长期性订阅消息仅面向政务、医疗、交通、金融、教育等线下公共服务小程序开放,后续将根据行业需求和用户体验不断进行完善。 「订阅消息」会带来什么影响?「订阅消息」的更新,意味着用户不再被动地接收信息,小程序消息推送的选择权回到用户手中。以往,当用户选择接收推送后,小程序便不加区分地将服务信息、营销信息统统推送给用户。现在,用户能够自主选择小程序的消息,也可以随时拒收该小程序的服务通知。 对于开发者而言,由于用户主动订阅才可以推送消息,之前通过不断收集formid来发送消息模板的操作将会失效,小程序开始走向人性化、精细化运营。 另一方面,「订阅消息」取消了7天内推送消息的限制,推送时间更加灵活并且能够契合多样化的服务需求。只要用户没有主动拒收,开发者就可以随时推送服务通知。使消息触达更加高效,也使用户唤醒更加方便。 「订阅消息」能用在什么地方· 用户召回对于低频、长线服务的小程序而言,订阅消息在用户召回方面显得更为重要。小程序提供实用的服务功能,让用户主动授权。在退出小程序后,小程序依然能结合场景因素,在后续选择合适的时间为用户提供服务消息,再次唤醒沉默的用户。 但是在召回用户同时,开发者需要顾及用户体验。根据订阅消息运营规范,使用订阅消息能力进行诱导订阅、诱导点击、内容与用户预期不符都会被视为违规。因此,订阅后解锁某个操作,或者订阅后获得奖励都是不被允许的。详见==小程序订阅消息接口运营规范==:https://developers.weixin.qq.... · 刚需服务既然订阅消息的选择权在用户手里,那么小程序能否提供用户需要的服务则成为关键。订阅消息可以更精准化、个性化,引导用户在不同场景内去订阅。例如生活类小程序的服务进度提醒、电商小程序的降价通知、内容小程序的话题推送等等。 针对不同行业的小程序,微信提供了各种消息模板,开发者可在后台选择相应的模板使用。比如,针对小游戏,微信就提供了排行榜、新功能发布、活动结束、版本更新、道具领取等14种通用模板。 在原来的模块消息下线之前,开发者们注意对接口进行及时调整。接入「订阅消息」能力,==可参考接口文档==:https://developers.weixin.qq.... 我们最近新建了个WeGeek技术交流群,欢迎小程序开发同好者进群交流,调戏勾搭群里的云开发大神~扫码添加Wegeek小助手即可获取进群方式。

October 14, 2019 · 1 min · jiezi

小程序生成海报通过-json-配置方式轻松制作一张海报图

背景由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 Canvas 功能生成一张带有二维码的图片,然后引导用户下载图片到本地后再分享到朋友圈。而小程序 Canvas 功能是很难用的,往往为了绘制一张简单图片,就得写上一堆 boilerplate code ,而且一不小心还会踩到 Canvas 的各种彩蛋(坑)。我想此时你的心情肯定是这样的。 分析想到小程序中有如此大量的生成图片需求,而 Canvas 生成方法又是如此难用和坑爹。那我们就想到可不可以做一款可以很方便生成图片,并且还能屏蔽掉直接使用 Canvas 的一些坑的库呢?所以我们发起了 “画家计划— 通过 json 数据形式,来进行动态渲染并绘制出图片”。 Painter 库的整体架构如下: 首先,我们定义了一套绘图 JSON 规范,开发者可以根据需求构建生成图片的 Palette(调色板),然后在程序运行过程中把调色板传入给 Painter(画家)。Painter 会调用 Pen(画笔),根据 Palette 内容绘制出对应的图片后返回。 解决问题那可不可以开发一款生成海报的插件库呢? 首先,只需要提供一份简单的参数配置文件即可解决掉小程序Canvas遇到的一些大大小小的坑有严苛的测试环节,解决各种环境和各种机型遇到的问题,并提供稳定的线上版本长期维护,并有专人更新迭代更新颖的功能隆重介绍Painter 的优势 功能全,支持文本、图片、矩形、qrcode 类型的 view 绘制布局全,支持多种布局方式,如 align(对齐方式)、rotate(旋转)支持渐变色,阴影,配置简单,容易上手,兼容性好支持圆角,其中图片,矩形,和整个画布支持 borderRadius 来设置圆角杠杠的性能优化,我们对网络素材图片加载实现了一套 LRU 存储机制,不用重复下载素材图片。杠杠的容错,因为某些特殊情况会导致 Canvas 绘图不完整。我们对此加入了对结果图片进行检测机制,如果绘图出错会进行重绘。How To Use运行例子git clone https://github.com/Kujiale-Mobile/Painter.git代码下载后,用小程序 IDE 打开后即可使用。 注:请选择小程序项目,非小游戏,例子中无 appid,所以无法在手机上运行,如果需要真机调试,请在打开例子时,填上自己的小程序 id 具体详细使用教程 GitHub 地址https://github.com/Kujiale-Mobile/Painter 扩展工具由于编写配置再加上调试还是有些麻烦,故制作一款可视化编辑工具,直接拖动编辑元素即可生成海报可视化编辑拖拽直接生成painter代码 工具体验地址https://lingxiaoyi.github.io/painter-custom-poster/工具使用文档https://juejin.im/post/5d8b20ba51882509615bca09例子展示

October 14, 2019 · 1 min · jiezi

小程序下拉刷新

在小程序中onLoad生命钩子只在页面创建时调用一次,在做navigateTo页面跳转后,返回上级页面,由于navigateTo跳转只是隐藏了当前页面,因此返回上一级页面时onLoad生命钩子不会再次执行,这样带来的好处是页面能快速展示出来,但是onLoad中的请求数据不会实时更新,这时候就需要一个下拉刷新的操作来帮助用手动更新页面数据,接下来这篇文章将会介绍小程序中实现下拉刷新的三种方式 enablePullDownRefreshenablePullDownRefresh是最容易实现下拉刷新的方法,在json文件中将enablePullDownRefresh设置为true,在Page中监听onPullDownRefresh事件即可,支持点击顶部标题栏回到顶部,自定义标题栏时会失效,还可以通过直接调用wx.startPullDownRefresh()触发下拉刷新事件,产生下拉刷新动画,处理完下拉刷新中的数据更新后调用wx.stopPullDownRefresh()结束动画即可。这种形式的下拉刷新的优点很明显就是简单,没有限制,但是缺点也同样明显: 下拉动画太过简单,交互不够优雅且不能自定义下拉动画当自定义标题栏时,fixed定位,在Android下标题栏也会被一起下拉,如图所示: scroll-viewscroll-view是官方的一个滚动视图组件,使用很简单,想要设置上拉刷新代码如下: <scroll-view class="scroll" scroll-y bindscrolltoupper="refresh"> <view class="content">content</view></scroll-view>想要利用scroll-view实现上拉刷新,需要注意: 一定要给scroll-view设置固定高度,否则监听事件不会触发设置纵向滚动scroll-yscroll-view内的内容高度一定要比scroll-view高度要高,否则无法产生纵向滚动,就无法触发监听事件scroll-view缺点: 由于iOS有橡皮筋效果,因此最终效果会与Android有一定的差异刚打开页面时上拉是无法触发上拉监听事件,需要先向下滚动,触发滚动,然后再上拉滚动才能触发监听事件当有自定义头部时,scroll-view需要一个高度计算,减去头部高度scroll-view优点: 可以自定义加载动画代码相对简单相对enablePullDownRefresh,scroll-view对滚动列表控制更加方便: scroll-into-view:滚动到指定元素enable-back-to-top:iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向,且当自定义标题栏后就会失效官方并不推荐使用scroll-view做下拉刷新,官方文档上有这样一个tip: 自定义下拉刷新自定义下拉刷新最主要希望解决的问题还是在Android使用enablePullDownRefresh时fixed定位的标题栏或导航栏会被下拉的问题,同时两端在下拉刷新时的动画保持一致,其实实现起来并不难,接下来就看看具体实现:wxml: <view class="scroll" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"> <view class="animation"> <view class="loading"></view> <text class="tip">{{state === 0 ? '下拉刷新' : state === 1? '松开刷新' : '刷新中'}}</text> </view> <view style="transform: translateY({{translateHeight}}rpx)"> <slot name="content"></slot> </view></view>这个文件定义组件的模版,有一个滚动view包裹,绑定了touch事件,里面包含下拉刷新时的动画,和一个slot,slot用于插入滚动列表的内容wxss: .animation { display: flex; justify-content: center; align-items: center; width: 100%; height: 150rpx; margin-bottom: -150rpx; background-color: #fff;}.loading { width: 30rpx; height: 30rpx; border:6rpx solid #333333; border-bottom: #cccccc 6rpx solid; border-radius: 50%; animation:load 1.1s infinite linear; }@keyframes load{ from{ transform: rotate(0deg); } to{ transform: rotate(360deg); }}.tip { margin-left: 10rpx; color: #666;}样式文件这没什么特别的js: ...

October 4, 2019 · 2 min · jiezi

小程序模块化

原本需要 24 个工作日才能完成的任务,我却在 0.5 个工作日内完成了,是如何实现的呢?趁着放假有空,写篇文章给大家分享一下我们小程序模块化加速项目开发的思路吧。阅读基础:有小程序项目经验,有查阅官方文档习惯的小伙伴 随着公司小程序项目日益繁多,仅仅靠着官方提供的框架、组件、API,已经远远不能满足项目高效迭代的要求了,于是我们组内萌生了对小程序进行模块化的想法。 实际项目中我们对小程序模块化已经涉及各个模块,我总结一下,从三个方向跟大家分享我们不一样的模块化思路:Page+,basePage,适配层。 Page+Page()作为页面的入口,我们可以通过对其入参对象的封装实现:生命周期的改造、全局状态管理和新增页面功能。 官方删除了小程序分享回调 complete,一起来尝试将其恢复吧。一般我们的逻辑是这样的: // pages/index/index.jsPage({ // 数据初始化 data: { shareFlag: false, //页面是否处于分享中 shareComplete: false //分享回调事件 }, // onShow 生命周期 onShow: function () { const { shareFlag, shareComplete } = this.data if( shareFlag ){ this.data.shareFlag = false //变量不涉及页面渲染,不使用 setData shareComplete && shareComplete() } }, // 分享事件 onShareAppMessage: function () { let shareInfo = { title: '分享测试标题', path: '', complete: function () { console.log('页面分享成功啦~') } } this.data.shareFlag = true this.data.shareComplete = typeof (shareInfo.complete) == 'function' ? shareInfo.complete : false return shareInfo }})在单页面内实现分享回调这样操作是可行的,如果多页面、多项目都要实现该功能,重复拷贝代码,则显格外得繁琐。 ...

October 2, 2019 · 3 min · jiezi

小程序滚动事件监测当前内容到顶部的距离

/** * 滚动事件 */ onPageScroll(e) { var that = this; that.scrollTop = e.scrollTop; console.log(that.scrollTop) },

September 20, 2019 · 1 min · jiezi

使用-Taro-Hooks-快速开发一个小程序-GitHub-Pro

在 Taro Hooks 出来 之后就一直想着体验一波 Hooks 小程序开发,不过一直忙着补番 ????。最近补完了,就搞了起来,开发了 20 天左右(其实大部分时间都在改 UI????),基本上是完成了,然后也上架了,遂跟大家分享一点心得 ???? 可以先扫描体验: 网络不稳定的小伙伴看预览: 在 GitHub Pro 的开发中,我写了四个 hooks,来帮助我提高开发效率 useRequestuseRequestWithMoreuseReachBottomEventusePullDownRefreshEvent接下来就分析一下它们的作用 useRequest作用同名字,用来进行网络请求,传入请求参数以及进行请求的函数,存储数据,返回 [currData, refresh] ,其中currData是存储的返回数据,refresh用于刷新请求。 function useRequest<T>( params: any, request: (params: any) => Promise<T | null>): [T | null, () => void] | [] { const [currData, setData] = useState<T | null>(null) const [count, setCount] = useState(0) const pagePullDownRef = useRef('') useEffect(() => { request(params).then(data => { if (data) { setData(data) } }) }, [count]) usePullDownRefresh(() => { refresh() }) useEffect(() => { events.on(PULL_DOWN_REFRESH_EVENT, (page: string) => { if (!pagePullDownRef.current) { pagePullDownRef.current = page } else if (pagePullDownRef.current !== page) { return } refresh() }) return () => { events.off(PULL_DOWN_REFRESH_EVENT) } }, []) const refresh = () => { setCount(count + 1) } return [currData, refresh]}export default useRequestuseRequest ...

September 19, 2019 · 3 min · jiezi

小程序的缺陷和弥补方案

前言记得16年底到17年初的时候,那时小程序刚出来,我也通过渠道获取了未正式发布的开发工具,准备一探究竟。结果看到一堆自创概率之后便望而却步。那时我狂热地追随 React,眼里哪还能容得下第二个框架。遂放弃。 2年多过去了,现在小程序如日中天,我不得不继续忽视它了(要恰饭的嘛),但是我好奇,为什么小程序会让我不爽,觉得不如 React,为什么 React 已经这么优秀和流行了,小程序不仿照它呢?遂作此文,记录下开发过程遇到的问题与思考。 在写这篇文章的时候,我力求不谈谁更先进,只谈谁更好用。1. 组件自定义函数在 React 中,构建组件采用的是类的方式,而小程序是对象方式。 // React 写法class Table extends Component { method1() { console.log(this.attr1); } method2() { this.method1(); }}// 小程序写法Component({ methods: { method1() { console.log(this.attr1); }, method2() { this.method1(); }, },});1. 概念问题两者组件自定义方法都会被挂到 this 下。这点 React 很明显,就是 js 语法,没有学习成本。但是在小程序中,由于构造函数(Component)的不透明性,方法被挂到 this 下这点就必须灌输给用户。 2. 绑定问题React 中需要绑定函数 this 的话,可以在 constructor 中处理,类似的,小程序可以在 created 生命周期中处理。但是 React 中还有一种骚写法,就是改写为箭头函数来完成 this 绑定,这个在小程序中是做不到的。 // React 写法class Table extends Component { constructor(props) { super(props); // 显式 bind this.method1 = this.method1.bind(this); } method1() { console.log(this.attr1); } // React 的骚写法:箭头函数 method2 = () => { this.method1(); };}// 小程序写法Component({ methods: { method1() { console.log(this.attr1); }, method2() { this.method1(); }, }, created() { // 只能显式 bind this.method1 = this.method1.bind(this); this.method2 = this.method2.bind(this); }});持续更新中,未完待续... ...

September 7, 2019 · 1 min · jiezi

小程序自适应canvas

wxml <canvas style="width: 686rpx;height: 686rpx;background:#f1f1f1;" canvas-id="qrcCanvas"/><input value='{{qrcStr}}' bindblur="onQrcStrBlur" type="text" maxlength="255" />js data:{ qrStr:'xxx' 需要生成字段 canvasId: "qrcCanvas",//需要绘画的元素 } //适配不同屏幕大小的canvas setCanvasSize(){ var size={}; try { var res = wx.getSystemInfoSync(); var scale = 750/686;//不同屏幕下canvas的适配比例;设计稿是750宽 var width = res.windowWidth/scale; var height = width;//canvas画布为正方形 size.w = width; size.h = height; } catch (e) { // Do something when catch error console.log("获取设备信息失败"+e); } return size; //返回大小 } , createQrCode(str,canvasId,cavW,cavH){ //调用插件中的draw方法,绘制二维码图片 qrCode.api.draw(str,canvasId,cavW,cavH); }, //获取input输入的值 onQrcStrBlur(e) { this.setData({qrcStr: e.detail.value}); }, //在 onReady调用 onReady: function() { let size = this.setCanvasSize();//动态设置画布大小 this.createQrCode(this.data.qrcStr, this.canvasId, size.w, size.h); },

August 27, 2019 · 1 min · jiezi

小程序实时音视频实践

微信小程序成为当下热门话题,下面从多个方面来谈谈小程序直播功能开发过程详解 。 2017年下半年,微信6.5.21版本支持在线音视频功能。开发者可以通过两个音视频组件 <live-pusher> 和 <live-player> 实现实时地在线直播、视频通话、语音通话等功能。 本期小程序课,微信开发哥将详细为大家介绍一下音视频组件在线直播和视频通话这两个应用场景。 在线直播该怎么做? 在线直播的应用场景有哪些? 在游戏直播、远程授课、以及企业内部的培训分享等场景中,都可能会用到在线直播功能,直播的应用场景可以遍及各行各业。 比如微信电竞是一款游戏直播产品,以小程序为产品呈现方式。 比如在医疗行业,专家医师往往需要全国各地飞进行学术交流和培训,出差本身耽误了医生大量时间,在线远程授课能大大减少这里的时间耗用。 小程序中的 <live-pusher> 和 <live-player> 两个组件 ,都有一个叫做live ( <live-pusher> 中对应 mode 属性为 SD, HD, FHD)的模式,专门为在线直播而设计,通过小程序的音视频接口的live 模式,可以实现上述应用场景。 02在线直播的内部原理是什么? 主播端使用 <live-pusher> ,它在小程序的内部是一个推流引擎,它负责对手机摄像头和麦克风的数据进行采集和编码,并通过 url 参数指定的 rtmp 推流地址上传到云端。 云端的作用类似信号放大器,它负责将来自主播端的一路音视频流数据进行放大,将数据实时并且无差异的负责并扩散到全国各地,从而解决主播和观众端之间距离太远(比如,跨地区和跨运营商)的问题。 观众端使用 <live-player> 进行播放,它在小程序的内部是一个在线播放器,负责从云端实时拉取音视频数据并进行解码和渲染。由于云端的放大效应,每一个观众都能在离自己比较近的云服务器上拉取到实时且流畅的音视频流。   下面从多个方面来谈谈 微信小程序怎么做直播。     怎么用小程序实现在线直播? step1:开通一个云直播服务(比如 腾讯云 ),或者自己搭建一个rtmp服务器(例如 nginx-rtmp 服务)。step2:生成推流 url ,推流地址一般以 “rtmp://” 打头,比如  rtmp://8888.livepush.myqcloud.com/live/8888_test 就是一个典型 rtmp 推流 Url。step3:为你的小程序增加一个 <live-pusher> 标签,并将 url 参数指定为你在 step2 中生成的推流 url。同时, <live-pusher> 的 mode 参数可以指定为 HD 或者 FHD,这是在线直播场景中比较推荐的画质。 同时,你还可以通过 <live-pusher> 的 beauty 和 whiteness 等参数设定美颜和美白等级。 step4:生成推流 url 和播放地址,推流一般都是 rtmp:// 打头的 url,而播放地址则有两种选择,分别是 “rtmp://” 开头的 rtmp 播放协议,“http://” 打头和“.flv”结尾的的 http-flv 播放协议,推荐使用后者,因为这种播放地址各个云厂商都优化的比较好。step5:为你的小程序增加一个 <live-player> 标签 ,并将 src 参数指定为你在 step4 中生成的播放 url。同时, <live-player> 的 mode 参数请指定为 live, orientation  和 object-fit 属性可以用于调整画面布局, min-cache 和 max-cache 则可以用于控制观众跟主播之间的延时大小,推荐的设置是 min-cache = 2, max-cache = 5。关于在线直播 ...

August 21, 2019 · 2 min · jiezi

微信小程序-webview-与-h5-通过-postMessage-实现实时通讯的实现

原文:https://pantao.parcmg.com/pre... 在做 React Native 应用时,如果需要在 App 里面内嵌 H5 页面,那么 H5 与 App 之间可以通过 Webview 的 PostMessage 功能实现实时的通讯,但是在小程序里面,虽然也提供了一个 webview 组件,但是,在进行 postMessage 通讯时,官方文档里面给出了一条很变态的说明: 网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data },data 是多次 postMessage 的参数组成的数组这里面已经说的很明白了,不管我们从 H5 页面里面 postMessage 多少次,小程序都是收不到的,除非: 用户做了回退到上一页的操作组件销毁用户点击了分享这里面其实我没有完全说对,官方其实说的是 小程序后退,并没有说是用户做回退操作,经过我的实测,确实人家表达得很清楚了,我们通过微信官方的SDK调起的回退也是完全可行的: wx.miniProgram.navigateBack()大体思路从上面的分析和实测中我们可以知道,要实现无需要用户操作即可完成的通讯,第三种情况我们是完全不需要考虑了的,那么来仔细考虑第 1 和第 2 种场景。 第 1 种方式:回退当我们想通过网页向小程序发送数据,同时还可以回退到上一个页面时,我们可以在 wx.miniProgram.postMessage 之后,立马调用一次 wx.miniProgram.navigateBack(),此时小程序的操作是: 处理 postMessage 信息回退到上一页我们在处理 postMessage 的时候做一些特殊操作,可以将这些数据保存下来 第 2 种方式:组件销毁这是我感觉最合适的一种方式,可以让小程序拿到数据,同时还保留在当前页面,只需要销毁一次 webview 即可,大概的流程就是: 小程序 postMessage小程序 navigateTo 将小程序页面导向一个特殊的页面小程序的那个特殊页面立马回退到 webview 所在的页面webview 所在的页面的 onShow 里面,做一次处理,将 webview 销毁,然后再次打开触发 onMessage 拿到数据H5 页面再次被打开这种方式虽然变态,但是至少可以做到实时拿到数据,同时还保留在当前 H5 页面,唯一需要解决的是,在做这整套操作前,H5 页面需要做好状态的缓存,要不然,再次打开之后,H5 的数据就清空了。 ...

August 20, 2019 · 4 min · jiezi

小程序如何在不同设备上自适应生成海报

小程序canvas的API并没有像其他的一样支持小程序独有的 rpx 自适应尺寸单位,在绘制内容时所应用的单位仍然是 px,那么如何实现不同尺寸屏幕的自适应呢? 我们的在开发中常用的参考屏幕尺寸(iPhone6)为:375*667; 那么想要适应其他尺寸的屏幕时只需按照iPhone6的绘制大小按比例进行换算即可: 获取系统屏幕尺寸先利用wx.getSystemInfo (获取系统信息)的API获取屏幕宽度,然后除iPhone6的屏幕宽度,即可得到相对单位 // 在onLoad中调用const that = thiswx.getSystemInfo({ success: function (res) { console.log(res) that.setData({ model: res.model, screen_width: res.windowWidth/375, screen_height: res.windowHeight }) }})在绘制方法中将参数乘以相对单位即可实现自适应这里的rpx是相对不同屏幕宽度的相对单位,测量出得实际宽度,就是实际测出的px像素值*rpx就可以了;之后无论实在iPhone5,iPhone6,iPhone7...都可以进行自适应。 这里的html也要动态的设置宽和高 <canvas canvas-id="PosterCanvas" style="width:{{screen_width*375+'px'}}; height:{{screen_height*1.21+'px'}}"></canvas>drawPoster(){ let ctx = wx.createCanvasContext('PosterCanvas'),that=this.data; console.log('手机型号' + that.model,'宽'+that.screen_width*375,'高'+ that.screen_height) let rpx = that.screen_width //这里的rpx是相对不同屏幕宽度的相对单位,实际的宽度测量,就是实际测出的px像素值*rpx就可以了;之后无论实在iPhone5,iPhone6,iPhone7...都可以进行自适应。 ctx.setFillStyle('#1A1A1A') ctx.fillRect(0, 0, rpx * 375, that.screen_height * 1.21) ctx.fillStyle = "#E8CDAA"; ctx.setFontSize(29*rpx) ctx.font = 'normal 400 Source Han Sans CN'; ctx.fillText('Hi 朋友', 133*rpx,66*rpx) ctx.fillText('先领礼品再买车', 84*rpx, 119*rpx) ctx.drawImage('../../img/sell_index5.png', 26*rpx, 185*rpx, 324*rpx, 314*rpx) ctx.drawImage('../../img/post_car2x.png', 66 * rpx, 222 * rpx, 243 * rpx, 145 * rpx) ctx.setFontSize(16*rpx) ctx.font = 'normal 400 Source Han Sans CN'; ctx.fillText('长按扫描获取更多优惠', 108*rpx, 545*rpx) ctx.drawImage('../../img/code_icon2x.png', 68 * rpx, 575 * rpx, 79 * rpx, 79 * rpx) ctx.drawImage('../../img/code2_icon2x.png', 229 * rpx, 575 * rpx, 79 * rpx, 79 * rpx) ctx.setStrokeStyle('#666666') ctx.setLineWidth(1*rpx) ctx.lineTo(187*rpx,602*rpx) ctx.lineTo(187*rpx, 630*rpx) ctx.stroke() ctx.fillStyle = "#fff" ctx.setFontSize(13 * rpx) ctx.fillText('xxx科技汽车销售公司', 119 * rpx, 663 * rpx) ctx.fillStyle = "#666666" ctx.fillText('朝阳区·望京xxx科技大厦', 109 * rpx, 689 * rpx) ctx.setFillStyle('#fff') ctx.draw() },如果图片是线上地址 ctx.drawImage()会出错,不能画出图片因为会访问一个get请求,是一个异步操作,还没等到get返回就执行了tx.draw()绘制画布。 解决方案 就只在 wx.downloadFile()中成功下载了图片在进行绘制画布。 ...

August 19, 2019 · 2 min · jiezi

小程序踩坑记

小程序踩坑记希望这个文章 能尽量记录下小程序的那些坑,避免开发者们浪费自己的生命来定位到底是自己代码导致的还是啥神秘的字节跳变原因 。 前记小程序大多数坑是同一套代码在不同平台上表现不一致导致的,微信开发者工具,Android,iOS。千万不要以为自己写的代码在模拟器上跑过了就完事了,一定需要在 Android 和 iOS 真机上再测一遍,否则后果不堪设想。之所以有如此坑爹的情况,也是由于小程序在不同系统下使用的底层框架不一致导致的,如下图所示。 另:小程序的视图层和 js 代码运行在不同的地方,相当于小程序的视图层运行在浏览器中,而 js 运行在原生的 js 解析引擎上。这也是为啥小程序的 js 无法获得 dom 和 bom 的原因。 坑们1,onShareAppMessage 中设置封面在 Android 和 iOS 上展示策略不一致相关文档 https://developers.weixin.qq.... 现象 当设置的 imageUrl 不是 5:4 的图片时,比如 5:3 时,就会出现下列情况,左边是在 Android 上的展示,右边是 iOS上的。两者对分享消息的封面展示策略并不一样。 版本 明显 iOS 上更合理一点,目前 Android 微信版本 6.6.7 依然会发生这种情况。 解决 像这种非 5:4 的图片,尽量也弄成 5:4 的,然后多余部分用白色进行填充。 2,wx.showToast 在 iOS 和 Android 上行为不一致相关文档 https://developers.weixin.qq.... 现象 当 showToast 后,马上返回上一个页面,在 Android 上,toast 依然存在,但 iOS 上 toast 无法显示。感觉是因为在 Android 上这个 toast 是全局的,而 iOS 上 toast 只是依附于某个页面。 ...

August 19, 2019 · 2 min · jiezi

从px到rpx了解微信小程序开发

我一直在想,我是不是有必要再写这一节,还是给大家提供一些阅读链接。因为关于单位的定义都是比较官方的。没什么好讨论的,我这里做一个汇总和简单的说明吧。首先本文只以移动设备为例说明。本文摘要:设计师以iphone6为标准出设计稿的话,1rpx=0.5px=1物理像素。Photoshop里面量出来的尺寸为物理像素点。所以可以直接使用标注尺寸数据。--------------------------------------看懂本文摘要的话,就不用阅读下面的内容了-------------------------------------【英寸Inch】英寸表示屏幕斜对角线的长度。如下图所示: 【像素Pixel】像素是图像的基本采样单位,它不是一个确定的物理量,因为像素点的物理大小是不确定的。如图: 【分辨率】分辨率是屏幕像素的数量,一般用屏幕宽度的像素点乘以屏幕高度的像素点。如描述iphone6的分辨率是750*1334.分辨率又分为【物理分辨率】和【逻辑分辨率】,值得注意的是实际工作中设计师常常给的是物理分辨率,程序中用到的是逻辑分辨率,但是都称为分辨率,容易混淆。【物理分辨率】是硬件所支持的分辨率,【逻辑分辨率】是软件可以达到的分辨率。物理分辨率和逻辑分辨率的商称为【像素倍率dpr】,也就是常说的几倍屏。如下图中所示,iphone6的分辨率写着375667,这里指的就是它的逻辑分辨率。我们上面提的7501334则是它的物理分辨率。所以iphone6的像素倍率=(7501334)/(375667)=2 理解了上述的几个概念,我们就可以接着来看下面的几个单位。【px】px就是Pixel的缩写,就是指像素。这个作为图片采样的基本单位,没什么需要特别说明的。【rem】在做移动端适配是最常用的方法就是使用rem作为单位,因为rem是根据html的fontsize去动态计算实际的px的。所以常常应用这点,做反向使用。即根据屏幕大小动态的设置fontsize.来达到不同的分辨率下有一样的效果。【rpx】rpx其实是微信对于rem的一种应用的规定,或者说一种设计的方案,官方上规定屏幕宽度为20rem,规定屏幕宽为750rpx。所以在微信小程序中1rem=750/20rpx。但是这不是我们要关注的重点。在使用rem时,我们常常让设计师根据iphone6的标准出设计稿。因为如果以iphone6为标准,并且在iphone6上将fontsize设置成62.5%。那么1rem就等于10px,我们只要将设计师标注的尺寸(一般标注的是物理分辨率)除以20就可以得到单位为rem的数值了。在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。css中的px与设备的物理像素并非绝对的一比一关系。px与物理像素的比例与设备的dpr(像素倍率)有关。rpx称为相对像素值,rpx与物理像素也并非绝对的一比一关系。wxss将设备宽定义为750rpx,是以iPhone6的分辨率(750x1334)为基准划分的。也就是说,在iPhone6上,1rpx=1物理像素=0.5px。因为设计师标注的尺寸一般是物理分辨率。所以如果以iphone6为标准出设计稿的话,那么我们就可以不需要经过换算直接标准rpx。这节课的内容就到这里结束了。感谢您的阅读。

August 19, 2019 · 1 min · jiezi

如何理解小程序系统参数屏幕宽度和窗口宽度

我们可以通过wx.getSystemInfo获取小程序的当前系统参数,那么大家对这里面的屏幕维度和窗口维度能正确区别吗? https://developers.weixin.qq.... 屏幕宽高指设备的宽高,窗口宽高指可用区域宽高,比如你用了小程序的tabbar和navigator,那,窗口高度就会被比屏幕高度小。 屏幕宽度和窗口宽度在大多数情况应该都是一样的,比如什么时候小程序只在屏幕里占一半宽了,那他们就不一样了。

August 19, 2019 · 1 min · jiezi

实操总结小程序裂变0成本获客3要素

本文主要分享下面3个方面:重新理解微信社交关系链,设计小程序的3个心得,小程序裂变实操案例详解。首先感谢大家今天在这里一起交流,我们主要是做营销方面,今天跟大家主要分享下面3个方面: 重新理解微信社交关系链 设计小程序的3个心得 小程序裂变实操案例详解 跟大家分享一下我们这2个月里尝试“小程序裂变”的一些心得。 一、重新理解微信社交关系链 之前我们团队主要是设计如何驱动用户分享微信朋友圈的玩法,展现是形式是H5、公众号、群裂变等;所以准备做小程序时,首先想验证的是我们已有的裂变经验能不能复用。 经过这2个月的实验验证,发现小程序的裂变和H5的裂变都遵循相同的规则,因为都是基于用户的社交关系链。 所以第一部分,先跟大家分享一下:什么样的微信社交关系链适合裂变。 实操总结:小程序裂变0成本获客3要素 1.1 互联网有多少人? 当大家的微信好友在4000人以上时,假如你通过本行业的某位朋友引荐,新添加一位微信好友时,你去翻阅这位新好友的朋友圈,你多半会发现有共同好友点赞过Ta。 我们每次做裂变活动,都会遇到一个节点:100万UV,在这个节点,会有两个可能: 一方面是短时间内流量过大,微信会把页面封掉; 另一方面是活动达到100万人访问,基本上该活动就会成为传播圈层的热点话题,形成一个行业新闻。 实操总结:小程序裂变0成本获客3要素 包括像5月中旬潘乱老师发的文章《腾讯没有梦想》,潘乱老师第二天说文章破百万阅读,文章影响力穿透了整个互联网圈,引发了上百家媒体讨论。 但像泛人群的咪蒙、视觉志等大号,百万阅读只是起步价。 实操总结:小程序裂变0成本获客3要素 有一次听梁宁老师说:微信红包最开始也是从互联网从业者开始扩散使用,但很长一段时间卡在400万用户没有大的增长,直到后面和春晚合作,借助春晚的影响力走向亿万家庭,用户迅速破亿,节节走高。 实操总结:小程序裂变0成本获客3要素 这些现象,都是在回答一个有趣的问题:“互联网”有多少人? 为什么“百万人”就能打透一个圈层?尽管比起微信的十亿用户,“一百万”只是水缸里的一勺水。 1.2 “微信互联网”流量的3个特征 我们总结了做裂变活动需要利用到的“微信互联网”3个特征: 特征1.“用户社交关系链垂直密集”——换一个解释就是“圈层经济”。 因为微信的熟人+商务社交属性融合,你会发现你的微信好友中,50%以上的人都是和你工作相关的、都是同一个行业/领域的从业者,所以就出现了:物以类聚人以群分的“圈层”。 所以朋友圈经常会出现和行业相关的文章、活动“刷屏”(因为你的好友密集度够高,十几个人发即可形成“刷屏”错觉)。 特征2.“行业KOL节点效应”。 大家的社交链关系是呈网状的,每个人所代表的的节点的影响力大小是不一样的(简单的理解:你的权威性越高、好友数越多,影响力就越大),影响力大的节点发朋友圈,点击率就越高(就好像你加了大咖好友,他发的链接,你基本上都会点进去学习一下),辐射影响的小节点就越多(好友越多)。 而且加上上面说的:因为“用户社交关系链垂直密集”。影响力大的节点之间交叉的小节点也会很多(比如你朋友圈会加好几个行业的大咖,不会只有1个)。 这样子几个大咖一起发朋友圈,就可以带动一次“刷屏”冷启动。 特征3.“各垂直行业的‘互联网化’进程不一”。 因为一些行业+互联网的时间比较早,互联网的一些营销玩法比较先进,但一些比较落后的行业、刚冒出来的行业,可以直接复制先进行业的营销玩法,降低自己的试错成本。 实操总结:小程序裂变0成本获客3要素 1.3 “3个特征”的裂变应用 总结的这3个特征,小公司/品牌如果直接去用,会因为缺乏品牌效应和种子用户的忠诚度比较难冷启动,所以在应用上我们经常结合社群,来促进这个裂变的冷启动: 像一般电商平台支付完之后、页面会引导你去逛其他商品 像知识付费平台、支付完之后就引导你去听课 但由于我们的目的是把流量裂变出去,所以我们把这个流程改了: 用户支付之后的页面引导用户进群(常用的引导内容:进群领课程资料、进群和老师交流提问、进群和同学交流、进群领红包等等); 用户进群后,通过社群运营,社群的封闭性、结合小号的互动,可以快速拉进用户对平台/公司的距离,增加用户的粘性,对提高老带新率、复购率的提升都是非常明显。 实操总结:小程序裂变0成本获客3要素 同时,一般用户购买“商品”之后主动分享的概率是在5%以下,同时由于流量是不连续的,用户分享也是稀稀疏疏的。 但如果用户支付之后都进群了,建立了初步的粘性之后,可以把分享率从5%提升到60%以上,同时引导用户集中在晚上21:00-22:00(刷朋友圈高峰期)分享(特征1:“用户社交关系链垂直密集”),就可以短时间内在用户所在圈层形成“刷屏”效应,进而提高老带新的效率(从众效应)。 实操总结:小程序裂变0成本获客3要素 “二八法则”同样适用于“裂变传播规律”:我们发现在20%互联网化程度高的行业/人群中:存在KOL节点效应,所以直接应用前2点特征就可以引爆。 但在80%的互联网程度不高的用户中,特别是现在所谓的下沉用户(五六线城市/农村乡镇),他们的朋友圈没有KOL,所以朋友圈的引爆逻辑在此处是失效的,这些人的流量入口是:微信群。 最开始我们在五六线城市人群尝试了几次朋友圈裂变引爆,无功而返。 因为我陷入了一个误区,我自己的微信有几百个群,除了置顶的几个群,我几乎很少会去看其他微信群的信息,所以我觉得微信群太嘈杂了,不能承载“流量入口”的角色。 但五六线城市、乡镇农村的用户,他们的微信好友一般都是保持在一两百人、微信群就几个,可以从白天起床一直聊到晚上睡觉,甚至有一些用户都不知道怎么屏蔽群消息。 当时调研发现这些中老年人的微信会话页只有1屏(我相信很多做运营的同学,置顶的群+个人都超过2屏了),所以微信群是他们对外的高频使用窗口。 这也是为什么拼多多在微信端流量入口比例是:微信群>服务号>朋友圈;今年微信生态的企业基本上都在搭建社群。 实操总结:小程序裂变0成本获客3要素 二、设计小程序的3个心得 除了刚说的可复用的“裂变”方法论,我们之所以能够运气这么好,能在短期内就制造了小程序爆款,接着说一下我们设计小程序的3个小心得: 实操总结:小程序裂变0成本获客3要素 1.历史无新事 我做事情喜欢先去研究前人的经验、总结规律,然后再以此来优化设计自己接下来要做的事情。 喜欢读历史的小伙伴肯定对:“历史无新事”这句话非常有感触。 我研究小程序产品的调研发现,小程序刚火起来的第一波都是工具类小程序:名片、答题、赞赏、便签;接下来是基于场景的小程序:电商、o2o、知识付费。 这跟移动互联网的APP产品形态的演化轨迹非常得相似(就像美团,最开始从团购的场景切入、演化成现在吃喝玩乐的超级APP);再去翻PC互联网的产品发展轨迹,也是非常的一致。 所以说,在“微信互联网”前期,存在非常巨大的红利:只要按照APP应用市场的分类榜单去拆解单一场景需求的APP,把功能拆解成单一形态,然后快速制作成小程序放到微信生态去裂变传播。 ...

August 19, 2019 · 1 min · jiezi

微信小程序开发之页面分享-onShareAppMessage-分享参数用处

今天下午突然听到群里有人说微信小程序工具更新了,文档也更新了不少内容. 顾不上吃冬至的饺子.我就冲进来了. 先说分享功能,目前真机尚不能调试.开发工具上可以看看效果.后续还会更新. Page()中加上如下代码后在右上角就会出现三个小白点 title:分享的标题. desc:分享一段描述. path:这个参数有点意思.以前在微信中的分享一般都是url.这里是当前页面这里应该是pages/index?id=123这里的id目前还不知道是什么. 也就是说以后你可以在微信中像分享一个网页一样分享一个页面了. onShareAppMessage: function () { return { title: '微信小程序联盟', desc: '最具人气的小程序开发联盟!', path: '/page/user?id=123' } }分享参数用处: 我这里没有用到路径后的参数,说个场景:参数是用户昵称,A分享了XXX小程序到微信群里,B点开小程序,弹个toast,”来自A的分享”. ———————————————— 版权声明:本文为CSDN博主「dzp_coder」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_3138...

August 18, 2019 · 1 min · jiezi

uniapp微信小程序接入人脸核身SDK

这几天使用uni-app开发某银行的一个微信小程序,需要集成接入腾讯云的人脸核身SDK,如上图所示,记录下整合接入过程及踩的一些坑,帮助后面需要的朋友们。关于uni-app接入人脸核身SDK有不懂的地方可以在下面提问,看到会及时回复。 申请服务不是所有的企业都能够申请的,需要符合以下行业要求的客户才能申请政务:政府机构或事业单位金融:银行、保险医疗:公立医疗机构运营商:电信运营商教育:公立教育机构交通:航空、客运、网约车、交通卡、共享交通、轨道交通、租车旅游:酒店物流:快递、邮政、物流 由于SDK会调用小程序原生的wx.startFacialRecognitionVerify方法,所以总共得申请2个服务SDK服务:申请人脸核身服务小程序:查看申请流程(需要发送邮件申请,使用该服务的小程序的appid,后面开发也是用的这个)重要的事情说3遍以上这2个服务都需要申请,缺一不可。以上这2个服务都需要申请,缺一不可。以上这2个服务都需要申请,缺一不可。 下载SDK由于不是我申请的,所以怎么下载我也不知道,听群里的人说的是SDK腾讯云下发给客户的。 SDK目录结构 SDK接入参考腾讯云文档的接入方法:https://cloud.tencent.com/document/product/1007/31071文档是针对原生小程序写的,所以页面引入的方法有所不同由于uni-app不支持直接引入小程序的原生页面,所以这里能想到的就是将它当作成一个微信小程序的组件,然后uni-app的页面引入这个组件 解压引入SDK在uni-app项目中新建wxcomponents目录,将SDK解压后放到该目录pages.json中globalStyle中全局引入小程序的组件,注意引用的路径 "usingComponents": { "verify-mpsdk": "/wxcomponents/verify_mpsdk/index/index"} 新建人脸核身页面pages中新建人脸核身的页面face(名字可以随意,根据自己的需要起名),pages.json中配置页面face页面中引入verify-mpsdk组件最终的人脸核身的页面访问就是/pages/face/face 初始化SDK在需要的页面初始化SDK,如有个页面需要点击按钮进行人脸核身,就在这个页面进行初始化。这个直接照着文档快速入门中的来就行了,这里就直接使用uni-app默认的index页面,适当修改下即可,大概代码如下: <template> <view class="content"> <button type="primary" @tap="gotoVerify"> 进入人脸核身 </button> </view></template><script> export default { data() { return { BizToken: '' } }, onLoad() { // 初始化慧眼实名核身组件 const Verify = require('@/wxcomponents/verify_mpsdk/main.js') Verify.init() }, methods: { // 单击进入人脸核身按钮时,触发该函数 gotoVerify () { this.BizToken = '' // 这里需要我们去客户后端调用DetectAuth接口获取BizToken // 调用实名核身功能 wx.startVerify({ data: { token: this.BizToken // BizToken }, success: (res) => { // 验证成功后触发 // res 包含验证成功的token, 这里需要加500ms延时,防止iOS下不执行后面的逻辑 setTimeout(() => { // 验证成功后,拿到token后的逻辑处理,具体以客户自身逻辑为准 console.log(res) }, 500) }, fail: (err) => { // 验证失败时触发 // err 包含错误码,错误信息,弹窗提示错误 setTimeout(() => { console.log(err) wx.showModal({ title: "提示", content: err.ErrorMsg, showCancel: false }) }, 500) } }) } } }</script>注意下这里的BizToken,需要调用后端服务接口来获取,需要后端的同学调用腾讯云提供的DetectAuth来返回前端需要的BizToken,调试开发阶段我们可以先通过腾讯云提供的工具API 3.0 Explorer直接来获取这个BizToken如果服务申请成功后控制台一般能找到SecretId,SecretKey,RuleId注意Endpoint和Region选择的地区得保持和申请时选择的地区一致。填写完成后点击在线调用中的发送请求按钮,如果填的都对的话返回信息里面会有BizToken拿到BizToken后就可以直接使用了,修改下上面的代码:xxxxxxxxxxxxxxxxx就是拿到的BizToken ...

August 17, 2019 · 1 min · jiezi

小程序录音播放以及语音识别功能

新闻地址:https://mp.weixin.qq.com/s/Lz... 腾讯已经开源了 同声传译 的小程序插件,以及满足我的诉求。 github地址:https://github.com/Tencent/Fa...

August 8, 2019 · 1 min · jiezi

CSS-常用布局在小程序中的应用

CSS 常用布局在小程序中的应用所有css布局的根本都是3个基本概念:定位、浮动、外边距操纵我们其他的布局实现方式,都是基于正常的文档流来进行的。所以我们先来看看什么是正常的文档流。 正常文档流(Normal Flow):正常布局流是指在不对页面进行任何布局控制时,浏览器默认的HTML布局方式。默认的文档流,确保在没有任何css样式的时候,还能够正确的渲染和显示内容。使页面具有比较好的可读性以及合理性。(position display float table flex-box grid-layout)默认情况下,元素是如何布局的? (引用自 https://developer.mozilla.org)首先,取得元素的内容来放在一个独立的元素盒子中,然后在其周边加上内边距、边框和外边距。(盒子模型)一个块级元素的内容宽度默认是其父元素的100%,其高度与其内容高度一致。行内元素的height width与内容一致。你无法设置行内元素的height width。 如果你想控制行内元素的尺寸,你需要为元素设置display: block; (或者,display: inline-block; inline-block 混合了inline 和 block的特性。)那独立元素之间又是如何相互影响的呢? 正常布局流是一套在浏览器视口内放置、组织元素的系统。默认情况下,块级元素按照在文档中书写出现的顺序放置 --- 每个块级元素会在上一个元素下面另起一行,它们会被设置好的margin 分隔。行内元素的表现有所不同 --- 它们不会另起一行;只要在其父级块级元素的宽度内有足够的空间,它们与其他行内元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行。如果两个相邻的元素都设置了margin 并且两个margin有重叠,那么更大的设置会被保留,小的则会消失 --- 这被称为外边距叠加。我们在传统的css布局当中,不管是css2还是css3,大致囊括了静态布局、流式布局、弹性布局、自适应布局、响应式布局、网格布局。对于css的这些布局方式,在小程序中又是怎样的呈现方式呢?我们分别来看一看。 1. 静态布局 (Static Layout)固定宽度布局。宽度以像素为单位。(当然我们还可以使用其他的绝对长度单位)缺点:无论窗口多大,尺寸不变。无法充分利用空间。行长和文本易读性不好。静态布局就是传统的网站形式:对于PC设计一个居中布局,窗口缩小时,内容被遮挡,呈现横竖向滚动条。对于移动设备,单独建立一个m.域名及相应的移动网站。静态布局在小程序中一般很少出现。因为如果使用静态布局,就无法做到不同屏幕自适应,750px的设计稿在小屏幕的手机上就会出现滚动条。 呈现效果如下: // wxml 代码<view class='page'> <view class='header'>静态布局</view> <view class='content'> <text>静态布局内容部分在小程序中的呈现。小程序page样式在overflow-x上默认是hidden。</text> </view></view>//样式如下page { overflow-x:scroll;}.page, .header, .content { width: 750px;}.content { background: #ccc;}2. 流式布局 (Liquid Layout)(百分比布局)流式布局是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。使用百分比实现:流式布局能够相对于浏览器窗口进行伸缩。缺点:窗口宽度较小,行变得非常窄,很难阅读。需要设置min-width来解决,但是如果min-width较大的话,也会有静态布局相同的限制。宽度太宽,同样会存在行长过长的问题。流式布局(Liquid)的特点(也叫"Fluid") 是页面元素的宽度按照屏幕进行适配调整,主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。我们来看看在小程序中使用流式布局的效果: 在不同的屏幕大小下呈现出来的效果如下: <!-- wxml代码 --><view class='page fluid'> <view class='header fluid__header'>流式布局</view> <view class='content'> <!-- 两列 --> <view class='wrapper'> <view class='grid-item grid-half'> <text>我是左侧部分</text> </view> <view class='grid-item grid-half'> <text>我是右侧部分</text> </view> </view> <!-- 三列 --> <view class='wrapper'> <view class='grid-item grid-three'> <text>我是左侧部分</text> </view> <view class='grid-item grid-three'> <text>我是中间部分</text> </view> <view class='grid-item grid-three'> <text>我是右侧部分</text> </view> </view> </view></view>/* css代码 */.fluid, .content, .wrapper { width: 100%; box-sizing: border-box;}.wrapper { height: 200px; margin-bottom: 20px;}.wrapper .grid-item { height: 100%; background: #ccc; display: inline-block; box-sizing: border-box;}.wrapper .grid-half { width: 48%;}.wrapper .grid-half:nth-child(2n) { margin-left: 4%;}.wrapper .grid-three { width: 32%;}.wrapper .grid-three:not(:first-child) { margin-left: 2%;}3. 弹性布局 (Flex Layout)CSS 弹性盒子布局是 CSS 的模块之一,定义了一种针对用户界面设计而优化的 CSS 盒子模型。在弹性布局模型中,弹性容器的子元素可以在任何方向上排布,也可以“弹性伸缩”其尺寸,既可以增加尺寸以填满未使用的空间,也可以收缩尺寸以避免父元素溢出。子元素的水平对齐和垂直对齐都能很方便的进行操控。通过嵌套这些框(水平框在垂直框内,或垂直框在水平框内)可以在两个维度上构建布局。对Flex的理解可以参考阮一峰 Flex 布局教程:语法篇。在此不做详细说明。那我们看看在小程序中Flex布局的使用。依然还是上一个例子中的wxml,我们只需要修改对应的class以及css即可。 ...

August 7, 2019 · 2 min · jiezi

小程序获取用户openid

调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。

July 26, 2019 · 1 min · jiezi

微信小程序数据字段大小写导致的坑

这两天在开发微信小程序登录以及加解密的时候,因为数据大小写的问题被坑了一把。 场景小程序调用wx.login时会获得code,传输给服务端可以得到openid,unionid(绑定了开放平台),session_key小程序调用getUserInfo会获得encrypted_data,iv,解密后得到unionId,openIdunionid和openid这两个场景键名大小写是不同的例子服务端根据code获取session_key返回结果如下: { "session_key": "我是session_key", "openid": "我是openid", "unionid": "我是unionid"}服务端根据session_key解密encrypted_data和iv返回结果如下: { "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP }}可以看到两次同样的字段openid和unionid大小写是不同的,此处容易踩坑。 结论服务端根据code换session_key/openid/unionid是小写服务端根据encrypted_data和iv解密得到的openId/unionId是大写最后,祝大家在开发过程中少踩坑。 更多精彩尽在我的博客一键直达

July 16, 2019 · 1 min · jiezi

微信小程序支付功能全流程实践

前言微信小程序为电商类小程序,提供了非常完善、优秀、安全的支付功能。在小程序内可调用微信的API完成支付功能,方便、快捷。小程序开发者在开发小程序时,支付流程是必然要接触到,今天胡哥就小程序支付的全流程为大家一一细说,让小伙伴能快速得掌握小程序支付能力,避免踩坑! 知己知彼,方能百战不殆 - 小程序支付流程图 举个栗子????:某用户小明在某电商小程序上购买一块肥皂,从浏览、下单到支付经历了什么样的过程呢? 打开电商小程序,搜索浏览到某雕肥皂,点击查看详情后,发现大小、丝滑程度都很合适,点击直接下单wx.login获取用户临时登录凭证code,发送到后端服务器换取openId在下单时,小程序需要将小明购买的商品Id,商品数量,以及小明这个用户的openId传送到服务器服务器在接收到商品Id、商品数量、openId后,生成服务期订单数据,同时经过一定的签名算法,向微信支付发送请求,获取预付单信息(prepay_id),同时将获取的数据再次进行相应规则的签名,向小程序端响应必要的信息(必须字段信息将在下文进行详细说明)小程序端在获取对应的参数后,调用wx.requestPayment()发起微信支付,唤醒支付工作台,进行支付小结进行微信支付,在小程序端我们主要做三件事: 注:服务端调用统一下单API、签名算法不再本次分享讨论范围内,请期待胡哥的另外一次分享。使用wx.login获取临时登录凭证code,发送到后端获取openId wx.login({ success (res) { if (res.code) { // 发起请求,换取openId wx.request({ url: '', data: { code: res.code } }) } }})将openId以及相应需要的商品信息发送到后端,换取服务端进行的签名等信息 wx.request({ url: '', data: { openId: '', num: 1, id: '111' }})接收返回的信息(必须要包含发起微信支付wx.requestPayment的参数),发起微信支付 wx.requestPayment({ // 时间戳 timeStamp: '', // 随机字符串 nonceStr: '', // 统一下单接口返回的 prepay_id 参数值 package: '', // 签名类型 signType: '', // 签名 paySign: '', // 调用成功回调 success () {}, // 失败回调 fail () {}, // 接口调用结束回调 complete () {}})注意:以上信息中timeStamp、nonceStr 、prepay_id、signType、paySign各参数均建议必须都由服务端返回(这样会尽最大可能性保证签名数据一致性),小程序端不做任何处理基于Taro的微信支付实例import Taro, { Component } from '@tarojs/taro'import { View, Text, Button } from '@tarojs/components'import './index.scss'export default class Index extends Component { config = { navigationBarTitleText: '首页' } componentWillMount () { } async componentDidMount () { } componentWillUnmount () { } componentDidShow () { } componentDidHide () { } /** * sendOrderInfo() * @description 提交订单信息,获取支付凭证,唤起支付 */ async sendOrderInfo () { // 获取临时登录凭证code let codeData = await Taro.login() // 换取openId let openId = '' if (codeData.code) { let res = await Taro.request({ // 定义的后端换取openId的接口 url: 'https://www.justbecoder.com/getLogin', data: { code: codeData.code } }) if (res && res.code === 0) { openId = res.openId } } // 发送openId以及对应的商品信息 let data = await Taro.requrest({ url: 'https://www.justbecoder.com/createdOrder', data: { openId, // 实际情况的商品数量 num: 1, // 实际情况的商品Id id: 111, } }) // code === 0 表示提交订单成功,返回需要的签名信息等 if (data && data.code === 0) { let { timeStamp, nonceStr, prepay_id, signType, paySign } = data.payInfo // 唤起支付,按小程序要求格式发送参数 let payData = await Taro.requestPayment({ timeStamp, nonceStr, package: 'prepay_id=' + prepay_id, signType, paySign }) if (payData && payData.errMsg === 'requestPayment:ok') { Taro.showModal({ title: '操作提示', content: '支付成功', showCancel: false, confirmText: '确定' }) } else { Taro.showModal({ title: '操作提示', content: '支付失败,请重新尝试', showCancel: false, confirmText: '确定' }) } } } render () { return ( <View className='index'> <Button onClick={this.sendOrderInfo}>立即下单</Button> </View> ) }}效果图 ...

July 16, 2019 · 2 min · jiezi

基于Taro的微信小程序分享图片功能实践

前言在各种小程序(微信、百度、支付宝)、H5、NativeApp 纷纷扰扰的当下,给大家强烈安利一款基于React的多终端开发利器:京东Taro(泰罗·奥特曼),Taro致力于多终端统一解决方案,一处代码,多处运行。 Taro支持以React语言开发小程序,支持CSS预处理器,支持实时编译更新,支持NPM,等等等等,简直不要太爽!微信小程序分享图片功能是经常在小程序业务中出现的,比如学习打卡分享,推广会员分享,推广商品分享等等。因为小程序是不支持直接分享图片到朋友圈的,一般操作为: 生成包含小程序码(当前也可以是其他特定的信息)的图片;用户点击保存图片,下载到本地,再发布到朋友圈;其他用户长按识别该小程序码,进入当前小程序。今天胡哥给大家分享下,基于Taro框架实现微信小程序分享图片功能的实践。 一、搭建Taro项目框架,创建微信小程序1. 安装taro脚手架工具npm install -g @tarojs/cli2. 初始化taro项目taro init taro-img-share3. 编译项目,开启Dev模式,生成小程序 -- dist目录npm run dev:weapp4. 微信开发者工具,创建小程序,选择项目根目录为taro-img-share下的dist目录二、小程序分享图片功能实践 --- 打卡图片分享功能先上图,再说话 这是重点:使用Canvas绘制图片并展示,保存图片到相册drawImage()方法负责绘制展示,saveCard()方法负责下载图片到相册src/pages/index/index.js import Taro, { Component } from '@tarojs/taro'// 引入对应的组件import { View, Text, Button, Canvas } from '@tarojs/components'import './index.scss'export default class Index extends Component { config = { navigationBarTitleText: '首页' } /** * 初始化信息 */ constructor () { this.state = { // 用户信息 userInfo: {}, // 是否展示canvas isShowCanvas: false } } /** * getUserInfo() 获取用户信息 */ getUserInfo (e) { if (!e.detail.userInfo) { Taro.showToast({ title: '获取用户信息失败,请授权', icon: 'none' }) return } this.setState({ isShowCanvas: true, userInfo: e.detail.userInfo }, () => { // 调用绘制图片方法 this.drawImage() }) } /** * drawImage() 定义绘制图片的方法 */ async drawImage () { // 创建canvas对象 let ctx = Taro.createCanvasContext('cardCanvas') // 填充背景色 let grd = ctx.createLinearGradient(0, 0, 1, 500) grd.addColorStop(0, '#1452d0') grd.addColorStop(0.5, '#FFF') ctx.setFillStyle(grd) ctx.fillRect(0, 0, 400, 500) // // 绘制圆形用户头像 let { userInfo } = this.state let res = await Taro.downloadFile({ url: userInfo.avatarUrl }) ctx.save() ctx.beginPath() // ctx.arc(160, 86, 66, 0, Math.PI * 2, false) ctx.arc(160, 88, 66, 0, Math.PI * 2) ctx.closePath() ctx.clip() ctx.stroke() ctx.translate(160, 88) ctx.drawImage(res.tempFilePath, -66, -66, 132, 132) ctx.restore() // 绘制文字 ctx.save() ctx.setFontSize(20) ctx.setFillStyle('#FFF') ctx.fillText(userInfo.nickName, 100, 200) ctx.setFontSize(16) ctx.setFillStyle('black') ctx.fillText('已在胡哥有话说公众号打卡20天', 50, 240) ctx.restore() // 绘制二维码 let qrcode = await Taro.downloadFile({ url: 'https://upload-images.jianshu.io/upload_images/3091895-f0b4b900390aec73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/258/format/webp.jpg' }) ctx.drawImage(qrcode.tempFilePath, 70, 260, 180, 180) // 将以上绘画操作进行渲染 ctx.draw() } /** * saveCard() 保存图片到本地 */ async saveCard () { // 将Canvas图片内容导出指定大小的图片 let res = await Taro.canvasToTempFilePath({ x: 0, y: 0, width: 400, height: 500, destWidth: 360, destHeight: 450, canvasId: 'cardCanvas', fileType: 'png' }) let saveRes = await Taro.saveImageToPhotosAlbum({ filePath: res.tempFilePath }) if (saveRes.errMsg === 'saveImageToPhotosAlbum:ok') { Taro.showModal({ title: '图片保存成功', content: '图片成功保存到相册了,快去发朋友圈吧~', showCancel: false, confirmText: '确认' }) } else { Taro.showModal({ title: '图片保存失败', content: '请重新尝试!', showCancel: false, confirmText: '确认' }) } } render () { let { isShowCanvas } = this.state return ( <View className='index'> <Button onGetUserInfo={this.getUserInfo} openType="getUserInfo" type="primary" size="mini">打卡</Button> {/* 使用Canvas绘制分享图片 */} { isShowCanvas && <View className="canvas-wrap"> <Canvas id="card-canvas" className="card-canvas" style="width: 320px; height: 450px" canvasId="cardCanvas" > </Canvas> <Button onClick={this.saveCard} className="btn-save" type="primary" size="mini">保存到相册</Button> </View> } </View> ) }}src/pages/index/index.sass ...

July 15, 2019 · 2 min · jiezi

CSS-常用布局在小程序中的应用

CSS 常用布局在小程序中的应用所有css布局的根本都是3个基本概念:定位、浮动、外边距操纵我们其他的布局实现方式,都是基于正常的文档流来进行的。所以我们先来看看什么是正常的文档流。 正常文档流(Normal Flow):正常布局流是指在不对页面进行任何布局控制时,浏览器默认的HTML布局方式。默认的文档流,确保在没有任何css样式的时候,还能够正确的渲染和显示内容。使页面具有比较好的可读性以及合理性。(position display float table flex-box grid-layout)默认情况下,元素是如何布局的? (引用自 https://developer.mozilla.org)首先,取得元素的内容来放在一个独立的元素盒子中,然后在其周边加上内边距、边框和外边距。(盒子模型)一个块级元素的内容宽度默认是其父元素的100%,其高度与其内容高度一致。行内元素的height width与内容一致。你无法设置行内元素的height width。 如果你想控制行内元素的尺寸,你需要为元素设置display: block; (或者,display: inline-block; inline-block 混合了inline 和 block的特性。)那独立元素之间又是如何相互影响的呢? 正常布局流是一套在浏览器视口内放置、组织元素的系统。默认情况下,块级元素按照在文档中书写出现的顺序放置 --- 每个块级元素会在上一个元素下面另起一行,它们会被设置好的margin 分隔。行内元素的表现有所不同 --- 它们不会另起一行;只要在其父级块级元素的宽度内有足够的空间,它们与其他行内元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行。如果两个相邻的元素都设置了margin 并且两个margin有重叠,那么更大的设置会被保留,小的则会消失 --- 这被称为外边距叠加。我们在传统的css布局当中,不管是css2还是css3,大致囊括了静态布局、流式布局、弹性布局、自适应布局、响应式布局、网格布局。对于css的这些布局方式,在小程序中又是怎样的呈现方式呢?我们分别来看一看。 1. 静态布局 (Static Layout)固定宽度布局。宽度以像素为单位。(当然我们还可以使用其他的绝对长度单位)缺点:无论窗口多大,尺寸不变。无法充分利用空间。行长和文本易读性不好。静态布局就是传统的网站形式:对于PC设计一个居中布局,窗口缩小时,内容被遮挡,呈现横竖向滚动条。对于移动设备,单独建立一个m.域名及相应的移动网站。静态布局在小程序中一般很少出现。因为如果使用静态布局,就无法做到不同屏幕自适应,750px的设计稿在小屏幕的手机上就会出现滚动条。 呈现效果如下: // wxml 代码<view class='page'> <view class='header'>静态布局</view> <view class='content'> <text>静态布局内容部分在小程序中的呈现。小程序page样式在overflow-x上默认是hidden。</text> </view></view>//样式如下page { overflow-x:scroll;}.page, .header, .content { width: 750px;}.content { background: #ccc;}2. 流式布局 (Liquid Layout)(百分比布局)流式布局是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。使用百分比实现:流式布局能够相对于浏览器窗口进行伸缩。缺点:窗口宽度较小,行变得非常窄,很难阅读。需要设置min-width来解决,但是如果min-width较大的话,也会有静态布局相同的限制。宽度太宽,同样会存在行长过长的问题。流式布局(Liquid)的特点(也叫"Fluid") 是页面元素的宽度按照屏幕进行适配调整,主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。我们来看看在小程序中使用流式布局的效果: 在不同的屏幕大小下呈现出来的效果如下: <!-- wxml代码 --><view class='page fluid'> <view class='header fluid__header'>流式布局</view> <view class='content'> <!-- 两列 --> <view class='wrapper'> <view class='grid-item grid-half'> <text>我是左侧部分</text> </view> <view class='grid-item grid-half'> <text>我是右侧部分</text> </view> </view> <!-- 三列 --> <view class='wrapper'> <view class='grid-item grid-three'> <text>我是左侧部分</text> </view> <view class='grid-item grid-three'> <text>我是中间部分</text> </view> <view class='grid-item grid-three'> <text>我是右侧部分</text> </view> </view> </view></view>/* css代码 */.fluid, .content, .wrapper { width: 100%; box-sizing: border-box;}.wrapper { height: 200px; margin-bottom: 20px;}.wrapper .grid-item { height: 100%; background: #ccc; display: inline-block; box-sizing: border-box;}.wrapper .grid-half { width: 48%;}.wrapper .grid-half:nth-child(2n) { margin-left: 4%;}.wrapper .grid-three { width: 32%;}.wrapper .grid-three:not(:first-child) { margin-left: 2%;}3. 弹性布局 (Flex Layout)CSS 弹性盒子布局是 CSS 的模块之一,定义了一种针对用户界面设计而优化的 CSS 盒子模型。在弹性布局模型中,弹性容器的子元素可以在任何方向上排布,也可以“弹性伸缩”其尺寸,既可以增加尺寸以填满未使用的空间,也可以收缩尺寸以避免父元素溢出。子元素的水平对齐和垂直对齐都能很方便的进行操控。通过嵌套这些框(水平框在垂直框内,或垂直框在水平框内)可以在两个维度上构建布局。对Flex的理解可以参考阮一峰 Flex 布局教程:语法篇。在此不做详细说明。那我们看看在小程序中Flex布局的使用。依然还是上一个例子中的wxml,我们只需要修改对应的class以及css即可。 ...

July 14, 2019 · 2 min · jiezi

uniapp-H5版本IOS图片长按识别

问题描述:uni-app开发H5碰到ios系统下,图片长按没有识别二维码(小程序码)的选项。问题解决:uni-app的配置文件中配置H5相关配置,设置路由模式为hash即可解决问题

July 14, 2019 · 1 min · jiezi

uniapp-组件传值踩坑记录

小程序端子组件的created事件和父组件的onload同时执行; 在小程序端,用watch监听传进来的值,等有值了再进行下一步操作;H5端先执行父组件的onload,再执行子组件的created;H5端可以在created中进行下一步操作,因为此时已经有prop传进来了

July 14, 2019 · 1 min · jiezi

小程序开发条件渲染了解一下

这个真是太棒了,比自己写样式控制要优雅100倍! https://developers.weixin.qq.... 条件渲染wx:if在框架中,使用 wx:if="" 来判断是否需要渲染该代码块: <view wx:if="{{condition}}"> True </view>也可以用 wx:elif 和 wx:else 来添加一个 else 块: <view wx:if="{{length > 5}}"> 1 </view><view wx:elif="{{length > 2}}"> 2 </view><view wx:else> 3 </view>block wx:if因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。 <block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view></block>注意: <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

July 13, 2019 · 1 min · jiezi

程序使用canvas二维码保存至手机相册

小程序使用canvas二维码保存至手机相册在使用canvas绘制海报的过程中不建议使用原生来进行画图,因为默认是不支持rpx像素的,px不会做到自适应。 推荐使用插件 Paintergithub地址 https://github.com/Kujiale-Mo... 配置很简单,也容易上手,无论是画矩形,还是将图片合成canvas;还是自己定义文字;都是很方便的。 附上一个简单的例子吧 <painter :customStyle="customStyle" :palette="imgDraw" />// const _this=this; wx.getSystemInfo({ success (res) { _this.drawCanvas(res.windowHeight); } }) drawCanvas(height) {//这里的canvas的高是动态获取设备的高度,做到自适应 const that = this; let heightVal=height*2+'rpx'; this.imgDraw = { width: '750rpx', height: heightVal, background: '#fff', views: [ { type: "rect", css: { top: '20rpx', left: '130rpx', color: '#1A1A1A', width: '660rpx', height: '220rpx', borderRadius: '32rpx' } }, { type: 'image', url: './a.jpg', css: { top: '36rpx', left: '16rpx', width: '188rpx', height: '188rpx' } }, { type: 'text', text: '', css: { top: '54rpx', left: '260rpx', fontSize: '48rpx', color: "#fff" } }, { type: 'text', text: '文字部分', css: { top: '134rpx', left: '260rpx', fontSize: '30rpx', color: "#d1d1d1" } }, { type: 'text', text: '1333333333', css: { top: '196rpx', left: '260rpx', fontSize: '26rpx', color: "#d1d1d1" } }, { type: 'text', text: '李四', css: { top: '304rpx', left: '302rpx', fontSize: '24rpx', color: "#767676" } }, { type: 'image', url: '/icon-localtion.png', css: { top: '275rpx', left: '260rpx', width: '26rpx', height: '168rpx' } }, { type: 'image', url: '二维码.png', css: { top: '646rpx', left: '236rpx', width: '278rpx', height: '278rpx' } } ] } let { path: __path } = mpvue.getStorageSync('createImagePath') mpvue.saveImageToPhotosAlbum({ filePath: __path, success(res) { // mpvue.showToast({ // title: '保存成功', // icon: 'success', // duration: 800, // mask: true // }); }, fail(res) { // mpvue.showToast({ // title: '保存失败', // icon: 'fail', // duration: 800, // mask: true // }); } }); }, 这里涉及到画二维码, 如果你的二维码图片不是一个线上的链接的话,这时需要做一些小操作。我的项目中二维码的图片传过来是一个流,所以用img的src默认发送get请求,就能拿到这个图片了。 所以url会直接发送get请求拿到图片。 ...

July 12, 2019 · 2 min · jiezi

小程序生成海报代码解析

最近趁垃圾分类这个热点,做了一个小程序,实现的功能有 根据关键词查询垃圾类别用户提交垃圾分类信息垃圾分类答题活动答题分数海报生成里面有比较重要的模块是答题活动,题目答完之后,会生成分数海报,本次我单独把这个功能拎出来讲下 请扫描体验 这里涉及微信小程序的几个知识点如下 获取用户个人信息授权保存图片到本地授权canvas文件操作以及下面几个API wx.getImageInfowx.downloadFilewx.saveFilewx.createCanvasContextwx.canvasToTempFilePathwx.getSettingwx.saveImageToPhotosAlbumwx.authorizewx.saveImageToPhotosAlbum获取背景图片 promiseBdImg: function(){ const _this = this const bdImagePath = '../../static/images/common/' return new Promise(function (resolve, reject) { wx.getImageInfo({ src: bdImagePath + "base.png", success: function (res) { console.log('promiseBdImg', res) resolve(res); }, fail: function(err){ console.log('2019062007'); console.log(err); } }) }); },将背景图片提前绘制到canvas上,由于绘制海报需要三个图片资源:背景图片、头像、小程序二维码以及文字,能不在一起的尽量提前处理 特别是头像是网络资源,能早点拿到头像信息存储起来最好的 onReady: function () { const _this = this //默认进入页面就生成背景图 var windowWidth = this.data.windowWidth; var posterHeight = this.data.posterHeight; this.promiseBdImg().then(res => { console.log('Promise.all', res) const ctx = wx.createCanvasContext('shareImg') ctx.width = windowWidth ctx.height = posterHeight console.log(windowWidth, posterHeight) //主要就是计算好各个图文的位置 ctx.drawImage('../../' + res.path, 0, 0, windowWidth, posterHeight, 0, 0) ctx.save() // 对当前区域保存 ctx.draw() }).then( () => { }) },生成海报图片,这是该模块的核心代码,主要是将图片资源绘制到canvas上面,具体坐标定位这个细节还有待完善 ...

July 11, 2019 · 2 min · jiezi

打怪升级小程序评论回复和发贴功能实战一

在学习成长的过程中,常常会遇到一些自己从未接触的事物,这就好比是打怪升级,每次打倒一只怪,都会获得经验,让自己进步强大。特别是我们这些做技术的,逆水行舟不进则退。下面分享下小程序开发中的打怪升级经历~ 先来看下实际效果图,小程序开发中有时会要做一些的功能复杂的组件,比如评论回复和发帖功能等,这次主要讲的是关于评论模块的一些思路和实战中的经验,希望能抛砖引玉,给大家一些启发,一同成长~ >>(最下面有实战demo的地址,可以直接浏览器打开添加至IDE工具中) << 根据这个demo.gif,本人做了一个简单的流程图,帮助大家理解。下面罗列一些开发中需要“打的怪”:1、组件目录结构├─components ---小程序自定义组件│ ├─plugins --- (重点)可独立运行的大型模块,可以打包成plugins│ │ ├─comment ---评论模块│ │ │ │ index.js│ │ │ │ index.json│ │ │ │ index.wxml│ │ │ │ index.wxss│ │ │ │ services.js ---(重点)用来处理和清洗数据的service.js,配套模板和插件 │ └─submit ---评论模块子模块:提交评论 index.js index.json index.wxml index.wxss为什么要单独做个评论页面页面(submit)?因为如果是当前页面最下面input输入的形式,会出现一些兼容问题,比如: 不同手机的虚拟键盘高度不同,不好绝对定位和完全适配弹窗输入框过小输入不方便,如果是大的textare时,容易误触下面评论的交。注:目录结构,仅供参考。 2、NODE端API接口返回结构和页面结构//node:API接口返回{ "data": { "commentTotal": 40, "comments": [ { "contentText": "喜欢就关注我", //评论内容 "createTime": 1560158823647, //评论时间 "displayName": "智酷方程式", //用户名 "headPortrait": "https://blz.nosdn.127.net/1/weixin/zxts.jpg", //用户头像 "id": "46e0fb0066666666", //评论ID 用于回复和举报 "likeTotal": 2, //点赞数 "replyContents": [ //回复评论 { "contentText": "@智酷方程式 喜欢就回复我", //回复评论内容 "createTime": 1560158986524, //回复时间 "displayName": "神秘的前端开发", //回复的用户名 "headPortrait": "https://blz.nosdn.127.net/1/2018cosplay/fourth/tesss.jpg", //回复的用户头像 "id": "46e0fb00111111111", //回复评论的ID "likeTotal": 2, //回复评论的点赞数 "replyContents": [], //回复的回复 盖楼 "replyId": "46e0fb001ec222222222", //回复评论的独立ID,用于统计 }, { "contentText": "@智酷方程式: 威武,学习学习", "createTime": 1560407232814, "displayName": "神秘的前端开发", "headPortrait": "https://blz.nosdn.127.net/1/2018cosplay/fourth/tesss.jpg", "id": "46e0fb00111111111", "likeTotal": 0, "replyContents": [], "replyId": "46e0fb001ec222222222", } ], "replyId": "", "topicId": "46e0fb001ec3333333", } ], "curPage": 1, //当前页面 //通过ID 判断 当前用户点赞了 哪些评论 "likes": [ "46e0fb00111111111", "46e0fb001ec222222222", "46e0fb0066666666", ], "nextPage": null, //下一页 "pageSize": 20, //一页总共多少评论 "total": 7, //总共多少页面 }, "msg": "success", "status": "success"}<!-- HTML 部分 --><block wx:if="{{commentList.length>0}}"> <!-- 评论模块 --> <block wx:for="{{commentList}}" wx:for-item="item" wx:for-index="index" wx:key="idx"> <view class="commentItem" catchtap="_goToReply" data-contentid="{{item.id}}" data-replyid="{{item.id}}" data-battle-tag="{{item.displayName}}"> <view class="titleWrap"> <image class="logo" src="{{item.headPortrait||'默认图'}}"></image> <view class="authorWrap"> <view class="author">{{item.displayName}}</view> <view class="time">{{item.createTime}}</view> </view> <view class="starWrap" catchtap="_clickLike" data-index="{{index}}" data-like="{{item.like}}" data-contentid="{{item.id}}" data-topicid="{{item.topicId}}"> <text class="count">{{item.likeTotal||""}}</text> <view class="workSprite icon {{item.like?'starIconHasClick':'starIcon'}}"></view> </view> </view> <view class="text"> {{item.contentText}} </view> </view> <!-- 评论的评论 --> <block wx:for="{{item.replyContents}}" wx:for-item="itemReply" wx:for-index="indexReply" wx:key="idxReply"> <view class="commentItem commentItemReply" catchtap="_goToReply" data-contentid="{{itemReply.id}}" data-replyid="{{item.id}}" data-battle-tag="{{itemReply.displayName}}"> ... 和上面类似 </view> </block> </block> <!-- 加载更多loading --> <block wx:if="{{isOver}}"> <view class="more">评论加载完成</view> </block></block>通过node提供一个API接口,通过用户的openId来判断是否点赞,这里提供一个参考的JSON结构。JSON尽量做成array循环的结构方便渲染,根据ID来BAN人和管理。底部加上加载更多的效果,同时,记得做一些兼容,比如默认头像等。 ...

July 11, 2019 · 3 min · jiezi

上线一个月做-QQ-小程序的情况如何

QQ 小程序平台的出现是必然。 2017 年微信推出并定义小程序,一年后支付宝、淘宝、百度、今日头条、十大手机厂商上线了各自的小程序平台,紧随其后的还有、抖音、快手、虎牙、Bilibili、360。短短两年,小程序平台已然成为了各大国民应用标配,甚至是巨头们渠道与投资布局的重点。如今各家纷纷入场,要用小程序打造多元化生态,曾经的社交之王 QQ 此时起步已经算晚,要满足更多年轻用户需求,只能加快小程序发展,进而更加扩大平台的服务边界和商业价值。 微信的成功,让各大应用学会了如何去做小程序;同样因为微信小程序的成功,让我们在谈到 QQ 小程序,或是其他任何小程序平台时,总是无法绕过一个问题:与微信小程序有什么不一样? QQ 小程序现状5 月 31 日,QQ 小程序正式上线,我们曾围绕这个问题进行过一个大致梳理。除开界面及部分功能的不同,二者差异主要体现在以下几个方面: 微信讲究「去中心化」,QQ 内设置了特定页面进行小程序推荐,更为「中心化」;微信小程序无法直接分享到朋友圈,QQ 小程序支持一键分享到 QQ 空间;微信更推崇工具、服务型小程序及休闲益智类小游戏,QQ 倾向于及更为费时的角色扮演类小游戏;QQ 小程序用户更年轻。时隔一个月,我们再次提起了这个话题,并邀请到了「墨迹天气」、「青团社兼职」、「小鸡词典」三个小程序的负责人一起讨论。这三款小程序,分别代表了在各自领域最头部的公司(「墨迹天气」和「青团社兼职」),以及最具创新性的团队(「小鸡词典」)。 从此次谈话(????采访实录)中我们可以得出简单的结论: 中心化的小程序推荐位和首页下拉为主要流量入口;微信小程序迁移到 QQ 上非常快捷;目前的 QQ 小程序广告能力还未全面开放,想以此获得收益时候尚早。三款小程序在 QQ 上的表现让我们更加确认,「年轻化」才是做一款 QQ 小程序的必备要素。微信想用小程序去「连接一切」,用「去中心化」的方式扩展自身成为一个强大的工具,不同的人可以在其中各取所需。但年轻人更强调「归属感」,他们并不需要那么多商业服务、内容资讯工具,他们更乐于接受推荐,也更偏爱娱乐化的产品,以此来获得社交的乐趣。 现在的 QQ 小程序新建,正是流量红利期,再加上切合的用户群体,尝到甜头的「先行者」们对 QQ 小程序平台未来发展保持着乐观。 知晓云支持 QQ 小程序知晓云已全面开放对 QQ 小程序的支持。即日起正式对外招募 50 名公测用户。公测期间你将有机会与知晓云的核心工程师直接交流,并获得 ¥200 元小程序开发补助。 我们希望你是这样的: 已经获得 QQ 小程序内测邀请码。本人或团队有小程序开发经验。了解 QQ 生态,对 QQ 小程序有自己的理解。有上线的小程序开发案例者优先。期待你的参与,赶快????提交申请????吧~ 同时,基于知晓云开发的小程序「糖纸 | 好产品就是一颗糖」也已经正式上线啦~大家可以用 QQ 扫描下方????二维码体验,或者在 QQ 中搜索「糖纸」小程序体验。 PS:如果大家感兴趣,请在文末留言,我们将邀请糖纸开发者分享从微信迁移到 QQ 小程序的宝贵经验。 ...

July 11, 2019 · 1 min · jiezi

做了一个垃圾分类小程序几个知识点介绍下代码可以分享

上海7月1号就开始执行垃圾分类了,在6月底注册了个小程序,小编我快马加鞭赶了一版,具体实现以下功能 1、垃圾分类查询2、垃圾分类介绍3、垃圾分类答题活动4、垃圾分类UGC5、垃圾分类答题活动生成海报,待审核发布中 目前分类数据已经把日常生活中最常用的维护进去了,还在一步一步完善中,由于白天还要上班,每天晚上会提交200条,请各位大大们不要嫌弃 具体如下图所示 接下来几天我会把在这两星期遇到的一些问题,跟大家分享整个实现的技术栈以及介绍几个技术细节,比如如何生成海报,如何前后端联调 如果对代码感兴趣,请在评论区留言,留下邮箱,我会第一时间把代码发过去。

July 10, 2019 · 1 min · jiezi

1个月获客100万这个支付宝小程序如何打造生态运营的增长飞轮

“支付宝生态红利是不可错过的时代产物,你很难再遇到这样一个能够让中小微创业者真正融入并扎根生长的生态平台。”拥有近 10 年互联网运营经验的老兵、嘉图软件副总经理兼共享事业部经理张韵攀说道。 嘉图软件是国内从事图书共享流转业务的平台企业,为全国读者提供书籍共享、图书借阅、二手书买卖等服务。张韵攀负责该公司线上图书共享业务。 二手共享市场被预测具有巨大的市场潜力,然而在共享经济心智日益成熟的今天,就二手图书业而言,据统计,全国每年新增闲置图书量约为 20-30 亿册,2014 年至今闲置图书量已经达到100 亿册,但是,国内二手书回收率不足 5%,流转率更加受到制约。 在这样的背景下,嘉图软件运营的支付宝小程序书袋熊 BOOKSTORE 平台,上线 1 个月时间即实现从零开始累计获得超过 100 万用户,并且不到三个月销售二手书 20 万册,营收上每个月增长率达 50%。这样的创新自运营成绩,让书袋熊 BOOKSTORE 小程序一举夺得第一届支付宝小程序创新大赛总季军。 支付宝小程序创新大赛是以支付宝端为依托,面向广大开发者、商户及企业的大型创新创业孵化计划,旨在通过开放阿里巴巴与蚂蚁金服的技术、能力和生态,助力优秀商户探索解决实际生活问题,推动各行业生态商业创新和服务升级。以日前刚结束的第一届大赛为例,通过创新挑战赛,支付宝小程序助力了多项商业价值创新成果,书袋熊便是其中之一。 那么,在高速业务增长的背后,书袋熊是如何不断向前自我驱动的? 为什么选择支付宝?虽然 2018 年才开始探索支付宝小程序,而嘉图软件与支付宝的结缘可以追溯到 2016 年 12 月。 据介绍,那时嘉图软件通过与芝麻信用合作,帮助全国多个城市公共图书馆简化线上借阅流程,优化读者体验,提升图书借阅率。 而随着自身对图书线上线下的管理能力逐渐形成,嘉图软件希望图书管理服务能够向外延伸,因此开展了二手图书回收共享业务,向更广大读者提供图书借阅、交易、公益捐赠等服务。 关于互联网线上运营,嘉图软件也经历尝试了许多路径,而该公司最终选择支付宝小程序的考虑在于,首先,无论是图书借阅或销售交易,都需要信用担保和完善的流程服务,支付宝则天生具有信任和服务的属性,通过接入支付宝展开业务是自然而然的选择。其次,由于自身场景的锻造,支付宝具有丰富的商业基础资源和能力支持,能够适应各类业务场景。 更重要的是,张韵攀表示,支付宝具有非常成熟的生态,强大的生态连接力和平台工具让中小微业务能够植根其中成为一方领域、一个频道,打造自己的阵地和增长模型,实现服务升级和商业创新。“这些原因促使我们决定全力投入支付宝生态,探索支付宝小程序的创新运营。” 也因为这些不同的考虑,书袋熊小程序上线时并没有直接做太多关于小程序本身的推广活动,而是通过“创新图书循环服务+支付宝开放平台”的融合创新模式,打造新的图书共享平台服务体系。 “我们的目标是从图书全生命周期出发,从各个领域贡献自身的能力,而不是利用支付宝小程序简单获取流量。”强调服务的生态特点,既是支付宝的优势,也是前提基础。 张韵攀认为,图书共享与循环流转是链条很长的过程,图书管理服务能力也具有相应的壁垒,而且阅读是一项深度沉淀的服务和社交活动,如果不能很好地消化转换平台上的流量,并提供优质的服务体验,后续的自运营就是空中楼阁。 因此,书袋熊小程序在开发、上线过程中,在支付宝小程序创新大赛平台的助力下,选择了通过服务生态、融合场景的方式来影响用户,创新商业运营模式。 1个月100万用户背后的秘诀经过多年实践积累,支付宝上有丰富的应用和服务场景对外开放,包括蚂蚁森林、小目标、社区生活等,以及地图、芝麻信用、区块链、智慧营销等技术和能力都全面开放给支付宝生态创新创业者。 图书共享流程包括从回收、处理,到借阅、捐赠或售卖。张韵攀介绍,书袋熊的图书回收能力包括完善的物流服务体系,后期对图书进行质检、消毒、翻新、塑封的仓储处理能力,以及高达数百万册的图书管理能力。数百万册的图书相当于一个市级图书馆藏书管理规模。 基于小程序进行生态创新运营时,书袋熊首先根据支付宝各类场景和能力特点,对自身业务和能力进行分解,形成不同的服务和能力融入支付宝生态场景中,最终实现全链条自运营创新。在此过程中,大赛也持续为参赛团队组织由投资人、创新创业者等组成的专家集训营交流。张韵攀笑称,“过去这大半年我几乎一周来一次支付宝大楼。” 服务输出,融合生态场景首先是回收循环的创新。 基于回收能力形成的壁垒,现在,在芝麻信用的信用回收频道,以及在城市服务领域,书袋熊都成为图书快速回收场景的服务者,输出图书回收处理能力。同时,书袋熊也作为绿色能量生产的策略和支付宝生态紧密结合,读者参与书籍回收可以获得相应的“蚂蚁森林能量”奖励。 而在提供能力和服务的同时,书袋熊也获得了生态的支持。除了一方面获得庞大的流量资源,化公为私,另一方面,基于芝麻信用能力,书袋熊实现预付款结算的回收模式创新,提升回收效率和用户体验;而基于城市共享和蚂蚁森林等应用,成功打造了良好的绿色阅读的心智,吸引用户。据统计,书袋熊上线收书 2 个月,收书总量超过 100 万册;截至 6 月 10 日,收书总量超过 300 万册。 过去,图书回收存在几个痛点:一是流程问题,需要读者先寄回书籍,再被评估价值,最后打款,过程长、无保证;或者是,线上线下回收点不发达,送书不够便捷,再一次提高书籍回收门槛。今天,这些问题都得到了解决。“支付宝生态的服务属性很强,相应地用户的便民诉求也比较突出。”张韵攀说道。“痛点的解决对市场潜力的释放作用也尤其明显。” 然而,“不只是收书,送书也是书袋熊的能力,”张韵攀笑道,并且,送书作为优质权益,它在书袋熊连接更丰富的场景中发挥着更加重要的作用。 打造场景矩阵,高增长高转化“免费领好书”是书袋熊为生态打造的一项“送书”权益,通过它而连接的生态场景涵盖支付宝的业务、应用、服务等各种类型,实现多场景融合,并将用户沉淀在小程序和生活号上。比如: 通过该权益,书袋熊与支付宝生态包括饿了么会员、支付宝会员、花呗等场景保持高频互动,最高曾实现单日会员增长 180%。对接“步数”应用,通过“行万里路,读万卷书”活动,读者可用步数免费兑换好书。针对大学生活、社区生活等人群和服务场景,推出“打卡读书小目标”等活动,覆盖更多人群。……有了更多好书,实现生态连接、用户留存后,基于支付宝人群画像、精准营销推荐等技术能力,通过“书单推荐”、“名人荐读”等服务,实现购买转化。据透露,书袋熊小程序上线 1 月累计用户突破 100 万,“免费领”销售转化率达到 11%;截至 6 月 10 日,出现单日订单最高超过 23000 单。 ...

July 9, 2019 · 1 min · jiezi

解决小程序scrollintoview无效果的问题

scroll-view的scroll-into-view无效,在支付宝小程序里scroll-into-view随着点击事件而改变,但是就是不会滚动,代码如下:<scroll-view scroll-y="true" style="height:100%;" scroll-into-view="{{scrollTopId}}" scroll-with-animation="true" enable-back-to-top="true">查了好久,终于找到一篇有用的文章,是style中的height设置了100%导致的。由于微信小程序是用mpvue写的,height设置了100%还能滚动,所以一直没想到原生的会有不一样的效果。 以下内容转自http://blog.sina.com.cn/s/blo... 实际上,这里需要一些注意的地方:scroll-view默认跟view是一样的,只是一个view容器,默认会随着内容大小自动改变大小。只有当你的scroll-view的大小,小于其内的内容时,才有机会实现真正的滚动。所以,你必须设置固定的宽高,如果不设置,那与滚动相关的功能都不会有。看似可以滚动,那个不是scroll-view的,而是window本身的滚动。造成了错觉。 既然如此,很多人设置了100%的高度,依然不行,这里必须设置固定的高度如400rpx之类的。不支持%单位。不信你试试! 还有一些其他问题会导致scroll-into-view失效的情况,比如: 下面是显示list和滚动到list同时setdata,不会成功 this.setData({ showtype:1, catlistHidden:true,toView: "defaultlist"}); 你必须改成,先显示,然后再滚动,分两次折行setData this.setData({ showtype:1, catlistHidden:true}); this.setData({ toView:"defaultlist"});//要先显示才能scroll-into,否则不会发生

July 9, 2019 · 1 min · jiezi

笔记微信小程序组件开发component

一、创建组件新建组件文件夹习惯组件目录放在src下面,在src/components/privPopup,跟其他的页面目录一样,新建wxml/js/json/wxss四个文件 在wxml里面,跟普通的页面一样的写法 <view class="st-modal-btns"> <label role="button" class="st-modal-btn border-top-1px border-right-1px st-button st-button-default" bindtap="onCancel"> <span class="st-button__text">取消</span></label> <label role="button" class="st-modal-btn border-top-1px st-button st-button-default st-modal-btn_highlight" bindtap="onConfirm"><span class="st-button__text">已阅读并同意</span></label></view>在json文件里面进行自定义组件声明,将component字段声明为true。其他的wxml和wxss写法和其他页面类似。{ "component": true}组件js文件里面使用Component({})来注册,并提供组件的属性定义、内部数据和自定义方法,组件的属性值和内部数据将用于wxml的渲染。其中属性值是可由组件外部传入的。Component({ data: { closed: false }, properties: { visible: { type: Boolean }, notConfirmList: { type: Array, }, }, methods: { onCancel() { this.triggerEvent('close'); }, onConfirm() { this.triggerEvent('confirm'); }, clickProtocol(e) { let goProtocol = { val: e.currentTarget.dataset.url }; this.triggerEvent('goProtocol', goProtocol); } }});二、引入组件account/index.wxml <privpopup visible="{{popupVisible}}" notConfirmList="{{notConfirmList}}" bind:close="onPopupClose" bind:confirm="onPopupConfirm" bind:goProtocol="goProtocol"/>account/index.json进行引用声明,提供自定义组件的标签名和自定义组件的引用路径{ "usingComponents": { "privpopup": "../../components/privPopup/index", }}三、父子组件传值通信1. 子组件向父组件传递数据子组件往父组件传值例如:我要把弹窗里面的协议用户点中的url传到父组件中,然后发生跳转 ...

July 8, 2019 · 1 min · jiezi

99的程序都没有考虑的网络异常使用Fundebugnotify主动上报

近日看到一篇文章99%的程序都没有考虑的网络异常,开篇提到: 绝大多数程序只考虑了接口正常工作的场景,而用户在使用我们的产品时遇到的各类异常,全都丢在看似 ok 的 try catch 中。如果没有做好异常的兼容和兜底处理,会极大的影响用户体验,严重的还会带来安全和资损风险。于是,笔者分析了 GitHub 上的一些开源微信小程序,发现大多数的代码异常处理确实是不够的。 登录接口只考虑成功的情况,没考虑失败的情况//调用登录接口wx.login({ success: function() { wx.getUserInfo({ success: function(res) { that.globalData.userInfo = res.userInfo; typeof cb == "function" && cb(that.globalData.userInfo); } }); }});网络请求只考虑then不考虑catch util.getData(index_api).then(function(data) { //this.setData({ // //}); console.log(data);});考虑了异常情况但是没有做妥善的处理 db.collection("config") .where({}) .get() .then(res => { console.log(res); if (res.data.length > 0) { Taro.setStorage({ key: "config_gitter", data: res.data[0] }); } }) .catch(err => { console.error(err); });也许 99%的情况下接口都是正常返回的,只有 1%的情况会失败。看起来好像不是一件严重的事情,但是考虑到用户的量级,这个事情就不那么简单了。假设有 100 万用户,那么就有 1 万用户遇到异常情况,而且如果用户的使用频次很高,影响的何止 1 万用户。并且,如今产品都是体验至上,如果遇到这样的问题,用户极大可能就弃你而去,流失了客户就等于流失了收入。 ...

July 8, 2019 · 1 min · jiezi

小程序采坑记

小程序采坑记上手小程序两个月,多多少少遇到一些坑,在此简单地作下总结。希望能对那些跟我一样有遇到过同样问题的人提供一点帮助,避免掉进这些坑,少走一些弯路。因为自己比较菜,也讲不了多少有用的东西,欢迎大神指教~~1. swiper组件高度的自适应问题用过小程序swiper组件的everybody 应该都知道,在swiper组件里只可放置swiper-item组件,否则会导致未定义的行为。但一些人可能会遇过这种情况:已知小程序 swiper 组件默认高度150px,如果子元素高度过高,swiper不会自适应高度。这种情况挺坑的。。要动态的改变swiper的高度,还得靠wx.createSelectorQuery()(在自定义组件或包含自定义组件的页面中,应使用 this.createSelectorQuery() 来代替)创建一个SelectorQuery 对象实例,通过选择器获取组件的高度去动态地改变swiper的高度,麻烦。 2. scroll-view组件内嵌原生组件scroll-view组件不得不说,挺坑的,尤其是在与原生组件配合着使用的时候,容易出现”惊喜“的效果。在scroll-view里内嵌textarea原生组件,真机调试上textarea直接不跟着滑动;在scroll-view里内嵌input组件,安卓手机的测试正常,iPhone上却出现了input框里输入数字重叠的情况......流泪ing...有个解决的方法是,用view组件替代scroll-view组件,在view组件里设置属性scroll-y或scroll-x,可模拟scroll-view的滑动功能,但需要给view组件设置{overflow: auto;}的样式才行。 3. 公共属性hidden失效的问题有些人可能一直使用hidden都没出什么问题,觉得hidden是一直生效的,但实际上hidden属性也有失效的时候。举个栗子,用最简单的代码阐述这个现象: <view hidden>啦啦啦</view><view style="display: block" hidden>啦啦啦</view>你会发现,前一个被成功隐藏了,但是后一个不会被隐藏。 一句话:在style属性里设置display属性会直接让hidden属性失效。 4. switch组件先引用下官方文档的说明: 可发现,这里仅有一个color样式可设置,若要改变switch组件的尺寸,还得这样写: .wx-switch-input{ width: 82rpx!important; height: 40rpx!important;}.wx-switch-input::before{ width: 80rpx!important; height: 36rpx!important;}.wx-switch-input::after{ width: 38rpx!important; height: 36rpx!important;}这种处理方式,虽然起作用了,但实际上可以看出,尺寸的设置依旧有很大的限制(可以自己试试),并不推荐这种做法。比较好的方法是引入第三方的组件库,例如直接用Vant Weapp里的switch组件。 5. 原生组件input无法被cover-view和cover-image之外的组件覆盖?对于这个问题,可能很多人都会回答说:是的。但实际上真是这样吗? 其实小程序的input组件表现挺奇怪的。首先,官方文档说他仅在focus时表现为原生组件。 这句话直到现在,我也觉得挺有问题的。来看看这个栗子吧,看看input组件的神奇表现: <view style="position: relative"> <image src='/pages/image/location.png' style="position: absolute; top: 10rpx; z-index: 1; width: 100rpx; height: 100rpx; background: gray" bindtap="click" > </image> <input style="background: yellow; border: 1px solid #000; height: 120rpx; width: 100vw;" bindinput="inputHandler" placeholder="请输入你的文字~~~" placeholder-style="color:#999" /></view>效果如下: ...

July 8, 2019 · 1 min · jiezi

小程序获取用户信息交互指南2

July 6, 2019 · 0 min · jiezi

小程序获取用户信息交互指南

July 5, 2019 · 0 min · jiezi

小程序egg后台简要文档

小程序egg后台简要文档更多 blog如果不需要后端java或者其他语言支持,对于小型的小程序后台,可以使用eggjs框架快速搭建简要的数据后台。 如果未接触过node编写接口,首先还是需要基本过一下egg官方文档,至少得把快速入门看完。 不会从头开始把每一步都详细写下来,只针对微信对接的一些处理列出来。 数据库使用mongo,示例通过egg-mongoose进行连接处理。 安装插件后,在/config/plugin.js进行基本配置: mongoose: { enable: true, package: 'egg-mongoose'}在/config/config.default.js文件中配置mongodb的连接(保证本地测试环境数据库连接好): // connect mongo config.mongoose = { client: { url: 'mongodb://127.0.0.1/fulishe', options: {}, } }在/app/models文件夹编写相关的model,在程序运行时会自动在mongo上创建对应的表。也可以优先创建好数据库和表设计等。 编写接口在controller写主要的业务逻辑,接受接口请求参数并返回。对于入参,需要进行验证的可以做验证处理,需要处理返回结果,即使请求出错也不要返回非200的状态码。可以将处理结果设置为一个函数,如: // data: 返回给前端的数据,code: 状态,1为成功,0为失败,message:状态信息formatResponse: function (data, code, message) { return { code, data, message }}!> 为避免出现出现问题而导致程序中断,最好在每一个容易出现问题的地方进行try catch将异常抛出并返回到前端。 在service编写数据库操作函数等,通过在controller进行调用,统一管理数据库数据进出。注意在数据新增的时候需要进行save操作: const addUser = await this.ctx.model.Users(data)addUser.save() // 不要遗漏相关的增删改查操作,需要直接点的可以看仓库app/service下的写法。 小程序接口相关以下是eggjs对小程序包括获取openId、获取unionId、获取手机号码、判断用户是否关注公众号、客服信息发送进行编写说明。 如果某个对象不知道是什么,一般都是可以根据名字找到对于的js文件或者通过npm引入,不再表述引入什么了。 获取openId参数说明: APPID: 小程序的appIdSECRET: 小程序的secret,跟appId在同一个地方能找到CODE:小程序在前端通过wx.login()获取的jscodeconst openIdRes = await rp(`https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${CODE}&grant_type=authorization_code`)const openId = JSON.parse(openIdRes).openId // 在处理错误判断后,返回的数据是json字符串,需要转化获取unionIdunionId,属于微信端通用的账号唯一标识,举个例子就是同一个微信号,唯一对应一个unionId。而在每一个小程序上,用户openId都不一样。可以用于判断在小程序上的用户是否关注公众号等。 ...

July 5, 2019 · 2 min · jiezi

混微信动态生成tabslist方案优化

在实现上图的开发过程中,总结了一套代码整洁的tabs-list的开发方式分析逻辑:①tabs可以当做一个json(好处在于通过wx:for可以动态生成,choosestatus可以用来对应下面的数据) [{ name:"待兑换", chooseStatus:"effectCoupon" },{ name:"已兑换", chooseStatus:"overdueCoupon" },{ name:"已过期", chooseStatus:"usedCoupon" }],②由于种种原因,接口返回的3个list是分开的。这就是choosestatus的作用,和返回的3个list字段一一对应,通过变量,动态改变选中样式和存储list的数组 get_yhq_list: function (e) { var _this = this; var clickId = e.currentTarget.dataset.index; //把点击的索引传递过来,改变显示隐藏的数组的布尔值来改变样式 var clickStatus = e.currentTarget.dataset.choose; //把点击的参数传递过来 _this.data.is_tab_on = [false,false,false]; _this.data.is_tab_on[clickId] = true; if(_this.data[clickStatus].length > 0){ _this.setData({ is_no_data:false, is_tab_on:_this.data.is_tab_on, CardList:_this.data[clickStatus] }) }else{ _this.setData({ CardList:[], is_tab_on:_this.data.is_tab_on, is_no_data:true, }) } },

July 5, 2019 · 1 min · jiezi

wepy返回上一页修改上一页面data后却没更新

A-B-A过程。 //A页面data = { value:'' }onShow(){ console.log(this.value) } //跳转到B页面methods ={ goB(){ wepy.navigateTo({ url: B); }}//B页面 onLoad(options){ }methods = { goBackA(){ var pages = getCurrentPages(); // 获取页面栈 var prevPage = pages[pages.length - 2]; // 上一个页面 prevPage.setData({ value:2 }) wepy.navigateBack({ delta: 1 }) }}开始觉得不是很简单嘛,原生就有 意想不到的情况发生了,在A页面onShow方法中打印value是空,也取不到,但是页面能渲染。。。懵逼了啊 最后在公司大神提醒下看了试了preload方法官网地址 A页面修改如下 this.$preload('preload',preloadData) wepy.navigateTo({ url: B);然后完美实现,是不是超简单。。具体preload用法参考 https://www.cnblogs.com/l-yabiao/p/9136327.html 文笔一般,给个赞吧

July 4, 2019 · 1 min · jiezi

小程序与小游戏获取用户信息接口调整请开发者注意升级

最近在开发小程序的过程中,获取用户信息一直得不到预期的效果,查了一些文档最终发现wx.getUserInfo接口不能弹出授权询问框了。https://developers.weixin.qq.... 微信相关公告如下 为优化用户体验,使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版调用 wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败。正式版暂不受影响。开发者可使用以下方式获取或展示用户信息: 一、小程序: 1、使用 button 组件,并将 open-type 指定为 getUserInfo 类型,获取用户基本信息。 详情参考文档: https://developers.weixin.qq.... 2、使用 open-data 展示用户基本信息。 详情参考文档: https://developers.weixin.qq.... 后话如果这样的话,如何弹出用户授权弹窗,以下几个方案仅供参考 方案1:在刚开始进入小程序的时候弹窗,然后如果已经授权可以获取,如果未授权则需要跳转到对应授权按钮页面

July 4, 2019 · 1 min · jiezi

小程序技术始于微信来看看移动端小程序技术的前世今生

本文由DCloud 公司创始人王安原创发布于CSDN,原题《小程序技术演进史》,即时通讯网收录时有改动,感谢原作者。 1、引言微信的成功,并非特定于某个具体的功能,微信的成功实际上是一大批创新技术和体验的成功合集,这也是它为何如此难此被超越的根本原因。 作为微信这个超级社交应用中最为亮眼的技术之一——微信小程序,俨然已成历移动端小程序的代名词,很多人一提起“小程序”3个字就条件反射式地认为是微信小程序。事实是,小程序技术并非微信独创,它的出现和演进,实际上包含了一大批各类公司、各产品技术先驱们的努力。 实际上,早在微信小程序之前,有力推轻应用的百度,有来自 HTML5 中国产业联盟的 DCloud 所主张的流应用,但最终却都已经淹没在了移动互联网的历史长河之中。唯有微信小程序风生水起,更是带动了巨头们的争相入场。 小程序迎来了专属于中国移动互联网的群雄逐鹿的时代。 本文作者王安即是流应用的创造者,作为移动领域的老兵,他依然在矢志不移地构建移动开发工具框架及生态,从原生应用到 HTML5 再到如今的小程序,他是这段历史的见证者、参与者。 本篇文章,将为你盘点移动端小程序技术的前世今生。通过本文,我们能够鲜活地看到小程序的技术演进历程,以及对于所有开发者来说,终将去往何处。 (本文同步发布于:http://www.52im.net/thread-26...) 2、关于作者王安:DCloud 公司创始人,HTML5 中国产业联盟秘书长。2003 年开始从事移动互联网工作,十几年编程和商业经验,连续创业者。曾任北京市学联主席,毕业后创办 DCloud 公司。兴趣爱好:编程、颠覆式创新。 3、相关文章《最火移动端跨平台方案盘点:React Native、weex、Flutter》《盘点主流移动端跨平台UI技术:实现原理、技术优劣、横向对比等》 4、中国特色的移动互联网时代伴随着 QQ 小程序 面向用户开放,这个手机端月活 7 亿的巨无霸正式入场。小程序,终于成为了超级 App 的标配。 盘点下已经支持小程序的超级 App: 微信、企业微信、QQ、支付宝、高德地图、手机淘宝、百度、百度贴吧、百度地图、今日头条、抖音…… 这些璀璨耀眼的名字,背后都是巨大的流量。 在这群超级 App 的支持下,中国的移动互联网格局被彻底改变。 这个有中国特色的移动互联网时代,被称为“小程序时代”。 这是继手机支付后,中国的移动互联网领先世界的第二个代表事物。 中国的技术标准、开发者生态,第一次得到大规模的普及应用,而且很明显,小程序在功能和体验上均超过了 HTML5。 中国人能建立开发者生态吗?这个命题曾一度让人怀疑。 小程序完成了这一步突破,这是一场值得歌颂的中国技术生态发展史。 让我们来回顾下这场技术生态革命,是如何开始,又将要去向何方。 5、罗马不是一天建成的,小程序也不是一天发明出来的HTML5 于 2007 年在 W3C 立项,与 iPhone 发布同年。 乔布斯曾期待 HTML5 能帮助 iPhone 打造起应用生态系统。 但 HTML5 的发展速度并不如预期,它虽然成功地实现了打破 IE+Flash 垄断局面的目标,却没有达到承载优秀的移动互联网体验的地步。 于是在 iPhone 站稳脚跟后,发布了自己的 App Store,开启了移动互联网的原生应用时代。 ...

July 4, 2019 · 3 min · jiezi

wepyredux

wepy-reduxredux文件 typetypes里是触发action的函数名称 只是存储函数名字 按照模块去创建type.js //base.jsexport const GETALLHOMEINFO = 'GETALLHOMEINFO'写好了函数名称 在index.js中export出来 export * from './counter'export * from './base'reducers随着应用变得复杂,需要对 reducer 函数 进行拆分,拆分后的每一块独立负责管理 state 的一部分这个时候多个模块的reducer通过combineReducers合并成一个最终的 reducer 函数, import { combineReducers } from 'redux'import base from './base'import counter from './counter'export default combineReducers({ base, counter})模块使用handleActions 来处理reducer,将多个相关的reducers写在一起handleActions有两个参数:第一个是多个reducers,第二个是初始state GETALLHOMEINFO reducer是将异步action返回的值赋值给data //base.jsimport { handleActions } from 'redux-actions'import { GETALLHOMEINFO } from '../types/base'const initialState = { data: {}}export default handleActions({ [GETALLHOMEINFO] (state, action) { return { ...state, data: action.payload } }}, initialState)actionsactions是对数据的处理 在index.js中export出来 ...

July 3, 2019 · 1 min · jiezi

小程序中canvas的drawImage方法参数详解

最近在开发小程序,海报生成的过程中,要在carvas中不断去添加图片,对小程序的drawImage参数不是很明确,这次解惑。 示例代码有三个版本的写法: drawImage(imageResource, dx, dy) drawImage(imageResource, dx, dy, dWidth, dHeight)drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 从 1.9.0 起支持const ctx = wx.createCanvasContext('myCanvas')wx.chooseImage({ success: function(res){ ctx.drawImage(res.tempFilePaths[0], 0, 0, 150, 100) ctx.draw() }})这个方法跟原生canvas的一样,具体如下 HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。drawImage函数有三种函数原型: drawImage(image, dx, dy) drawImage(image, dx, dy, dw, dh) drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)第一个参数image是所要绘制的图片资源 作为参数。dx和dy是image在canvas中定位的坐标值;dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值;sx和sy是image所要绘制的起始位置,sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值。

July 3, 2019 · 1 min · jiezi

gulp小程序高效开发

简介基于gulp4.0 实现七牛云自动上传+图片压缩+scss+封装wx.request+实时编译脚手架开发小程序 根据WeApp-Workflow 修改 在这里你可以找到一个简单的gulp构建的小程序友好的使用scss,高效开发压缩图片,自动上传七牛云px转换rpx封装request,添加拦截器介绍SCSS 实时编译为 WXSS,图片压缩新增 图片上传七牛云cdn新增 请求数据优化相对路径的图片引用,gulp复制文件和替换%ASSETS_IMG%/冲突,导致保存文件时小程序报错 开始使用Node 版本建议在v4 以上,本人使用8.9.1,低版本容易npm i安装失败安装0、请先全局按照 Gulp-cli npm install gulp-cli -g1、通过git clone下载项目文件。 git clone https://github.com/sunnie1992/weapp-gulp2、建议删除.git目录(Windows 用户请手动删除) cd weapp-gulprm -rf .git3、安装必要模块 npm i4、启动开发 建议复制config.js并重命名为config.custom.js,修改七牛云配置,根据 gulp-qiniu配置 gulp ornpm run dev 其余任务:gulp clean:清除dist,tmp文件夹。 鸣谢WeApp-Workflow 意见反馈您可以扫描添加下方的微信并备注 Soul 加交流群,给我提意见,交流学习 如果对你有帮助送我一颗小星星(づ ̄3 ̄)づ╭❤~

July 3, 2019 · 1 min · jiezi

小程序公众号免费商城系统源码

源码地址 功能简介 1.商品: 能够对商品的状态分类管理 (出售中、待上架、库存中、已售馨、库存警戒、回收站)、添加产品、添加商品分类等功能 2.会员:站内会员的管理 (发放优惠劵、发通知、发图文消息、增加余额、会员行为详情)、站内通知 、微信端用户管理 (微信用 户的管理、分组、行为观察、添加标签) 等功能 3.营销:能够管理优惠的发放和制作、用户积分的统计使用情况、秒杀产品的管理等 4.财务:能够对用户的消费、充值、返佣的记录 5.订单:能够完成用户的订单管理(发货、订单详情、修改订单、订单备注、订单记录、订单退款) 、售后服务 (评论的回复与删除) 6.分销:后台有分销统计管理,分销可以设置人人分销和指定人分销,也可以自己稍微开发一下修改规则,例如下单后成为分销等 7.数据统计图表统计分析(财务统计、产品统计、会员统计、营销统计、分销统计、交易统计等) 8.设置:能够完成管理员对网站的商品资料(添加大类、添加小类、商品添加、属性快速生成、商品审查)、商品交易(外理订单、发 货查询)、会员管理(会员审查)、操作管理(管理员添加、管理员审查、管理员退出)、系统配置、后台通知等功能 9.内容:管理文章分类 (添加分类、删除分类、修改分类) 、 管理文章 10.维护:查看系统日志、文件变动效验、刷新网站缓存、在线更新系统、清除数据、文件管理等功能 11.强大的权限管理系统

July 3, 2019 · 1 min · jiezi