历史文章回顾:
最近依然停留小程序的开发之中,原想着很快能完事儿,交工,不料真是计划赶不上变化。
将自己经历的一些问题记录在案,方便后续类似相同需求直接使用“CV 大法”,节省部分开发成本。当然,如果此文某一条正好对屏幕前的你有所帮助,点个小赞赞,我会贼老开心的~
欢迎大家提供更好的解决方案,我毕竟老本行是搞 Android 的,这方面还真不熟练。
1. 如何消除小程序云函数的警告信息?
解决方式:
- 项目根目录下新建 miniprogram 目录(名称随意),随后将除了 project.config.json 和云函数自身之外的所谓文件/文件夹全部放到 miniprogram 目录中;
- 随后在 project.config.json 中配置 miniprogramRoot 目录,部分代码如下所示:
{
"miniprogramRoot": "miniprogram/", // 与刚刚创建的目录名称一一对应即可
}
随后执行编译即可,有可能需要重新打开微信开发者平台。
2. 微信小程序如何绘制简单基础表格?
比较尴尬的是,微信小程序一直没有提供类似 H5 中 table 标签,所以我们直接通过 flex table 属性间接实现表格效果。
下面着手实现如下简单表格,这里为了方便,我直接写死了。
回顾在 H5 中的 table、tr、td,这里先按照 H5 的方式实现静态代码编写:
<view class="table_content">
<text class="table_name">季度汇总表</text>
<view class="table">
<view class="tr">
<view class="td">日期</view>
<view class="td">第一季度</view>
<view class="td">第二季度</view>
<view class="td">第三季度</view>
<view class="td">第四季度</view>
</view>
<view class="tr">
<view class="td">2020-12-12</view>
<view class="td">111</view>
<view class="td">222</view>
<view class="td">333</view>
<view class="td">444</view>
</view>
<view class="tr">
<view class="td">总计</view>
<view class="td">111</view>
<view class="td">222</view>
<view class="td">333</view>
<view class="td">444</view>
</view>
</view>
</view>
随后我们开始编写对应的 CSS:
.table {
display: table;
width: 100%;
box-sizing: border-box;
align-self: center;
}
.tr {
display: table-row;
}
.td {
display: table-cell;
border: 1rpx solid gray;
font-size: 28rpx;
padding: 6rpx;
text-align: center;
vertical-align: middle;
}
而关于如何设置表头以及表尾加粗居中等样式只需要在遍历对应的 Array 时,获取当前 index 并设置对应 class/style 即可。这里拷贝关键代码作为引子:
<view
class="td {{ idx == 0 ? 'font_weight' : '' }} {{ index == 0 ? 'min_width_170' : '' }}"
style="background-color:{{ idx == yachtSailingTime.length - 1 ? 'lightgray' : '' }}"
wx:for="{{ item }}" wx:for-item="regionalNum" wx:key="regionalNum">
{{ regionalNum }}
</view>
3. 微信小程序如何实现水平滑动表格?
很多时候,当我们展示的 cel 较多,或者 cell 名儿较长时,一行肯定就不满足,那么如何实现水平滑动呢?先来看个效果:
其实需要改动的地方有两点:
- 外部采用 scroll-view 包裹;
- 设置 col width 为最大内容宽度即可;
现附上对应静态网页代码:
<view class="table_content" wx:if="{{ yachtSailingTime.length > 1 }}">
<text class="table_name">游艇会出海艘次</text>
<scroll-view scroll-x scroll-with-animation>
<view class="table max_width">
<view wx:for="{{ yachtSailingTime }}" wx:for-index="idx" wx:key="yachtSailingTime" class="tr">
<view class="td {{ idx == 0 ? 'font_weight' : '' }} {{ index == 0 ? 'min_width_170' : '' }}"
style="background-color:{{ idx == yachtSailingTime.length - 1 ? 'lightgray' : '' }}"
wx:for="{{ item }}" wx:for-item="regionalNum" wx:key="regionalNum">
{{ regionalNum }}
</view>
</view>
</view>
</scroll-view>
</view>
而对应部分关键 CSS 样式如下:
.max_width {
width: max-content;
}
4. 微信小程序如何实现跨行表格?
效果如下:
当初这块看的着实让我很蒙圈,这里先把完成后的页面结果关键部分截个图,大家一起来观察下:
关键的重点在于:
- 时间整体为一行,呈现的效果也就是跨行。其实是因为后续的 col 包含多个 col 将此行撑大,间接实现跨行操作。
这里附上关键代码:
<view class="table_content" wx:if="{{ showMonthData}}">
<scroll-view scroll-x scroll-with-animation>
<view class="table max_width">
<view class="tr">
<view class="td font_weight">日期</view>
<view class="td font_weight">俱乐部</view>
<view class="td font_weight">本期数据</view>
<view class="td font_weight">去年同期</view>
<view class="td font_weight">同比增长</view>
</view>
<view wx:for="{{ monthData }}" wx:for-index="key" wx:for-item="value" class="tr">
<view class="td_span">{{key}}</view>
<view class="td_span" wx:for="{{ value }}" wx:for-item="item">
<view class="td__span" wx:for="{{ item }}" wx:for-item="regionalNum" wx:for-index="idx"
wx:key="regionalNum">
{{ regionalNum }} </view>
</view>
</view>
</view>
</scroll-view>
</view>
以及对应的关键 CSS 代码:
.td_span {
display: table-cell;
border: 1rpx solid gray;
font-size: 28rpx;
text-align: center;
vertical-align: middle;
}
.td__span {
border-bottom: 1rpx solid #333;
padding: 6rpx;
}
5. 原生 canvas 层级过高导致 uCharts 图片重叠怎么处理?
先看下效果:
这块功能主要是报表的一个筛选,用户可以按照日期或者月份进行筛选并查看相关报表以及图标。当首次查询完成之后再次点击选择日期,则会出现上面覆盖的情况。
原因很简单,微信原生 canvas 层级最高,而我们的 uCharts 无法覆盖。对此处理方案目前尝试有三种:
- 方案一:点击弹框弹起/消失时设置图表对应的 position,使其真实位置离开遮罩弹框层下。缺陷是需要对每个遮罩层弹起以及消失做对应的处理,当然也可以直接抽取一个共有方法,直接引用,但是相对成本比较好,后期维护成本较大。当然,如果业务简单,仅仅只有少数遮罩弹框层的小伙伴忽略。毕竟也算是最为粗暴之解。
- 方案二:图表加载完成后,默认转为图片,并获取其临时加载地址,并通过标志符去控制默认显示图表,遮罩弹起替换为图片。同理消失后替换为图表。缺点,需要处理两者直接替换,或者增加对应的动画处理,否则效果上会有很突兀的感觉。相对成本较低。
- 方案三:更新 uCharts 版本,使用 2d 模式即可。优势则是无需处理方案一二那些繁琐的逻辑。
这里由于时间关系,不在录制对应的效果。解决方式讲清楚了,相信各位小伙伴分分钟就可以解决了,稍后也会附上对应的关键代码。
5.1 方案二:替换图片法
首先编写 html 代码部分:
<canvas hidden="{{ isImageShow }}" canvas-id="regionalSailingTimeHistogram" id="regionalSailingTimeHistogram" class="charts"/>
<image class="charts" hidden="{{ !isImageShow }}" src="{{ imageSrc }}"/>
在图表渲染完成后,将图表转为临时图片,并拿到临时加载地址:
wx.canvasToTempFilePath({
canvasId: 'regionalSailingTimeHistogram',
success: (res) => {
let tempFilePath = res.tempFilePath;
that.setData({
imageSrc: tempFilePath
});
console.log('---> canvasToTempFilePath', tempFilePath);
}
}, that);
在对应遮罩层打开将 image 状态符设置为 true,同理关闭时设置为 false:
openCalendar() {
console.log('----> openCalendar');
let that = this;
that.setData({
isImageShow: true
});
},
closedCalendar() {
console.log('----> closedCalendar');
let that = this;
that.setData({
isImageShow: false
});
},
如果业务遮罩弹框较多时,建议直接抽取方法,根据不同 type 统一处理即可。
5.2 方案三:升级 uCharts 版本并使用 2d 版本
直接找到最新版本,复制对应的 uCharts 并替换即可实现无缝升级,😂
<canvas type="2d" canvas-id="canvasLineB" id="canvasLineB" class="charts"/>
对应 css 文件如下:
.charts {
width: 100%;
height: 500rpx;
background-color: #FFFFFF;
margin: 30rpx 0;
}
关键 js 代码如下:
const query = wx.createSelectorQuery()
query.select('#canvasLineB')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
regionalTripsSeaHistogram = new uCharts({
//这俩参数是新增加的,开启2d并传入ctx
canvas2d: true,
context: ctx,
canvasId: canvasId,
type: 'column',
legend: true,
fontSize: 11,
background: '#FFFFFF',
pixelRatio: 1,
animation: true,
categories: chartData.categories,
series: chartData.series,
enableScroll: true,
xAxis: {
disableGrid: true,
itemCount: 5,
scrollShow: true,
},
dataLabel: false,
width: this.cWidth,
height: this.cHeight,
extra: {
column: {
type: 'stack',
width: this.cWidth * 0.45 / 5,
}
}
});
})
6. 如何解决云函数调用失败,errCode: -404011
我遇到这个问题主要是测试环境迁移正式环境时发生。
问题原因,因为存在多个云环境,至少目前我这边一个测试环境,一个正式环境,而且在 app.js 中未指明具体某个环境,所以导致找不到,云函数执行失败。
解决方案:
打开云开发管理平台,找到正式环境对应的环境 ID,拷贝下来:
在 app.js 初始化环境时设置对应的环境 ID,如下所示:
wx.cloud.init({
env: '对应的环境 ID', // 正式环境
traceUser: true,
})
最后最好清楚全部缓存,重新编译下,就好啦。
7. 关于云函数初始化
上面第六条讲过,在云函数初始化时,需要设置对应的 env 也就是环境 ID,不难理解,你总的告诉人家你要基于哪儿个环境进行操作吧。
但是这样写的话,会有一点不太好。假如你有多个环境呢?难道我每次切换环境都需要调整一次云函数初始化吗?那不得累死人。
查看官网,发现如下说明:
截取官方部分介绍:
标志当前所在环境,注意该值不是当前所在环境 ID 的字符串,其值等价于 Symbol.for('DYNAMIC_CURRENT_ENV'),是用于标志当前所在环境的。如在 init 中如果给 env 参数传该常量值,则后续的 API 请求会自动请求当前所在环境的云资源,如云函数 A 当前所在环境是 test-123,则其接下来请求数据库、文件存储、云函数时都默认请求环境 test-123 的数据库、文件存储、云函数。
常量可用于:
- cloud.init 的 env 参数
- cloud.updateConfig 的 env 参数
- 各 API 的 config 参数中的 env 参数
也就是说,针对上面的疑问,我们只需要将云函数中的初始化调整如下:
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
便能自动根据当前已选择的环境进行访问、处理了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。