小程序云开发之始末

前言

一直都不喜欢微信,所以关于小程序的开发也是没怎么上心。只是在浏览招聘网站时,发现小程序已经成为前端开发人员的一个基本技能了。所以,只能硬着头皮尝试着学习开发小程序。

在学习小程序开发时,倒是没觉得有什么阻碍,毕竟前端的最流行的框架已经流行了那么多年了,从某些方面,它们是相似的。本次所开发的功能很简单,但是就整个流程来说却是很漫长的,由于是从零开始开发,所以大部分时间还是花在了产品的构思上和小程序一些奇奇怪怪的问题上。而且,这次的开发只完成了产品预想的 50% 左右,核心的部分基本没有去做。最大的原因可能就是开发体验不好,浪费时间。

小程序云开发

对于个人开发人员来说,小程序云开发降低了开发门槛,尤其是前端人员的门槛。基于云开发,前端人员可以完成从前端到后台的所有任务。小程序云平台有着 Node环境,所以我们可以把它想象成基于 node 的后台环境。
以爬虫为例,首先在 cloudfunctions 文件夹下创建文件夹 crawler,在该文件夹下面在创建创建相应 crawler.jspackage.json 文件,剩下就可以写些逻辑了。

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
30
31
32
33
34
35
36
37
38
39
40
41
// 云函数入口文件
const cloud = require('wx-server-sdk')
const Crawler = require("crawler");
cloud.init()
const uriArray = [{ uri: 'http://www.nows.fun/', selector: '#sentence' },
{ uri: 'https://www.nihaowua.com/', selector: 'body > div > section > div' },
{ uri: 'https://www.nihaowua.com/home.html', selector: 'body > div > section > div' }];

let crawler = new Crawler();
let canClick = true;

const crawlerWebPage = () => {
if (!canClick) return false;
canClick = false;
let index = Math.floor(Math.random() * 3);
let { uri, selector } = uriArray[index];
return new Promise((resolve, reject) => {
crawler.direct({
uri: uri,
retries: 0,
timeout: 5000,
skipEventRequest: false,
callback: function (error, response) {
canClick = true;
if (error) {
console.log(error)
} else {
var $ = response.$;
var content = $(selector).text();
console.log('index', index)
resolve(content);
}
}
})
})
};

exports.main = async (event, content) => {
const result = await crawlerWebPage();
return result;
}

云函数创建好了,剩下的就是在小程序中去调用了。

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
refresh: function (obj) {
if (!this.data.canClick) return;
this.setData({
canClick: false
})
wx.showLoading({
title: '加载中',
})
wx.cloud.callFunction({
name: "crawler",
success: res => {
wx.hideLoading();
this.setData({
soup: res.result,
canClick: true
})
},
fail: err => {
wx.hideLoading();
this.setData({
soup: "鸡汤要一口一口喝,你太急啦",
canClick: true
})
console.error('[云函数] [crawler] templateMessage.send 调用失败:', err)
}
})
}

小程序中的组件

刚开始接触小程序时,给我的感觉像是在开发一个多页面应用。在开发构思的过程中,需要写的逻辑越来越多。于是就想着把这么多的东西拆开,翻了下文档,发现小程序提到自定义组件比较适合。
首先在父组件中配置文件中配置子组件路径,然后自组件也要配置。

1
2
3
4
5
6
7
8
9
10
11
12
// father.json
{
"usingComponents": {
"type-year": "../../component/type-year/type-year",
"type-month": "../../component/type-month/type-month",
"type-date": "../../component/type-date/type-date"
}
}
// children.json
{
"component": true
}

剩下的就和 React、Vue 中的自定义组件差不多。

以上也只是自定义组件,平时还会接触到第三方的组件,比如常用的 UI 组件。通常第三方组件都是使用 npm 包,但是小程序的环境比较特殊,它不是 Node 环境,所以基于 Node 环境的 npm 包也要特殊处理才能够在小程序只能够使用。尽管小程序官方提供了 npm 包转换的方案,但是依然会有很多包不能在小程序中使用,具体可见官方小程序开发文档。

小程序中操作节点

小程序的渲染层和逻辑层分别由2个线程管理,这和浏览器的环境是不一样的,所以要想操作节点需要使用小程序提供的API,不过在跨组件获取节点时,需要注意一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
onLoad: function () {
let height = {};
let yearChartHeight,monthChartHeight,componentHeight;
let query = wx.createSelectorQuery().in(this); // Note: 操作节点
query.selectAll('#little_target, #target_type, #target_content').boundingClientRect(
res => {
res.map(item => {
height[`${item.id}_height`] = item.height;
})
yearChartHeight = height.little_target_height - height.target_content_height - height.target_type_height;

componentHeight = monthChartHeight = height.little_target_height - height.target_type_height - 48;
this.setData({
yearHeight: yearChartHeight,
monthHeight: monthChartHeight
})
}
).exec();
}

上面代码就是通过相关的 API 获取三个节点的数据。

小程序中使用 echarts

对比了 F2 和 echarts, 发现 echarts 提供的图表更多一些。这两个图表库的使用的方式也不同,F2 是 npm 包,需要转换导入使用。echarts 使用起来就相对简单一些,和上面提到的自定义组件一样,而且 echarts 还可以自定义选择需要图表导出,这样就减小包的体积。
在使用这些图表库时,才明白什么叫做调參工程师,在开发的过程中真的是边看文档边调整参数。在使用 echarts 的过程中,本以为canvas 可以撑开盒子,结果发现需要父元素需要有高度,这也是为什么上面动态计算盒子高度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- init 1 -->
<view class="chart_wrap" style="height:{{chartHeight}}px">
<ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
</view>
<!--
data: {
ec: { onInit: initChart }
},
-->

<!-- init 2-->
<view class="chart_wrap" style="height:{{chartHeight}}px">
<ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}" bind:init="echartInit"></ec-canvas>
</view>

在使用的过程中发现,初始化的方式并不惟一,结果也是不一样,这个需要注意一下。

小程序的开发体验

小程序的开发工具真心不怎么样,从日常 chrome 开发者工具再到小程序的开发者工具,这其中的差距还是很大。而且,我们不能方便随意地使用 npm 包,这在小程序中限制很明显。
反正问题很多。



miniprograming

over!

------------- The End -------------
显示评论