生命周期执行顺序:onLoad > onShow > onReady
禁止下拉
app.json中window下加enablePullDownRefresh:false
摇一摇实现相应操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| onShow: function() { wx.onAccelerometerChange(function (res) { if (res.x > .7 && res.y > .7) { wx.showToast({ title: '摇一摇成功', icon: 'success', duration: 2000 }) } }) }
|
环境判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let version = __wxConfig.envVersion; if (!version) version = __wxConfig.platform;
switch (version) { case 'devtools': return 'https://xxx.com'; break; case 'develop': return 'https://xxx.com'; break; case 'trial': return 'https://xxx.com'; break; case 'release': return 'https://bbb.com'; break; default: return 'https://bbb.com'; }
|
自定义tabbar
和自定义组件相同
特别注意要在自定义组件中定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
properties: { selected: Number },
onLoad(){ if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ selected: 0 }) } }
|
env(safe-area-inset-bottom)
这个css属性只适用于苹果手机,该变量是IOS 系统内核提供的,在IOS上正常使用;而安卓和开发工具上用的是 Chromium 内核,没有这个变量,所以不支持
官方文档给的tabbar示例中有个css方法:
padding-bottom: env(safe-area-inset-bottom);
这个方法是用来兼容全面屏手机,如iPhoneX,XR,XS等,会在底部留下安全距离,但是引发另一个问题,就是滚动时页面会暴露在tabbar下面,像这样:

其实如果不是这种凸出来的,加个background
就搞定了,相当于挡住了下面的页面,而像上面这种就不能简简单单background
了,
这时候可以取个巧,利用背景渐变来达到效果:
1 2 3 4
| .tab-bar{ padding-bottom: env(safe-area-inset-bottom); background-image: linear-gradient(transparent 35%,#fff 35%) }
|
- !!!不要把自定义tabbar文件夹放在最外层,否则会导致全局引用
swiper指示点样式控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| .wx-swiper-dot { display: inline-block !important; width: 6rpx !important; height: 6rpx !important; margin-right: 8rpx !important; }
.wx-swiper-dot-active { width: 12rpx !important; height: 6rpx !important; border-radius: 3rpx !important; } .wx-swiper-dot::before{ content: ''; flex-grow: 1; background: rgba(255,255,255,0.8); border-radius: 8rpx } .wx-swiper-dot-active::before{ background:rgba(244,0,0,0.8); }
|
swiper-item一张时,真机调试出现不显示的情况,暂时处理为一张时不用swiper
找到解决方法了,哈哈哈哈哈哈哈,e,
每次更新数据的时候(数组的长度可能减小),所以记得:
1
| <swiper current="{{current}}">
|
1 2 3
| this.setData({ current:0 })
|
小程序中ios不支持时间格式为 - 或者 . 的转换必须转换为 / 格式
例如:new Date(“2019-07-05 12:00:00”.replace(/-/g, “/“));
只有这样可以得到正确的时间格式,其他转换可能也行,但是没试
1 2 3 4 5 6 7 8 9 10 11 12 13
| button::after{ border:none; } button{ outline:none; border:none; list-style: none; padding:0; line-height: normal; margin: 0rpx; background-color: #fff; border-radius: 0rpx; }
|
分享图片华为手机不支持本地图片,会有50%概率读取不到,亲测,放在cdn上是可以的
js canvas生成二维码,华为手机显示不出来,亲测,调用两边draw方法就可以成功
wx.chooseImage中使用wx.showLoading
- wx.chooseImage方法中使用wx.showLoading会导致wx.showLoading不显示,微信客户端bug,初步方案为加个setTimeout方法可以解决,时间必须设置300ms以上
自定义组件
自定义组件中css不建议使用标签选择器,手机调试会看到警告提醒,page中可以使用
自定义组件中获取canvas2d元素与page中获取方法不同:
pages中:
1 2 3 4 5 6 7
| wx.createSelectorQuery().select('#canvas').fields({ node: true, size: true, }).exec((res) => { const canvas = res[0].node; const ctx = canvas.getContext('2d'); })
|
自定义组件中:
1 2 3 4 5 6 7
| wx.createSelectorQuery().in(this).select('#canvas').fields({ node: true, size: true, }).exec((res) => { const canvas = res[0].node; const ctx = canvas.getContext('2d'); })
|
- 区别在于组件中要先调用
.in(this)
方法获取当前实例,才能再选择canvas
自定义组件监听数据变化
属性值的改变情况可以使用 observer 来监听。目前,在新版本基础库中不推荐使用这个字段,而是使用 Component 构造器的 observers 字段代替,它更加强大且性能更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Component({ properties: { min: { type: Number, value: 0, observer: function(newVal, oldVal) { } } }, observers: { "data": function (data) { this.setData({ allData: data }) this.formateData(this.data.allData) } }, })
|
传送门
1 2 3 4 5 6
| <scroll-view ...> <block wx:for="{{dataList}}" wx:key="index"> <view>{{item.id}}</view> </block> <view style="width:2rpx;height:2rpx;bottom:-2rpx;position:absolute;" /> </scroll-view>
|
1 2 3 4
| <scroll-view ...> <view style="width:100%;height:100%;padding-bottom: 20vw;"> </view> </scroll-view>
|
原理都相同,加个空view标签
撑起内容高度,我试了第二种实现了,第一种没实现
svroll-view下拉刷新有时会莫名抖动2020.07.24
用npm包时,先检查根目录是否有package.json文件,没有新建一个,再npm install
list页跳转detail页,detail页操作数据后,list做到不刷新同步数据
非常简单,利用小程序中自带方法getCurrentPages()
可以获取上个页面数据方法的特性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let pages = getCurrentPages(); if (pages.length >= 2 && pages[pages.length - 2].route == "page/list/list") { let preData = pages[pages.length - 2]; let arg = { resultFlag: res.infoMap.resultFlag, id: item.id, type: type, count: res.infoMap.count }; preData.detailSetData(arg) }
|
wx.setNavigationBarTitle方法不区分页面,导致异步请求未完成返回会显示在前一个页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let page = getCurrentPages(); let currentRoute = page[page.length - 1].route; setTimeout(()=>{ let page2 = getCurrentPages(); let currentRoute2 = page2[page2.length - 1].route; if (currentRoute == currentRoute2) { wx.setNavigationBarTitle({ title: res.result.goods_name }) } },1000)
|
模板语法
1.定义模板,使用name
属性作为模板名称,然后再template
标签中写入代码,或者引入自定义组件
1 2 3 4 5 6
| <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template>
|
2.使用模板,使用is
属性,声明要使用的模板,然后将上面定义的模板中需要的数据引入:
1
| <template is="msgItem" data="{{...item}}"/>
|
1 2 3 4 5 6 7 8 9
| Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } } })
|
is
属性还可以使用Mustache胡子语法,动态引入需要的模板
小程序内置插件启用
1.旧项目
在 project.config.json 文件中,修改 setting 下的 useCompilerPlugins 字段为 [“typescript”],即可开启工具内置的 typescript 编译插件。 如需同时开启 less 编译插件,可将该字段修改为 [“typescript”, “less”]。 目前支持三个编译插件:typescript、less、sass
2.新建项目
可在创建小程序项目时,选择对应的语言模板。 目前支持的语言模板有
- TypeScript
- TypeScript + Less
- TypeScript + Sass
小程序插件的大小是会算进小程序代码包2M体积限制中的,所以如果遇到插件包过大,可以考虑引用较低版本的插件,当然得考虑兼容性;
所以插件尽量放到分包中
加密数据传输用CryptoJS
弱网体验优化(弱网情况下直接返回缓存的数据)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| App({ onLaunch() { const cacheManager = wx.createCacheManager({ origin: `api域名`, }) cacheManager.addRules([ '/cgi/home', '/cgi/detail/:id', ]) cacheManager.on('enterWeakNetwork', () => { console.log('enterWeakNetwork') }) cacheManager.on('exitWeakNetwork', () => { console.log('exitWeakNetwork') }) cacheManager.on('request', evt => { return new Promise((resolve, reject) => { const matchRes = cacheManager.match(evt) if (matchRes) { resolve(matchRes.data || null) } else { reject({errMsg: `catch not found: ${evt.url}`}) } }) }) } })
|
swiper设置current属性失效
如果有手动滑动过swiper,再设置current就不生效了,因为触发onchange事件没有同步current
1 2 3 4 5 6 7
| <swiper class="swiper" current="{{currentIndex}}" bindchange="changeSwiper"> changeSwiper(e) { this.setData({ currentIndex: e.detail.current }) },
|