Weex 开发 [Weex]
前几天看知乎,Evan You
叫 Weex
作 Vue-Native
😊
本文主要学习如何使用 Weex
常用组件进行开发工作,再根据开发过程中遇到的问题,完善补充。
Tips
不支持相对单位
em
,rem
等,只能使用px
;不支持
css
组合写法,只能设置一个属性值,如border: 1 solid red;
<image>
在ios
平台border
不支持设置不同的radius
;不支持百分比
根布局必须是
<div>
、<scroller>
事件最好定义成有意义的形式,不然有时会出问题,例如
@change="change"
监听change
事件没问题,但是@scroll="scroll"
就会出现监听不到的问题。标签属性一定要写成标签属性的形式
porperty=value
,不能用css
属性代替,有些属性在Android
上面支持,但是在ios
那边不支持。当不是根元素的
div
嵌套列表时,比如list
,列表在ios
上无法显示出来,要显式的指定div
的高度,有点类似两个可滑动的组件套在一起,无法测量高度的情况。使用
:style
支持动态设置多个属性时,如果值带有单位,则一定要使用''
包含,中间以逗号分隔,如:style="{width:'750px',color:red,height:height+'px'}"
盒模型
Weex
盒模型的 box-sizing
默认为 border-box
,即盒子的宽高包含内容、内边距和边框的宽度,不包含外边距的宽度。
width/height - 指的是 content + padding + border
部分的尺寸
1 | .frame{ |
padding - 内边距,content
和 border
之间的距离
1 | .frame{ |
margin - 外边距,元素与元素之间的距离
1 | .frame{ |
border - 边框
1 | .frame{ |
FlexBox
flexbox
是 CSS3.0
新的布局模式,Weex
对它进行了部分的支持。
flexbox
是唯一的默认的布局模式,不需要指定 display: flex;
,默认所有的容器类元素都是 flex
容器。
布局方向
1 | .frame{ |
主轴方向元素的排列
1 | .frame{ |
侧轴方向元素的排列。
1 | .frame{ |
flex 成员项
flex
属性定义了 flex
成员项可以占用容器中剩余空间的大小。如果所有的成员项设置相同的值 flex: 1
,它们将平均分配剩余空间. 如果一个成员项设置的值为 flex: 2
,其它的成员项设置的值为 flex: 1
,那么这个成员项所占用的剩余空间是其它成员项的 2 倍。
1 | .frame{ |
pseudo
主要支持 active
,focus
,enabled
,disabled
。所有组件支持 active
,只有 input
和 textarea
支持 focus
。
在客户端中,active
表示组件被按压时的状态,focus
表示组件获取到焦点时的状态,enabled
表示可用时的状态,disable
表示不可用时的状态。
在 ios
上,enable
没有效果。
优先级:
1 | active > focus > enable |
div
不可嵌套层级过深,控制在 10 层以内,避免性能问题;
不能在 div
中直接写文字,需要使用 <text>
组件;
即使高度超出范围 div
也不能滑动;
web
不支持 click
和 longpress
事件
标签属性
1 | // 加载的地址 |
事件,event
里面内容很多
1 | // 页面开始加载 |
video
内部只能包含 <text>
标签
标签属性
1 | // 播放地址 |
事件
1 | // 每次开始播放,自动播放或者暂停后播放都会触发 |
switch
标签属性
1 | checked = true // 是否选中 |
文档中提到,下面的样式不能使用,测试发现,width/height
、margin
、border
这些属性都是可以使用的,不过确实有部分属性在 ios
上面没有效果。
1 | width |
事件
1 | // 状态切换时触发 |
A
它是一个容器类的标签,看 Android
这边的源码,是继承自 div
标签,a
和 html
里面的 a 标签差不多,但是不能包含文本,如果要有文本需要使用 <text>
标签。
点击之后会调用一个名为 event
的 module
的 openURL
方法,这个 module
需要我们来注入到 sdk
中,参数就是 href
。
1 | <a class="button" href="http://g.tbcdn.cn/ali-wireless-h5/res/0.0.16/hello.js"> |
image
「image
」标签用来显示图片,必须指定 width
和 height
,否则无法显示,不能包含子组件,
标签属性
1 | // 显示的图片地址 |
事件
1 | // 图片加载成功监听 |
方法
1 | // 将图片保存到本地 |
text + input + textarea
文本样式汇总
1 | .mytext { |
「text-decoration
」,已经支持前后带有空格显示,当带有空格时,如果加了 decoration
,在 android
上面空格的地方也会有装饰,ios
只会在文字的地方有。
「font-family
」,在生命周期方法 beforeCreate
为页面加载一套字体
1 | beforeCreate() { |
text
组件 text
具有 value
属性,用来表示显示的值,当 value
和内容都指定时,将会显示内容的值。
1 | <text class='mytext' value="test1"> test2 </text> |
input
组件 input
标签属性,需要注意的是如果标签中间写了文案,会显示在组件下方。
1 | maxlength = 10 // 可以输入的最长长度 |
伪类
1 | .myinput:active { |
支持的 css
属性
1 | 同样支持 color,font-size,fone-weight,font-style,text-align 属性 |
事件
1 | @input 输入监听,每次输入内容变化,会调 |
方法,为 input
组件设置 ref="input_ref"
1 | var el = this.$refs["input_ref"]; |
textarea
多行文本输入 textarea
和 input
基本类似,
他们俩的差别:
事件上,textarea
不支持 @return
事件
方法上, 均支持
标签属性上,增加了 rows
属性,不支持 return-key-type
,max-length
,type
,支持的属性汇总如下:
1 | rows = 3 // 指定组件的高度,默认2 |
slider + indicator
slider
默认高度会占满屏幕,所以必须为 slider
指定一个高度,而 indicator
也会继承这个高度。
1 | <slider class="slider" interval=3000 auto-play=true infinite=true @change="changePage" @scroll="scrollSlider "> |
slider 标签属性
1 | interval = 3000; // 播放时间间隔 |
slider css 属性
1 | .slider{ |
indicator 常用属性
1 | .indicator{ |
事件
1 | // change 事件,当页面滑动到下一页时触发 |
scroller
对客户端来说是不可复用元素的列表
滑动方向 - 可以垂直或者水平滑动,flex
和 scroll
的方向必须一致。
1 | 两者方向必须一致 |
实现一个 tab 导航
1 | <scroller class="scroller" scroll-direction=horizontal @scroll='scrollerScroll'> |
常用标签属性,同样支持一些列表统一的标签属性 列表标签属性
1 | // 滑动方向,默认 vertical |
支持 loadmore
事件,见 列表 loadmore
支持 scroll
事件,见 列表 scroll
支持 resetLoadmore
,见 列表 resetLoadmore
支持 scrollToElement
,见 列表 scrollToElement
list + waterfall + cell + header
把他们放在一起是因为他们一起完成了一个列表的显示,其实 waterfall
和 list
是一样的, 类似 Android
上面当年的 ListView
和 GridView
,当然现在都已经被 RecyclerView
代替了,他们表现的都是一个 垂直列表,而 waterfall
支持多列的显示,
使用 cell
生成列表的每一项,header
其实是 cell
的子类,它可以在滑动出屏幕时,固定在屏幕顶端,实现悬挂的效果。
列表中只支持 cell
、header
、refresh
、loading
和 使用 fix
定位的组件,其他组件不能正确渲染。
实现一个简单的列表显示,需要格外注意的是,v-for
的语句要写在 cell
上面,这样才能保证生成多个 cell
,开始的时候我写在了 div
上面,其实是在一个 cell
里面生成了多个 div
,这样就无法实现回收和复用。
1 | <list style="height:500px;" @loadmore="loadmorelist"> |
header
这个 header
用起来坑比较多,汇总一下:
- 在
list
里面用header
,默认是一样悬挂效果,就是当header
向上将要被滑出屏幕时会固定在屏幕顶端,但是向下滑出时不会固定在底端。 list
里面header
上面的cell
不能全部使用v-for
生成,如果是的话,对header
没有挤压效果,header
会一直在顶部,就好像v-for
生成的那些cell
没有压在header
上面,但是一旦有一个不是v-for
生成的,就好了,这应该是个bug;waterfall
里面使用header
时,默认是没有悬挂效果的,会像普通的cell
一样跟着整个列表一起走,这样可以实现单列和多列并存的效果。- 如果希望
waterfall
里面有悬挂效果,要对header
设置position:sticky;
,使用这个属性,他不会滑出屏幕,不管上面还是下面都会挂住。 - 在
list
中使用sticky
没什么效果,在waterfall
中一方面可以使用sticky
对header
做悬挂效果,另一方面cell
如果设置了sticky
会变成跨越正行,类似header
使用 header
标签实现悬挂效果
<header/>
标签是 list
可以渲染的标签之一,当 header
到达顶部时,会吸附在屏幕顶部,<header/>
不一定要在顶部,可以在列表的任何位置,当这一项,被滑动到顶端时,会吸附在顶部,不会划出屏幕。
ps:同样的效果,如果在 cell
上面使用 position:fixed;
在 Android
可以正确显示,但是在 ios
没有任何效果
使用方法很简单,只需要将某一项使用 <header>
包含即可。
1 | <list> |
waterfall
👮如果是一个 list
套在 div
里面显示没问题,但是如果是 waterfall
就不行,看到有报错说无法解析 auto
,当然设置成固定值也不行,解决方案是给 waterfall
一个固定的宽度,让他可以计算,就没问题了。
瀑布流 waterfall
支持多列显示,因此相比 list
多了一些属性,但是 list
的属性和事件他也是支持的。
「waterfall
」 特有属性,column-width
和 column-count
不能同时指定为 auto
无法计算将无法显示。
1 | 当某个属性指定为 auto 时,会使用下面的约束来计算 auto 对应的值。 |
common
「waterfall
和 list
」 常用属性 - 支持列表统一的标签属性 列表标签属性
「waterfall
和 list
」 支持 loadmore
事件,见 列表 loadmore
「waterfall
和 list
」 支持 scroll
事件,见 列表 scroll
「waterfall
和 list
」 支持 resetLoadmore
,见 列表 resetLoadmore
「waterfall
和 list
」 支持 scrollToElement
,见 列表 scrollToElement
列表
在 weex 指的就是 scroller 和 list 了,这里汇总一些公共的属性和方法,方便管理和对比。
类似 scroller
和 list
都属于列表,他们有一些通用的属性和方法,提取出来统一介绍,⚠️ 不允许相同方向的列表互相嵌套
列表标签属性
1 | // 屏幕底部到页面底部的距离,用来触发 loadmore,默认 0 |
列表事件
1 | @loadmore 加载更多事件,横向滑动时,`loadmore` 不能触发 |
方法
resetLoadmore(node,options)
重置 loadmore
,如果进行过一次 loadmore
之后,列表内容没有发生变更,则再次滑动到末尾时,不会触发 loadmore
事件,需要使用 resetLoadmore()
来重置状态。
1 | scroller.resetLoadmore(node,options) |
scrollToElement(node,options)
使得列表滑动到指定的 node,需要使用 dom module
来操作
ps:使用过程中发现 waterfall
组件的 scrollToElement
在 andorid
上是将指定项滚动到屏幕底部,ios
是滚动到顶部,list
和 scroller
正常,都是到顶部。
1 | scrollToElement(node,options) |
示例,对一个横向列表进行操作,使得点击的那个子元素自动滑动到居中显示
1 | <scroller class="scroller" scroll-direction='horizontal'> |
在 click
事件中,滑动 scroller
由于我每一个子项的宽度设置为了 150px
,而 weex
默认屏幕是 750px
,一次屏幕内正好可以放置 5 个子项,距离左边 300px
即可居中。
1 | changeTab(index){ |
refresh + loading
使用 refresh
和 loading
实现加载数据的效果,refresh
是下拉刷新数据,loading
是上拉加载更多数据,他们只有在被 list
和 scroller
包含时才能正确渲染,接下来将会以 list
为例简单学习一下使用方法,在 scroller
是一样的。在用法上,refresh
和 loading
也基本相同,只是显示的位置不同和一些事件名字不同。
「diaplay
」属性来决定组件的展示和隐藏,display
值为 show
或 hide
。仅隐藏 <indicator>
,<loading>
其他子组件依然可见,loading
事件仍会被触发,因此我们要实现刷新的效果需要动态的修改 display
的值。
1 | <refresh :display="isRefreshing?'show':'hide'"></refresh> |
「<loading-indicator>
」 是内置一个组件,显示是一个带动画效果的圆形进度条,就是系统默认的加载动画,需要注意的是宽高必须指定,不然默认是0无法显示,可以使用 color
属性来更改进度条的颜色。
1 | <loading-indicator style='color:red;width:40px;height:40px;'></loading-indicator> |
事件,<refresh>
有 @refresh
事件,<loading>
有 @loading
事件,他们都会在滑动距离超过整个组件的高度时被触发,可以在这里面做加载数据的操作。
另外 <refresh>
还有一个自己的事件,@pullingdown
事件会返回组件滑动过程中的一些数据,不过这个监听在 andorid
和 ios
上面的数据差别比较大。
1 | event => |
完整的带有刷新和加载功能的代码
1 | <list> |
默认 isFreshing
和 isLoading
自然都是 false
,当刷新时,更改组件的状态为显示,开始加载数据,并且延时 1s 后将组件隐藏。
1 | refreshList(){ |
config
文档说明使用 weex.config
获取,但是测试发现不行,需要使用 this.$getConfig()
获取到,调查发现 weex.config
需要 weex
版本 >=0.9.5
才可以,而我使用官方的 playground
版本是 0.9.4
。
默认以宽度为 750px
做适配渲染,要获得 750px
下的屏幕高度,可以通过 height = 750/deviceWidth*deviceHeight
公式获得,可以使用到 CSS
中,用来设置全屏尺寸。
数据结构:
1 | config |
目前维护的几个项目,求 ✨✨✨✨
- SocialSdk 登录分享功能原生接入
- LightAdapter 轻量级适配器
- ImageEditor 图片处理,裁剪旋转,贴纸涂鸦,滤镜等
- WeexCube Weex 容器方案
- Kotlin 学习系列总结,共计 22 篇
- 本文链接: http://cdevlab.top/article/41ed2d2f/
- 版权声明: 版权所有,转载请注明出处!