1. 微信小程序开发中遇到的坑及解决办法
taro单独为某个项目切换taro版本环境
单独为某一个项目升级#这样做的好处是全局的 Taro 版本还是 1.x 的,多个项目间的依赖不冲突,其余项目依然可以用旧版本开发。 如果你的项目里没有安装 Taro CLI,你需要先装一个:
# 如果你使用 NPM
$ npm install --save-dev @tarojs/[email protected]
# 如果你使用 Yarn
$ yarn add -D @tarojs/[email protected]
echarts在小程序中滑动卡顿
由于微信小程序中,echarts的层级最高,无论设置多大层级也无法遮住echarts。而且小程序中好像只能用echarts吧。所以为了解决这个bug,我只能委屈求全了。打开ec-canvas.wxml文件,将touchStart、touchMove和touchEnd去掉了,直接删除就好啦。这三个事件应该是做缩放的吧,我们也没有这个缩放的需求。所以就去掉了。虽然暂时满足的需求,还是没有真正的解决问题。
原:
bindinit="init"
bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}"
bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}"
bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"
现:
bindinit="init"
echarts在小程序中无法跟随页面滑动
在卡顿问题中能与echarts交互少的,可以直接使用图片代替cannvas,即在echarts渲染完毕后将它替换为一张图片。
如果我更新了数据,那么就重新放出echarts,等它渲染完毕后,再次替换为一张图片。
chart.on('finished', () => {
getCurrentInstance().page.selectComponent(id).canvasToTempFilePath({
success: res => {
console.log('res.tempFilePath====',res.tempFilePath)
this.setState({
echartImgSrc: res.tempFilePath
})
},
fail: res =>console.log('转换图片失败', res)
});
})
render:
this.state.echartImgSrc =='' ?
ref={this.refChart}
id={this.state.id}
canvas-id="mychart-area"
force-use-old-canvas="true"
ec={this.state.ec}
/>
:
<CoverImage src={this.state.echartImgSrc}></CoverImage>
2. 微信小程序H5页面缓存问题处理
微信小程序会缓存H5页面,导致页面升级之后不能及时刷新。
这种情况通过配置nginx不缓存静态页面无法影响到小程序缓存。
假设H5请求地址是 https://xxx/h5/
用户进入小程序之后生成一个数字,请求H5时把数字拼接到URL后缀即可。
例: https://xxx/h5/222/
3. 微信小程序webview的缓存问题
小程序webview的页面缓存会影响开发中的调试和生产中的使用
1.页面缓存由浏览器缓存引起,那么可以通过设置来修改浏览器缓存。
可以通过nginx设置cache-control 来关闭浏览器缓存
2.由于是单页面应用,所以只需要对index.html设置即可。
对index.html中的资源地址,也会存在缓存,可以通过webpack构建时加入hash值解决。
4. 小程序之缓存
每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync)可以对本地缓存进行设置、获取和清理。同一个微信用户,同一个小程序 storage 上限为 10MB。localStorage 以用户维度隔离,同一台设备上,A 用户无法读取到 B 用户的数据。
1.设置缓存
2.获取缓存
3.清除缓存
5. 微信小程序开发——本地缓存
本地缓存是指微信小程序存储在当前设备空间里地数据。在官方文档说明中,其所有的数据存储上限为10MB即单个小程序的存储空间上限为10MB。==在使用过程中用户使用本地缓存可以存储一些非重要性的生产操作,例如让小程序再次打开能快速渲染页面,减少用户等待时间。
小程序提供了读写删本地缓存的方法:
关于同步缓存和异步缓存的区别
异步与同步的区别是,异步不会阻塞当前任务,同步缓存直到同步方法处理完才能继续往下执行。
写入本地缓存
根据key读取本地缓存
根据key移除本地缓存
清除本地所有缓存
最后,还要注意的一点是如果写入了同样key的缓存数据,后写的会覆盖了前者,因此需要我们注意一下
6. 小程序开发有哪些坑
1. JSON 配置文件小程序中,包含唯一的全局配置文件app.json,以及每个页面的配置文件page.json。每单页页面相应的 JSON 文件会覆盖与app.json相同的配置项。如下,是一个包含了所有配置选项的简单配置app.json。"pages": [ //设置页面的路径"pages/index/index", //不需要写index.wxml,index.js,index,wxss,框架会自动寻找并整合"pages/logs/logs"],"window": { //设置默认窗口的表现形式
"navigationBarBackgroundColor": "#ffffff", //顶部导航栏背景色
"navigationBarTextStyle": "black", //顶部导航文字的颜色 black/white
"navigationBarTitleText": "微信接口功能演示", //顶部导航的显示文字
"backgroundColor": "#eeeeee", //窗口的背景色
"backgroundTextStyle": "light", //下拉背景字体、loading 图的样式,仅支持 dark/light
"enablePullDownRefresh": "false", //是否支持下拉刷新 ,不支持的话就直接不写!
"disableScroll": true, // 设置true不能上下滚动,true/false,注意!只能在 page.json 中有效,无法在 app.json 中设置该项。},"tabBar": { //底部tab或者顶部tab的表现,是个数组,最少配置2个,最多5个
"list": [{ //设置tab的属性,最少2个,最多5个
"pagePath": "pages/index/index", //点击底部 tab 跳转的路径
"text": "首页", //tab 按钮上的文字
"iconPath": "../img/a.png", //tab图片的路径
"selectedIconPath": "../img/a.png" //tab 在当前页,也就是选中状态的路径
}, { "pagePath": "pages/logs/logs", "text": "日志"
}], "color": "red", //tab 的字体颜色
"selectedColor": "#673ab7", //当前页 tab 的颜色,也就是选中页的
"backgroundColor": "#2196f3", //tab 的背景色
"borderStyle": "white", //边框的颜色 black/white
"position": "bottom" //tab处于窗口的位置 top/bottom
},"networkTimeout": { //默认都是 60000 秒一分钟
"request": 10000, //请求网络超时时间 10000 秒
"downloadFile": 10000, //链接服务器超时时间 10000 秒
"uploadFile": "10000", //上传图片 10000 秒
"downloadFile": "10000" //下载图片超时时间 10000 秒
},"debug": true //项目上线后,建议关闭此项,或者不写此项
2. JS 逻辑层
小程序的逻辑层由 JavaScript 语言完成。但因为小程序不在浏览器中运行,所以 JS 在 web 浏览器中的一些函数不能用,如document、window等。
app.js有全局的小程序生命周期,page.js有自己本页面的生命周期。
2.1 注册小程序app.js
这一步骤,有这几个需要注意的地方:
必须在app.js中,使用app()函数注册微信小程序。全局小程序中,只能注册一次;
不能在app()内的函数中调用getApp()(小程序实例),使用this就可以拿到小程序的实例;
不要在onLaunch的时候getCurrentPage(),因为此时page还没有生成;
通过其他子页面调用getApp()获取实例后,不要私自调用小程序全局的生命周期方法;
可以通过var app=getApp()获取小程序的实例。
- app ( { // 小程序生命周期的各个阶段
- onLaunch: function(){},//当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
- onShow: function(){},//当小程序启动,或从后台进入前台显示,会触发 onShow
- onHide: function(){},//当小程序从前台进入后台隐藏,会触发 onHide
- onError: function(){},//当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
- // 自定义函数或者属性,用 this可以访问
- ...
- })
- Page({ data: { //页面的初始数据//调用:{{text}} {{array[0].msg}}
- text: 'init data', array: [{ msg: '1'
- }, { msg: '2'
- }]
- }, // 页面生命周期的各个阶段
- onLoad: function () {}, //生命周期函数--监听页面加载
- onShow: function () {}, //生命周期函数--监听页面初次渲染完成
- onReady: function () {}, //生命周期函数--监听页面显示
- onHide: function () {}, //生命周期函数--监听页面隐藏
- onUnload: function () {}, //生命周期函数--监听页面卸载
- onPullDownRefresh: function () {}, //页面相关事件处理函数。如果需要监听用户下拉动作,需要 在app.json中配置 "enablePullDownRefresh":"true" 允许上拉刷新
- onReachBottom: function () {}, //页面上拉触底事件的处理函数
- onShareAppMessage: function () { //用户点击右上角分享
- return { title: '自定义分享标题', desc: '自定义分享描述', path: '/page/user?id=123'
- }
- }, // 自定义函数或者属性如:
- customData: { hi: 'MINA'
- }...
- })
- function sayHello(name) {//公共方法util类
- console.log(`Hello ${name} !`)
- }mole.exports.sayHello = sayHello//用mole.exports 对外暴露接口
- //先引入文件,是新建的一个 utils 包,公共方法在 util.js 里面var util = require('../../utils/util.js')
- Page({//调用类
- onLoad: function () {// 使用时,用 util 引用名调用,如:util.sayHello()
- util.sayHello('我是传的值');
- }
- })
- App({// app.js
- globalData: 1})// 某 page.jsconsole.log(getApp().globalData)
- <view wx:if="{{zhenjiaa=='123'}}">123334</view><view wx:if="{{zhanjia}}">123334</view><view wx:if="{{len > 5}}">大于5我就显示了 </view><view wx:if="{{length > 5}}"> 1 </view><view wx:elif="{{length > 2}}"> 2 </view><view wx:else> 3 </view><block wx:if="{{true}}"><view> view1 </view><view> view2 </view></block>
微信小程序中的wx:if是惰性的。如果不符合渲染条件,它不会渲染相应部分;
使用display: hidden时,元素始终渲染,只是视图层上没有显示,用户看不见。
- page.jsPage({ data: {
- array: [1, 2, 3, 4, 5]
- }
- })
字符串:wx:key="unique"
保留关键字:wx:key="*this"
- <template name="msgItem"><view><text> {{index}}: {{msg}} </text><text> Time: {{time}} </text></view></template><!-- 其他代码 --><template is="msgItem" data="{{...item}}"/>
- <!-- B.wxml --><import src="a.wxml"/><!-- A.wxml --><template name="A">
- <text> A template </text></template>
- <!--引用 header、其中 header.wxml 中也引用了 footer.wxml--><include src="header.wxml"/><view> body </view><!-- header.wxml --><view> header </view><include src="footer.wxml"/>
2.2 注册小程序的页面page.js
Page()用来注册一个页面,维护该页面的生命周期以及数据。
2.3 公共模块util.js
公共模块方法需要通过mole.exports对外暴露接口,使用的时候需要利用require(path),将文件引入。如:
2.4 数据操作
setData()不能直接操作数据,例如this.data.text="xxxxx"就是错误的。你需要在this.setData ()之中,进行数据的操作。
同时,这里有作用域的问题。比如,需要在局部函数中使用,就需要.bind(this)。
如果你需要操作全局的数据,你需要在 app.js 中进行相应设置,例如:
3. 视图层 WXML
视图层的数据绑定均来自于Page中的data,想要修改相应值,你需要用到this.setData。数据绑定使用两对花括号,将变量名包起来。
3.1 条件渲染
你可以利用if和else,在视图层上编写在特定情况下,出现的不同的视图结果。
很多人会将 CSS 中的display: hidden属性,将其做一个比较。
如果你的小程序有元素显示频繁切换的需求,建议你使用display: hidden,能够为用户提供能顺畅的使用体验。
3.2 列表渲染
相当于让 WXML 处理一个循环。
在 WXML 中,你可以这样来建立一个 for 循环:
<view wx:for="{{array}}"> {{index}}:{{item}} </view>
然后在相应的 JS 中,新建一个数组:
需要注意的是,如果列表中的项需要动态添加到列表中,并希望项目保持原有的特征和状态,那么你应该使用wx:key。
wx:key有两种形式:
3.3 运算
WXML 可以执行简单的运算任务。例如:
<view> {{a + b}} + {{c}} + d </view>
也可以做到字符串拼接:
<view>{{"hello" + name}}</view>
甚至,你可以使用...在 WXML 中展开对象。
3.4 模板
name定义组件模版的名称,引用模版的时候使用is属性指定模版的名字,is可以进行简单的三目运算,需要传入模版需要的data数据。
因为模版拥有自己的作用域,所以只能使用 data 传入数据,而不接受双花括号的写法。
3.5 公共模块的引用
WXML 提供import和include两种文件引用方式。
import有作用域的概念,不能多重引用。
而include就可以多重引用了。
3.6 事件
名称以bind开头的事件不阻止冒泡,名称以catch开头的事件冒泡是阻止的。如bindTap和catchTab。
在 WXML 中,可以使用dataset定义data中的数据,会通过事件传递。它的事件以data-开头,多个单词以-链接,如data-a-b。
需要注意的是,使用这种方式定义的变量不能有大写。它会自动转成驼峰命名,调取的时候去驼峰命名的名字。
4. WXSS
WXSS 的用法类似于 CSS,并在 CSS 的基础上,扩展了 rpx 尺寸单位和样式导入功能。
WXSS 可以使用内联样式,但这样会影响渲染速度。
每个页面自己的page.wxss样式表,会覆盖全局样式表app.wxss。
7. 总结微信小程序中遇到的一些坑
然后再index页面的onload中判断显示哪个tab
wepy文档
1,Q: 怎么在page组件和 component 组件中回去到 getApp() ,就是app里面定义的函数,通过 this.$parent 只能拿到数据,拿不到方法?
A:可以在 this.$parent 的 _proto 上拿到方法,即 this.$parent.onLogin
2, Q:怎么实现按需加载
A:在 compoent 组件中自定义生命周期函数,并手动触发
8. 钉钉小程序(E应用)开发踩坑
a、在钉钉开发平台创建小程序,并将自己的钉钉账号设置为开发人员;
b、在IDE中登录,关联应用;
c、上传完成后,即可在钉钉开发平台将上传版本设置为体验版。
npm install lodash // 安装第三方包
import lodash from 'lodash' // 载入第三方 npm 模块
注: 可能报错 error:cannot read property 'prototype' of undefined;
建议: import get from 'lodash/get' 单独引入用到的工具类
编译失败查看日志,通常是超过5M,是将根目录下的debug.log一起编译到项目中了,所以直接删除这个debug.log就可以编译通过了
钉钉小程序E应用在发版时会有一个老版本的缓存,每次发版后直接打开E应用,其实访问的是上一个版本的缓存,这个缓存会在发版后10分钟左右自动更新成最新版本,如果想要直接看到最新版本,可以退出钉钉登录账户,并杀掉钉钉进程,这样再进去后就是直接访问的最新版本了.