Toffee's Blog

  • 首页

  • 归档

  • 搜索

小程序多端开发框架

发表于 2020-03-23

小程序与web开发区别

小程序由于采用双线程机制,视图层通过一个webview用于页面渲染,但是小程序屏蔽了DOM,BOM接口,自定义了一套组件规范,逻辑层通过jsCore线程负责对代码进行解析,通过setData方法和页面通信,做到渲染和执行分离。
而浏览器端元素显示的基本单位就是DOM元素,所以web代码无法直接运行在小程序端。


小程序运行环境

主流解决方法

静态编译转换(代表 uni-app/taro/rax)

静态编译是目前主流的跨端解决方法,其思路是在构建打包时,将一种结构化语言(框架规定)转换成另一种结构化语言(如小程序wxml)。

这样做的前提是,框架本身实现了一套基础的组件库,同时,为了抹平多端的接口差异,更进一步实现了一套统一api库,用于处理接口请求,数据本地缓存,路由切换等等

运行时兼容(代表 kbone/rax/remax)

kbone通过模拟DOM接口,生成语法树,然后转换成小程序的dom树,最终渲染

如何理解两者,下面看代码,有点SSR和spa渲染的意思在里面

这是源代码

1
2
3
<div>
这是一段话
</div>

静态编译转换:

1
<view>这是一段话</view>

编译时转换

1
2
3
4
5
6
7
8
9
10
11
12
// 先解析语法,生成AST语法树,然后通过 miniprogram-element 模块生成对应的小程序dom树
h = function () {
var e = this,
t = e.$createElement,
n = e._self._c || t
return n('div', { staticClass: 'cnt' }, [
n('Header'),
n('div', [
n('div', [e._v('这是一段话')])]),
e._m(0),
n('Footer')], 1)
}

实际wxml文件,只有一个element空标签,内部的元素都是动态生成出来的

1
2
3
4
<element wx:if="{{pageId}}" class="{{bodyClass}}" style="{{bodyStyle}}" data-private-node-id="e-body" data-private-page-id="{{pageId}}" >
<!--下面是动态生成的 并不在实际的静态文件里 这里只是示例-->
<view>这是一段话</view>
</element>

kbone 体验

缺点

  • 编译速度慢(个人感觉是有点卡,看小程序开发者工具log是每次修改代码都重新执行了npm构建)
  • 原始依赖体积不小
  • 没有统一的api,所以需要判断环境变量,如下面代码

    1
    2
    3
    4
    5
    6
    if (process.env.isMiniprogram) {
    wx.navigateBack() // 这里需要调用微信的后退api
    }
    // 在taro/uni-app 中,都可以用统一api去实现
    uni.navigateBack
    Taro.navigateBack
  • 运行时方案必然会有性能损失

运行时编译优点

  • 支持更为完整的前端框架特性(如v-html 指令,filter特性)
  • 如果已有h5端的代码,那么迁移到小程序端就比较方便
  • 小程序运行时,可以直接使用小程序的特性,如内置组件(辩证看待)
  • 由于是通过在客户端生成wxml相关代码,所以性能肯定是不如静态代码
框架 初始包大小 自研组件库 社区生态(2020/3/24) 跨端范围 状态管理 维护团队
kbone 505kb 无 无 微信小程序,h5 根据选择的DSL框架,可自主选择 微信个人开发者
uni-app 280kb 有 丰富(1389物料) 5大程序,h5,native vuex Dcloud公司
taro 207kb 有 较丰富(89物料) 5大程序,h5,native redux/mobx/dav 京东Auto实验室

background-clip 苹果官网渐变色字体实现

发表于 2020-03-19


阅读全文 »

平滑数组-图表运用

发表于 2020-03-02

起因

最近做了一个页面,都是由图表构成的,UI设计图上的图表一般都比较美观,但是实际做出来的图表观感却一点也不好看,究其原因,是真实数据之间的差异过大,导致使用echarts画出来的图表效果很差,对于不同的图表类型,可以使用特定的方法,比如可配置最小角度,最小宽度等尽量去减小差异,但是我们这里需要绘制的是一个南丁格尔玫瑰图,echarts
的配置项通读下来,发现也没有较好的解决方法,为了解决这一问题,我还尝试了去使用highcharts图表库,但是效果也不是很好。

关于这一问题,网上分成两派,一种是尽量通过某种手段消减数据之间差异过大导致图表不好看的问题
二是认为这就是数据的真实表现,如果采取手段会产生误解问题

解决

在这里,我不去关注图表工具库提供的功能,而是转而去关注数据本身,只要我们的数据是’合理’的,那么绘制出来的图不也是’合理’的了吗?

‘降噪’

如果我的数据源本身就是抖动不大的,那么出来的效果肯定也是观感较好的,那么如何去做呢?

阅读全文 »

使用d3创建地图以及点击实现下钻动效

发表于 2020-01-15

效果预览

点击空白页面后退

主要涉及到的d3 api

由于d3.js的api众多,本文只介绍这次涉及到的api,推荐阅读官方文档,本文使用的是v5版本,相比之前版本api调用发生了较大的变化且增加了promise回调

阅读全文 »

hack localstorage实现过期功能

发表于 2019-12-05

Window.localStorage

只读的’localStorage’属性允许你访问一个’Document’源(origin)的对象’Storage’;存储的数据将保存在浏览器会话中。’localStorage’ 类似 ‘sessionStorage’,但其区别在于:存储在 ‘localStorage’ 的数据可以长期保留;而当页面会话结束——也就是说,当页面被关闭时,存储在 ‘sessionStorage’ 的数据会被清除 。

localStorage用法

1
2
3
4
5
localStorage.setItem('myCat', 'Tom');
localStorage.getItem('myCat');
localStorage.removeItem('myCat');
// 移除所有
localStorage.clear();

hack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function () {
var getItem = localStorage.getItem.bind(localStorage)
var setItem = localStorage.setItem.bind(localStorage)
var removeItem = localStorage.removeItem.bind(localStorage)
localStorage.setItem = function (keyName, keyValue, expires) {
if (typeof expires !== 'undefined') {
var expiresDate = new Date(expires).valueOf()
setItem(keyName + '_expires', expiresDate)
}
return setItem(keyName, keyValue)
}
localStorage.getItem = function (keyName) {
var expires = getItem(keyName + '_expires')
if (expires && new Date() > new Date(Number(expires))) {
removeItem(keyName)
removeItem(keyName + '_expires')
}
return getItem(keyName)
}
})()

原理:
先看localStorage.setItem方法,此方法接收第三个参数expires过期时间,该值为一个时间戳, 并且会同时在缓存中设置一个后缀为_expires的key,value为过期时间。
再看localStorage.getItem方法,先判断是否有取值的后缀名为_expires的值,如果有,再判断当前时间戳是否大于取值的时间戳,如果大于的话,就执行删除removeItem方法,将缓存中的两个值都删除,如果没有取到或者时间未到过期时间,则正常返回值。

123…9
Toffee

Toffee

44 日志
GitHub E-Mail 我的网站 StackOverflow
0%
© 2018 – 2021 Toffee