Weex布局尺寸通用适配方案的研究

简介: ## 问题 weex为前端赋予了强大的跨端开发能力和较一致的良好的用户体验。weex一般是与native进行协作开发: 1. 同app内不同页面用两者分别开发,统一串联 2. 同页面两者协作开发,比如native提供组件,weex使用 由于native布局一般采用定高不定宽的方式,以求不同尺寸的屏幕可以得到基本一致的布局体验,然而weex布局采用基于750的等比例缩放,这种不

问题

weex为前端赋予了强大的跨端开发能力和较一致的良好的用户体验。weex一般是与native进行协作开发:

  1. 同app内不同页面用两者分别开发,统一串联
  2. 同页面两者协作开发,比如native提供组件,weex使用

由于native布局一般采用定高不定宽的方式,以求不同尺寸的屏幕可以得到基本一致的布局体验,然而weex布局采用基于750的等比例缩放,这种不一致导致的问题:

  1. 同一元素在不同屏幕的尺寸展现不一致,大屏手机尺寸偏大,小屏手机尺寸偏小
  2. 与native尺寸偏差较多

字号的差异也比较明显。

默认依据ip6尺寸布局,惨不忍睹的现场直击...

  • 红框部分的滑动组件是native的,而背景容器是weex布局的,由于weex等比例缩放,而native使用pt,导致iphone 5s native组件溢出,而iphone 6p组件相比于容器过小。

数据流图

  • 下面是iphone 6p下native列表和weex列表字号对比

思考及分析

weex目前的尺寸处理方式:

无视屏幕分辨率和尺寸,虚拟宽度统一为750,布局尺寸以750为基准按比例缩放。

那么使用weex原生尺寸定义想实现native的体验“在不同尺寸手机上同样元素的尺寸基本一致”是不太可能的。

不过weex在Js运行时提供了屏幕的物理分辨率和像素比例,那么运行时可不可以用js动态算一下呢?

我们定义weex的原生尺寸为vp(virtual pixel),视觉稿的尺寸或native的尺寸为ns(native size)。

期待的转换规则为

vp = translateRule(dp)

这样用户只需要按native的方式写布局尺寸,就可以映射为weex的尺寸,被weex布局逻辑动态解析,从而达到我们的目的。

既然我们要模拟Native的尺寸适配,首先要知己知彼,简单了解了一下native的适配方法

安卓尺寸适配

安卓提供了一个万能的适配单位:dp,dp屏蔽了屏幕大小和分辨率,提供了一致体验,dp和物理像素的换算关系如下:

dp = px / (dpi / 160)

欲转换先取dpi,可惜weex没有dpi,但提供了一个比例scale,可用来计算dpi

scale = dpi / 160

换算可得

vp = dp * 750 / ( deviceWidth / scale )

IOS尺寸适配

类似dp的单位是着色器(似乎等同于pt?)

pt = px / scale

换算可得

vp = pt * 750 / ( deviceWidth / scale )

通过分析我们发现,安卓和IOS的适配规则殊途同归,可统一转换规则为:

    function translateRule(dp) {
        return dp * 750 / ( deviceWidth / scale );
    }

到这里似乎大功告成,只要在写样式时祭出我们的法宝:计算属性,并动态赋到模板节点的style属性上即可。然而这种方式让开发同学想起了前端茹毛饮血的上古时代,而今前端显然已经沐浴在现代化的春风里很久了。如果在写样式的时候需要写固定尺寸时,能像native一样直接写pt/dp这样的单位那肯定是极好的。

扫了一下经过weex-loader编译的代码,与vue-loader编译的区别主要是在style的处理上,前者将style编译为map形式,并挂载到Vue实例上,所以我们在两个位置可以拿到编译后的style map

  1. vue实例生命周期内
  2. vue导出的组件对象上

由此有两个插入自动处理尺寸逻辑的方案:

  1. 运行时。于上述2的位置,扫描vue实例的style map,过滤出自定义单位和值并替换为weex识别的尺寸
  2. 编译时。通过webpack loader对vue文件进行预处理,扫描自定义单位并于1位置注入运行时处理尺寸的逻辑

分析

方案一:

  1. 性能较差,需要遍历每个页面整个组件树的style map
  2. vue实例拿到的style map,已被weex-loader过滤掉自定义单位,变成了人畜无害的数字。。。
  3. 需要js代码处理,一看就不是weex的亲儿子单位

结论:放弃

方案二:

  1. 每个组件单独注入修改尺寸的代码,免去了遍历组件树的开销
  2. 在weex-loader的样式分析之前解析,可以拿到原始样式代码
  3. 纯编译时纯工具处理,使用自定义单位如同使用原生单位一样方便,weex开发者毫无感知

结论:靠谱

实现

主流程

  • 识别style里的自定义单位/函数,抽取单位前的数值
  • 根据规则生成尺寸处理逻辑的代码
  • 注入到vue实例的beforeCreate函数里

    样式识别支持less和css

单位一般用于单参数映射规则,多参数映射规则可写成函数

规则文件

基于以下原因,需要独立的、用户自定义的、vue实例里可以方便引用的规则文件

  • 可能需要多个单位,因此需要一个规则集合
  • 规则需要支持自定义,方便使用者修改和扩展
  • 用户可能也需要手动调用某个单位的计算规则,比如实现动画

    loader实现内部提供了一个默认的规则文件,支持用户自定义规则文件去覆盖和扩展默认规则

默认规则

单位/函数 描述
dp 模拟安卓dp单位, 兼容ios,与native布局尺寸相同
mq media query
vw 相对于屏幕宽度的百分比
vh 相对于屏幕高度的百分比



数据流图如下:

数据流图

效果

无痛使用

    .class-name {
        /*
            自定义单位/处理函数dp, vw
            多个参数可用函数形式,单参数建议用单位
        */
        width: 100dp;
        height: 200vw;
        font-size: dp(24, 750); //可直接用24dp,这里仅做例子
    }

UI效果

  • 不同尺寸屏幕native组件和weex容器完美契合(贴图不是实际屏幕大小,所以5s布局尺寸看着比较大,仅做页面内native和weex的尺寸比较)

  • weex与native文字尺寸基本一致(由于weex安卓使用小数字号有问题,所以计算后的字号做了四舍五入取整,且字体也差异,所以效果还是稍微有点差异,但对比做适配前已经好很多了)

扩展

因为实现原理是编译时解析自定义样式函数,并插入运行时js代码。因此除了用于计算尺寸外,还可以计算其他依赖环境(比如屏幕尺寸、设备类型等)的样式,成为一个通用的weex css运行时处理工具。

当然更期待着weex原生支持各种布局单位,这才是康庄大道。

包地址:http://web.npm.alibaba-inc.com/package/@ali/weex-css-runtime-loader

目录
相关文章
|
移动开发 weex JavaScript
深度揭秘阿里移动端高性能动态化方案Weex
阿里巴巴前端开发专家赵锦江和技术专家徐凯对Weex进行了深入的解析。以下为演讲速记整理后的成文。
793 0
|
移动开发 weex 双11
Weex动态化方案与双十一实践
在2017年1月12日 Weex Conf 2017上,来自手机淘宝移动平台Weex团队的凝砺结合淘宝实际业务分享了Weex动态化方案和双十一实践,本文先介绍了Weex的整体架构,接着重点分享了Weex在双十一会场上的实践,最后谈及了Weex的业务支撑,包括AliWeex等。
10241 0
|
移动开发 前端开发 JavaScript
|
6月前
|
移动开发 前端开发 JavaScript
探究移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动端混合开发技术在移动应用开发领域日益流行,为开发者提供了更高效的跨平台开发方案。本文将比较三种主流混合开发技术:React Native、Weex和Flutter,从性能、生态系统和开发体验等方面进行评估,以帮助开发者在选择适合自己项目的技术时做出明智的决策。
406 2
|
6月前
|
移动开发 前端开发 weex
移动端混合开发技术:React Native、Weex、Flutter 之争
在移动应用开发领域,React Native、Weex 和 Flutter 是备受关注的混合开发技术。本文将对它们进行全面比较与评估,以帮助开发者做出明智的选择。我们将从开发生态、性能、跨平台能力和易用性等方面进行比较,为读者提供全面的参考和指导。
|
6月前
|
移动开发 Dart 前端开发
移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动应用的开发已经成为现代社会中的重要一环。本文将比较并评估三种主流的移动端混合开发技术:React Native、Weex和Flutter。通过对它们的特点、优势和劣势的分析,帮助开发者在选择适合自己项目的技术方案时做出明智的决策。
|
6月前
|
移动开发 开发框架 前端开发
移动端混合开发技术探析:React Native、Weex、Flutter的比较与选择
随着移动应用开发的高速发展,混合开发技术成为了一种备受关注的选择。本文将对移动端混合开发技术中的React Native、Weex和Flutter进行比较与探讨,分析它们在性能、开发体验、生态系统和跨平台支持等方面的差异,以及如何根据项目需求进行选择。
217 1
|
移动开发 JSON JavaScript
weex开发 - VS Code解除格式警告
weex开发 - VS Code解除格式警告
118 0
weex开发 - VS Code解除格式警告
|
移动开发 JavaScript weex
weex开发- 无法找到模块“weex-vue-render”的声明文件。引入vue报错,无法找到引入的vue模块
weex开发- 无法找到模块“weex-vue-render”的声明文件。引入vue报错,无法找到引入的vue模块
307 0
weex开发- 无法找到模块“weex-vue-render”的声明文件。引入vue报错,无法找到引入的vue模块
|
weex-ui 移动开发 JavaScript
weex开发-使用weex-ui绑定事件源注意事项
weex开发-使用weex-ui绑定事件源注意事项
149 0