记录一下小程序开发工作中遇到的问题,想到什么记什么
1、换行
只有在<text></text>
里才支持回车符换行,<view></view>
里面不支持。
2、动态头部
在自定义界面自定义的头部在下滑的时候会划走,需要自定义一个固定在头部的头部,直接显示不太好,加了点动画,记录一下代码
需要根据滚动做判断,所以需要把页面的代码都放到scroll-view
里面,scroll-view
做父级元素包裹所有代码。
<view>
<scroll-view bindscroll="scroll" scroll-y class="scrollBox" scroll-top="{{scrollTop}}">
<!-- 其他HTML代码 -->
</scroll-view>
</view>
样式,scroll-view
需要使用屏幕高度。
.scrollBox{
height: calc(100vh - 120rpx);
width: 100%;
}
js里面需要判断任务栏的高度,和做判断,加动画
Page({
data: {
h: 0, // height
scrollTop: 0,
opacity:0,
animationOpacity: null, //动画实例
},
onShow: function () {
let h = app.globalData.navHeight;
let top = this.data.top;
if (top > 50) {
this.setData({ opacity: 1 });
} else {
this.setData({ opacity: 0 });
}
this.setData({ h: h });
},
// 滚动
scroll(e) {
var top = e.detail.scrollTop;
this.setData({ top: top });
if (e.detail.scrollTop > 20) {
var animation = wx.createAnimation({
duration: 650,
timingFunction: 'ease-in'
})
animation.opacity(1).step();
this.setData({ animationOpacity: animation.export() });
} else {
var animation = wx.createAnimation({
duration: 650,
timingFunction: 'ease-out'
})
animation.opacity(0).step();
this.setData({ animationOpacity: animation.export() });
}
},
})
3、骨架屏
项目需要加骨架屏,自己动手实现了一个。
html代码
<view wx:if="{{!isSkeleton}}">
<!-- 其他加载完显示的业务代码 -->
</view>
<!-- 骨架屏 -->
<view wx:if="{{isSkeleton}}" class="skeleton">
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
<view>
<view class="text1 {{isSkeleton ? 'animation' : ''}}"></view>
<view class="content1 {{isSkeleton ? 'animation' : ''}}"></view>
</view>
</view>
样式及动画
/* 引入app.wxss,抽离了公共样式 */
@import '/app.wxss';
/* 每个页面的样式 */
.skeleton{
width: 100%;
padding: 40rpx;
box-sizing: border-box;
}
.text1{
width: 45%;
height: 40rpx;
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 25%, hsla(0,0%,73%,0.23) 37%,hsla(0,0%,74.5%,.2) 63%);
}
.content1{
width: 100%;
height: 150rpx;
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 25%, hsla(0,0%,73%,0.23) 37%,hsla(0,0%,74.5%,.2) 63%);
margin: 40rpx 0;
}
/* 动画实现的css,抽离到app.js里面了 */
@keyframes mymove{
from {
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 25%, hsla(0,0%,73%,0.23) 37%,hsla(0,0%,74.5%,.2) 63%);
}
5%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 30%, hsla(0,0%,73%,0.23) 42%, hsla(0,0%,74.5%,.2) 68%);
}
10%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 35%, hsla(0,0%,73%,0.23) 47%, hsla(0,0%,74.5%,.2) 73%);
}
15%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 40%, hsla(0,0%,73%,0.23) 52%, hsla(0,0%,74.5%,.2) 78%);
}
20%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 45%,hsla(0,0%,73%,0.23) 57%, hsla(0,0%,74.5%,.2) 83%);
}
25%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 50%,hsla(0,0%,73%,0.23) 62%, hsla(0,0%,74.5%,.2) 88%);
}
30%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 55%,hsla(0,0%,73%,0.23) 67%, hsla(0,0%,74.5%,.2) 93%);
}
35%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 60%,hsla(0,0%,73%,0.23) 72%, hsla(0,0%,74.5%,.2) 98%);
}
40%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 3%,hsla(0,0%,74.5%,.2) 65%,hsla(0,0%,73%,0.23) 77%);
}
45%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 8%,hsla(0,0%,74.5%,.2) 70%,hsla(0,0%,73%,0.23) 82%);
}
50%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 13%,hsla(0,0%,74.5%,.2) 75%,hsla(0,0%,73%,0.23) 87%);
}
55%{
background-image: linear-gradient(90deg, hsla(0,0%,74.5%,.2) 18%,hsla(0,0%,74.5%,.2) 80%,hsla(0,0%,73%,0.23) 92%);
}
60%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 23%, hsla(0,0%,74.5%,.2) 85%,hsla(0,0%,73%,0.23) 97%);
}
65%{
background-image: linear-gradient(90deg,hsla(0,0%,73%,0.23) 2%, hsla(0,0%,74.5%,.2) 28%, hsla(0,0%,74.5%,.2) 90%);
}
70%{
background-image: linear-gradient(90deg,hsla(0,0%,73%,0.23) 7%, hsla(0,0%,74.5%,.2) 33%), hsla(0,0%,74.5%,.2) 95%;
}
75%{
background-image: linear-gradient(90deg,hsla(0,0%,73%,0.23) 12%, hsla(0,0%,74.5%,.2) 38%), hsla(0,0%,74.5%,.2) 5%;
}
80%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 5%,hsla(0,0%,73%,0.23) 17%, hsla(0,0%,74.5%,.2) 43%);
}
85%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 10%,hsla(0,0%,73%,0.23) 22%, hsla(0,0%,74.5%,.2) 48%);
}
90%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 15%,hsla(0,0%,73%,0.23) 27%, hsla(0,0%,74.5%,.2) 53%);
}
95%{
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 20%,hsla(0,0%,73%,0.23) 32%, hsla(0,0%,74.5%,.2) 58%);
}
to {
background-image: linear-gradient(90deg,hsla(0,0%,74.5%,.2) 25%,hsla(0,0%,73%,0.23) 37%, hsla(0,0%,74.5%,.2) 63%);
}
}
.animation{
animation:mymove 1.5s infinite;
-webkit-animation:mymove 1.5s infinite;
}
js里面根据变量判断是否加载完,在接口里面处理
Page({
data:{
isSkeleton: true
},
onShow: function(){
let that = this;
// 加载页面的数据
wx.request({
url: url,
method: "GET",
header: app.header(),
success: function (res) {
if (app.checkRes(res)) {
// 其他业务逻辑,然后取消骨架屏
that.setData({ isSkeleton: false });
}
}
});
},
})
4、设置导航栏右上角角标
wx.setTabBarBadge({
index: 1,
text: 1
})
wx.hideTabBarRedDot({index:1})
index
是索引。
5、检测版本更新
const updateManager = wx.getUpdateManager()
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
6、获取用户信息
在代码里获取用户信息需要在wx.getUserInfo()
的回调里面
wx.getUserInfo({
success(e) {
var userInfo = e.userInfo;
let data: {
name: userInfo.nickName,
avatar: userInfo.avatarUrl,
gender: userInfo.gender
}
}
})
7、服务号通知
点单类小程序用户下单完成需要推送给用户一条通知,比如取餐码之类的内容,需要先设定模板,模板在小程序后台设置流程:
- 登录小程序后台
- 功能 - 订阅消息
- 选一个模板
设置完后会有一个模板的id,在代码里面传入,当用户点击的时候就会弹出一个授权弹窗,授权完成后想关闭在小程序的右上角设置里面关,关了貌似不会再次弹窗授权弹窗。
wx.requestSubscribeMessage({
tmplIds: ['idxxxxxxx'],
success (res) {
// 业务代码
},
complete (){
// 业务代码,这个功能需要用户同意,也可以拒绝,同意or拒绝都要执行的话放这里
}
})
配置完其他需要后台配合,后台的文档https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/uniform-message/uniformMessage.send.html
8、canvas
小程序的canvas同一个id只能的渲染一次,画一次如果wx:if
隐藏掉,再打开无法再次渲染,小程序官方给出的回答是不工作了。
另外小程序想画二维码可以使用:weapp.qrcode.esm.js
。
9、image
判断图片加载是否成功可以使用onload
<image onload="imgOnload" ></image>
10、用户信息展示
用户信息展示不需要调取获取用户信息的微信接口,直接展示就好了。
<view class="listItem flex between">
<view class="title">头像</view>
<view class="con img"><open-data type="userAvatarUrl"></open-data></view>
</view>
<view class="listItem flex between">
<view class="title">性别</view>
<view class="con"><open-data type="userGender" lang="zh_CN"></open-data></view>
</view>
<view class="listItem flex between">
<view class="title">用户名</view>
<view class="con"><open-data type="userNickName"></open-data></view>
</view>
11、小程序的一些要求
现在小程序的各种规则越来越复杂,开发一些感觉会出问题的需求的时候建议先看看这些规范,没啥问题再开发。
官方文档地址:https://developers.weixin.qq.com/community/develop/article/doc/000a62dc6c8a88125129cdc055bc13