extend-to-ios

iOS 扩展

Updated time: 04/08/2017

注意

Weex 所有暴露给 JS 的内置 module 或 component API 都是安全和可控的, 它们不会去访问系统的私有 API ,也不会去做任何 runtime 上的 hack 更不会去改变应用原有的功能定位。

如果需要扩展自定义的 module 或者 component ,一定注意不要将 OC 的 runtime 暴露给 JS , 不要将一些诸如 dlopen()dlsym()respondsToSelector:performSelector:method_exchangeImplementations() 的动态和不可控的方法暴露给JS, 也不要将系统的私有API暴露给JS

Module 扩展

swift 扩展 module

Weex SDK 只提供渲染,而不是其他的能力,如果你需要 像网络,图片,URL跳转这些特性,需要自己动手实现他们
例如,如果你想实现一个url地址跳转函数,你可以按照如下步骤实现一个 Module

自定义module的步骤

  1. 自定义的module类 必须实现 WXModuleProtocol
  2. 必须添加宏 WX_EXPORT_METHOD, 它可以被weex识别,它的参数是 JavaScript调用 module指定方法的参数
  3. 添加 @synthesized weexInstance,每个moudle对象被绑定到一个指定的实例上
  4. Module 方法会在UI线程中被调用,所以不要做太多耗时的任务在这里,如果要在其他线程执行整个module 方法,需要实现 WXModuleProtocol- (NSThread *) targetExecuteThread的方法,这样,分发到这个module的任务会在指定的线程中运行
  5. Weex 的参数可以是 String 或者Map Module
  6. 支持返回值给 JavaScript中的回调,回调的类型是 WXModuleCallback,回调的参数可以是String或者Map
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @implementation WXEventModule
    @synthesize weexInstance;
    WX_EXPORT_METHOD(@selector(openURL:callback:))
    - (void)openURL:(NSString *)url callback:(WXModuleCallback)callback
    {
    NSString *newURL = url;
    if ([url hasPrefix:@"//"]) {
    newURL = [NSString stringWithFormat:@"http:%@", url];
    } else if (![url hasPrefix:@"http"]) {
    newURL = [NSURL URLWithString:url relativeToURL:weexInstance.scriptURL].absoluteString;
    }
    UIViewController *controller = [[WXDemoViewController alloc] init];
    ((WXDemoViewController *)controller).url = [NSURL URLWithString:newURL];
    [[weexInstance.viewController navigationController] pushViewController:controller animated:YES];
    callback(@{@"result":@"success"});
    }
    @end

暴露同步方法v0.10+

如果你想要暴露同步的native方法给JS, 即JS可以直接拿到Native的返回值。 你可以使用 WX_EXPORT_METHOD_SYNC 宏。

native 代码:

1
2
3
4
5
6
7
8
@implementation WXEventModule
WX_EXPORT_METHOD_SYNC(@selector(getString))

- (NSString *)getString
{
return @"testString";
}
@end

js 代码:

1
2
const eventModule = weex.requireModule('event')
const returnString = syncTest.getString() // return "testString"

除了string, 你也可以返回 number/array/dictionary 类型.

注意: 暴露的同步方法只能在 JS 线程执行,请不要做太多同步的工作导致JS执行阻塞。

注意: Vue 2.0 还未支持这个特性,最早会在 0.12 版本支持

注册 module

通过调用 WXSDKEngine 中的 registerModule:withClass 方法来注册自己的module

1
2
3
4
5
6
7
8
WXSDKEngine.h
/**
* @abstract Registers a module for a given name
* @param name The module name to register
* @param clazz The module class to register
**/
+ (void)registerModule:(NSString *)name withClass:(Class)clazz;
[WXSDKEngine registerModule:@"event" withClass:[WXEventModule class]];

使用自己的 module

这里的 require 里面的 event 就是在 上一步调用 registerModule: 注册 module 时候的 name

1
2
3
4
var eventModule = weex.requireModule('event');
eventModule.openURL('url',function(ret) {
nativeLog(ret);
});

Weex SDK 没有 图片下载,navigation 操作的能力,请大家自己实现这些 protocol

WXImgLoaderProtocol

weexSDK 没有图片下载的能力,需要实现 WXImgLoaderProtocol, 参考下面的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
WXImageLoaderProtocol.h
@protocol WXImgLoaderProtocol <WXModuleProtocol>
/**
* @abstract Creates a image download handler with a given URL
* @param imageUrl The URL of the image to download
* @param imageFrame The frame of the image you want to set
* @param options : The options to be used for this download
* @param completedBlock : A block called once the download is completed.
image : the image which has been download to local.
error : the error which has happened in download.
finished : a Boolean value indicating whether download action has finished.
*/
-(id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)options completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock;
@end

实现上述协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@implementation WXImgLoaderDefaultImpl
#pragma mark -
#pragma mark WXImgLoaderProtocol
- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock
{
if ([url hasPrefix:@"//"]) {
url = [@"http:" stringByAppendingString:url];
}
return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, finished);
}
}];
}
@end

handler注册

你可以通过WXSDKEngine 中的 registerHandler:withProtocol 注册handler

1
2
3
4
5
6
7
8
WXSDKEngine.h
/**
* @abstract Registers a handler for a given handler instance and specific protocol
* @param handler The handler instance to register
* @param protocol The protocol to confirm
*/
+ (void)registerHandler:(id)handler withProtocol:(Protocol *)protocol;
[WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)]

Components 扩展

虽然 WeexSDK 中有很多的 native 的 Component,但这有可能并不能满足你的需求。在之前你可能已经写了一些很酷炫 native 的组件,想包装一下,导入到 Weex 中,因此我们提供了让开发者实现自己的 native Component。下面将以 WeexSDK 中已经存在的 Component:image 为例子,介绍一下如何构建一个 native Component。假设你已经了解 iOS 开发

注册 Component

注册一个 component 比较简单,调用 WXSDKEngine 中的 registerComponent:withClass: 方法,传入组件的标签名称,还有对应的 class 然后你可以创建一个
WXImageComponent 表示 image 组件的实现。在 .we 文件中,只需要写 <image></image>

添加属性

现在我们要做一些让 image component 更加强大的事情。既然作为一个图片的 component,那它应该要有源,给他加上一个 src 的属性,同时给它加上一个 resize 的属性(可以配置的有 contain/cover/stretch

1
2
3
4
@interface WXImageComponent ()
@property (nonatomic, strong) NSString *imageSrc;
@property (nonatomic, assign) UIViewContentMode resizeMode;
@end

component 中所有的 style,attribute,events 都会被传递到 Component 的初始化方法中,所以,你可以在初始化方法中存储你感兴趣的一些属性值

1
2
3
4
5
6
7
8
9
10
@implementation WXImageComponent
- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
_imageSrc = [WXConvert NSString:attributes[@"src"]];
_resizeMode = [WXConvert UIViewContentMode:attributes[@"resize"]];
}
return self;
}
@end

attribute 中拿到的值的类型都是 id,我们可以用转换方法把它转换到任何值。Weex SDK 提供了一些基础的转换方法,可以参考 WXConvert 类,或者你可以添加自己的转换函数。

Hooking 渲染生命周期

native 的 component 是由 Weex 管理的,Weex 创建,布局,渲染,销毁。Weex 的 component 生命周期都是可以 hook 的,你可以在这些生命周期中去做自己的事情。

方法 描述
initWithRef:type:… 用给定的属性初始化一个component.
layoutDidFinish 在component完成布局时候会调用.
loadView 创建component管理的view.
viewWillLoad 在component的view加载之前会调用.
viewDidLoad 在component的view加载完之后调用.
viewWillUnload 在component的view被释放之前调用.
viewDidUnload 在component的view被释放之后调用.
updateStyles: 在component的style更新时候调用.
updateAttributes: 在component的attribute更新时候调用.
addEvent: 给component添加event的时候调用.
removeEvent: 在event移除的时候调用.

在 image component 的例子里面,如果我们需要我们自己的 image view 的话,可以复写 loadView这个方法.

1
2
3
4
- (UIView *)loadView
{
return [[WXImageView alloc] init];
}

现在我们使用 WXImageView 渲染 image component
作为一个 image component,我们需要拿到服务器图片,而且把它设置进 image view 里. 这个操作可以在 viewDidLoad 方法中做,这个方法是在 view 已经被创建而且加载了时候 Weex SDK 会调用到,而且 viewDidLoad 这个方法是你做额外初始化工作比如改变 content mode(也就是设置resize) 的最好时间.

1
2
3
4
5
6
7
8
9
- (void)viewDidLoad
{
UIImageView *imageView = (UIImageView *)self.view;
imageView.contentMode = _resizeMode;
imageView.userInteractionEnabled = YES;
imageView.clipsToBounds = YES;
imageView.exclusiveTouch = YES;
// Do your image fetching and updating logic
}

如果可以改变 image 的 src,也可以 hook updateAttributes: 方法来做属性更新操作,当 updateAttributes: 或者 updateStyles: 被调用的时候, component 的 view 已经加载完成

1
2
3
4
5
6
7
8
9
10
11
- (void)updateAttributes:(NSDictionary *)attributes
{
if (attributes[@"src"]) {
_imageSrc = [WXConvert NSString:attributes[@"src"]];
// Do your image updating logic
}
if (attributes[@"resize"]) {
_resizeMode = [WXConvert UIViewContentMode:attributes[@"resize"]];
self.view.contentMode = _resizeMode;
}
}

或许你需要考虑更多的生命周期方法去 Hook,当布局完成时候,像 layoutDidFinish,如果你想了解更多,可以参考一下 WXComponent.h 声明的方法。

现在你可以用在任何 .we 文件里面使用 <image>,而且可以加上 image 的属性。

1
<image style="your-custom-style" src="image-remote-source" resize="contain/cover/stretch"></image>

component 方法

WeexSDK 0.9.5 之后支持了在 js 中直接调用 component 的方法,这里提供一个例子

  • 自定义一个 WXMyCompoenent 的组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @implementation WXMyComponent
    WX_EXPORT_METHOD(@selector(focus)) // 暴露该方法给js
    - (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
    {
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
    // handle your attributes
    // handle your styles
    }

    return self;
    }
    - (void)focus
    {
    NSLog(@"you got it");
    }
    @end
  • 注册组件 [WXSDKEngine registerComponent:@"mycomponent" withClass:[WXMyComponent class]]

  • 在 weex 文件中调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <template>
    <mycomponent id='mycomponent'></mycomponent>
    </template>
    <script>
    module.exports = {
    created:function() {
    this.$el('mycomponent').focus();
    }
    }
    </script>

difference-of-vuex

使用 Vuex 和 vue-router

Updated time: 14/06/2017

Vue.js 也有较多周边技术产品,如 Vuexvue-router等,这些库也可以在 Weex 中很好的工作。

我们基于 Weex 和 Vue 开发了一个的完整项目 weex-hackernews ,在项目中使用了 Vuex 和 vue-router ,能够实现同一份代码,在 iOS、Android、Web 下都能完整地工作。

使用 Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理工具库,可以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

由于在 Vuex 本身就是平台无关的,有较强的移植能力,完全可以在 Weex 中正常地使用 Vuex ,阅读其官方文档可以了解详细的使用方法。

Vuex 也集成到了其官方调试工具 devtools extension中,提供了诸如 time-travel 调试、状态快照导入导出等高级调试功能。这些工具在 Web 平台中可以一如既往地工作。

使用 vue-router

vue-router 是专为 Vue.js 开发的便于实现单页应用的工具库,能够以声明式的方法编写页面的导航和跳转信息。

由于 Weex 的运行环境不只是浏览器,通常是以移动端原生环境为主,然而在 Android 和 iOS 中都没有浏览器的 History API,也不存在 DOM,因此如果想在 Weex 环境中使用 vue-router ,有些功能受到了限制,使用时应该注意。

路由模式

vue-router 提供了三种运行模式:

  • hash: 使用 URL hash 值来作路由。默认模式。
  • history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
  • abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。

配置方法是在定义路由时,传递 mode 属性:

1
2
3
4
new Router({
mode: 'abstract',
// ...
})

从三种模式的介绍中也可以看出来,Weex 环境中只支持使用 abstract 模式。不过,vue-router 自身会对环境做校验,如果发现没有浏览器的 API,vue-router 会自动强制进入 abstract模式,所以在使用时只要不写 mode 配置即可。默认 vue-router 会在浏览器环境中使用 hash 模式,在移动端原生环境中使用 abstract 模式。

编程式导航

vue-router 中使用 <router-link> 创建导航链接,不过在其中使用了基于 DOM 事件的一些特性,在 Weex 原生环境中并不能很好的工作。在 Weex 中,你必须使用编程式导航来编写页面跳转逻辑。

编程式导航其实就是通过主动调用 router 实例上的 push 方法实现跳转。

使用 <router-link> 的代码示例:

1
2
3
4
5
6
7
8
<!-- 只能在 Web 中使用,Native 环境不支持! -->
<template>
<div>
<router-link to="profile">
<text>Profile</text>
</router-link>
</div>
</template>

在 Weex 中,需要写成这个样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<div>
<text @click="jump">Profile</text>
</div>
</template>
<script>
import router from './path/to/router'
export default {
methods: {
jump () {
router.push('profile')
}
}
}
</script>

difference-with-web

Vue 2.x 在 Weex 和 Web 中的差异

Updated time: 14/06/2017

平台差异

Vue.js 最初是为 Web 平台设计的,虽然可以基于 Weex 开发原生应用,但是 Web 开发和原生开发毕竟不同,在功能和开发体验上都有一些差异,这些差异从本质上讲是原生开发平台和 Web 平台之间的差异,可以通过《Weex和 Web 平台的差异》了解更多细节和原因。

由于运行平台存在差异,Weex 不支持 Vue.js 中与 DOM 相关的功能:

  • 不支持事件冒泡和捕获机制,.prevent.capture.stop.self 等事件修饰符在原生环境中无意义。
  • 键盘事件的 .{keyCode | keyAlias} 修饰符在原生环境中无意义。(参考 Vue 相关文档)
  • 无需自行调用 vm.$mount,默认会将入口组件挂载到原生应用的视图中。
  • 不支持 v-htmlv-text 指令。

功能差异

仅引入了 Vue Runtime

Vue 除了提供默认的完整包以外,还提供一个更小巧的 vue.runtime.js,在这个文件中移除了模板编译的相关操作,Weex 中也仅引入 Vue Runtime 的功能,这样做除了可以减少代码体积以外,还能减少运行期编译模板的负担,提升性能。

具体的差异有:

  • 定义组件时不支持使用 template 属性。
  • 不支持使用 x-templates
  • 不支持使用 Vue.compile

隔离多页面的作用域

Weex 在原生端使用的是“多页”的实现,不同的 js bundle 将会在不同的原生页面中执行;也就是说,不同的 js bundle 之间将不同共享 js 变量。即使是 Vue 这个变量,在不同页面中也对应了不同的引用。

基于这个特性,Vue 中全局功能将只在当前页面内生效:

  • Vue.config
  • Vue.component
  • Vue.directive
  • Vue.filter
  • Vue.mixin
  • Vue.use

注:以上接口的功能并未受影响,只是其生效范围将会限制在同一页面内。

样式差异

Web 中的 CSS 非常的灵活,积累了特别多的属性,支持多种布局方法;这是其优势,也是浏览器性能优化的一个瓶颈。

Weex 中的样式是由原生渲染器解析的,出于性能和功能复杂度的考虑,Weex 对 CSS 的特性做了一些取舍,使其更符合最佳实践。

单类名选择器和作用域

Weex 中只支持单个类名选择器,不支持关系选择器,也不支持属性选择器。

1
2
3
4
5
6
7
8
9
10
11
12
/* 支持单个类名选择器 */
.one-class {
font-size: 36px;
}
/* 不支持关系选择器 */
.parent > .child {
padding-top: 10px;
}
/* 不支持属性选择器,不支持 `v-cloak` 指令 */
[v-cloak] {
color: #FF6600;
}

这个只是对样式定义的限制,不影响样式类名的使用,在标签中可以添加多个样式类名,如:

1
2
3
<template>
<div class="one two three"><div>
</template>

组件级别的作用域

在 Weex 中,写在组件 <style> 里的样式只能用在当前组件中,默认是 scoped 作用域。为了保持和 Native 的一致性,建议在 .vue 文件中写样式时,加上 scoped 属性,即: <style scoped>

支持的样式属性

Weex 支持的样式特性是 CSS 的子集,并且会不断扩充;在实现过程中我们参考了 CSS 属性在浏览器中的使用频率,优先实现其中频率最高的一些属性。

Weex 支持了基本的盒模型和 flexbox 布局,以及其他常用样式,详情可参考Weex 通用样式文档

在编写样式时,还应该注意一下几点:

  • 不需要写样式前缀。
  • Weex 不支持 display: none;,因此也不支持 v-show 指令。
  • 为了优化样式解析的效率,样式属性暂不支持简写,涉及一下属性:
    • borderborder-(top|bottom|left|right)
    • margin
    • padding
    • flex

编译环境的差异

在 Weex 中使用 Vue.js ,你所需要关注的运行平台除了 Web 之外还有 Android 和 iOS ,在开发和编译环境上还有一些不同点。针对 Web 和原生平台,将 Vue 项目源文件编译成目标文件,有两种不同的方式:

  • 针对 Web 平台,和普通 Vue 2.X 项目一样,可以使用任意官方推荐的方式编译源文件,如 Webpack + vue-loader 或者 Browserify + vueify 。
  • 针对 Android 和 iOS 平台,我们提供了 weex-loader 工具支持编译 .vue 格式的单文件组件;也就是说,目前只能使用 Webpack + weex-loader 来生成原生端可用的 js bundle。

使用 weex-loader

weex-loader 是 Webpack 的一个加载器,使用方法参考其官方文档。需要提醒的是,如果 Webpack 配置的入口文件是个 .vue 格式的文件的话,还需要额外传递 entry 参数,通常设置为
true,表示将当前组件作为入口组件。为了能正常匹配 .vue 文件,Webpack 配置文件中 weex-loader 的匹配规则也需要有所调整。

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
// 针对 .vue 文件要添加 entry 参数
entry: './path/to/App.vue?entry=true',
// 其他配置项 ...
module: {
loaders: [{
// 匹配包含了 entry 参数的 .vue 文件路径
test: /\.vue(\?[^?]+)?$/,
loaders: ['weex-loader']
}]
},
}

如果使用 .js 文件作为 Webpack 配置的入口文件,则不需要额外配置这些参数,我们推荐使用 Javascript 文件作为编译的入口文件。

搭建原生开发环境

Weex 项目生成的是原生应用,学习一些开发原生应用的基础知识,会对你开发 Weex 项目很有帮助。参考《集成 Weex 到已有应用》了解更多信息。

JS-Service

JS Service v0.9.5+

Updated time: 14/06/2017

JS service 和 Weex 实例在 JS runtime 中并行运行。Weex 实例的生命周期可调用 JS service 生命周期。目前提供创建、刷新、销毁生命周期。

重要提醒: JS Service 非常强大但也很危险,请小心使用!

注册 JS Service

iOS

1
[WeexSDKEngine registerService:@"SERVICE_NAME" withScript: @"SERVICE_JS_CODE" withOptions: @{}];

Android

1
2
3
4
5
HashMap<String, String> options = new HashMap<>()
options.put("k1", "v1")
String SERVICE_NAME = "SERVICE_NAME"
String SERVICE_JS_CODE = "SERVICE_JS_CODE"
boolean result = WXSDKEngine.registerService(SERVICE_NAME, SERVICE_JS_CODE, options)

Web

1
2
<!-- 必须在 JSFM 之后加载 -->
<script src="SERVICE_JS_CODE_URL"></script>

编写一个 JS service

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
42
43
44
45
46
47
48
49
50
// options: native inject options
// options.serviceName is native options name
service.register(options.serviceName, {
/**
* JS Service lifecycle. JS Service `create` will before then each instance lifecycle `create`. The return param `instance` is Weex protected param. This object will return to instance global. Other params will in the `services` at instance.
*
* @param {String} id instance id
* @param {Object} env device environment
* @return {Object}
*/
create: function(id, env, config) {
return {
instance: {
InstanceService: function(weex) {
var modal = weex.requireModule('modal')
return {
toast: function(title) {
modal.toast({ message: title })
}
}
}
},
NormalService: function(weex) {
var modal = weex.requireModule('modal')
return {
toast: function(title) {
modal.toast({ message: title })
}
}
}
}
},
/**
* JS Service lifecycle. JS Service `refresh` will before then each instance lifecycle `refresh`. If you want to reset variable or something on instance refresh.
*
* @param {String} id instance id
* @param {Object} env device environment
*/
refresh: function(id, env, config){
},
/**
* JS Service lifecycle. JS Service `destroy` will before then each instance lifecycle `destroy`. You can deleted variable here. If you doesn't detete variable define in JS Service. The variable will always in the js runtime. It's would be memory leak risk.
*
* @param {String} id instance id
* @param {Object} env device environment
* @return {Object}
*/
destroy: function(id, env) {
}
})

Using JS Service (vuejs)

1
2
3
4
5
6
7
8
9
10
11
<script>
var _InstanceService = new InstanceService(weex)
var _NormalService = new service.normalService(weex)
module.exports = {
created: fucntion() {
// called modal module to toast something
_InstanceService.toast('Instance JS Service')
_NormalService.toast('Normal JS Service')
}
}
</script>

WebStandards

Web 标准

Updated time: 14/06/2017

HTML

refs: https://www.advancedwebranking.com/html/ 2016-12-11

Overview

percentage name supported
98.1% <head> -
97.9% <body> -
97.9% <html> -
97% <title> -
93.9% <meta> -
89.9% <div>
89.6% <a>
88.5% <script>
86.5% <link> -
86.3% <img>
81.5% <p> - (can be customized)
75.6% <span> - (can be customized)
73.8% <li> - (can be customized)
73.7% <ul> - (can be customized)
70.3% <br>
60.4% <style>
55.8% <h1> - (can be customized)
52.7% <h2> - (can be customized)
48.4% <input>
46.9% <form>
44.3% <strong> - (can be customized)
43.1% <h3> - (can be customized)
30.9% <table>
30.3% <tr>
30.2% <td>

Forms

percentage name supported
49.5% <option>
30.2% <input>
16.6% > [type="hidden"] -
8% > [type="text"]
4.2% > [type="submit"] -
2% > [type="checkbox"] - (<switch>)
1.2% > [type="email"]
1.1% > [type="radio"]
0.9% > [type="image"] -
0.8% > [type="button"] -
0.6% > [type="search"]
0.6% > [type="password"]
0.1% > [type="tel"]
0.1% > [type="number"]
0% > [type="reset"] -
0% > [type="file"]
0% > [type="date"]
0% > [type="url"]
0% > [type="range"]
0% > [type="color"]
0% > [type="time"]
0% > [type="datetime-local"]
7.2% <label> -
6.1% <form> -
3.7% <button> - (can be customized)
2.6% > [type="button"] -
1.3% > [type="submit"] -
0% > [type="reset"] -
1.9% <select>
0.7% <textarea>
0.5% <fieldset> -
0.1% <optgroup>
0.1% <legend> -
0% <progress>
0% <datalist> -
0% <output> -
0% <meter> -

CSS Properties

refs: https://www.chromestatus.com/metrics/feature/popularity 2016-12-11

percentage name supported
90.5115% display flex only
89.8243% margin ✓ (not support combo)
88.7012% width
88.6468% overflow ✓ iOS only, hidden only for Android
88.6432% background-color
88.0803% height
87.7648% font-size
87.3837% padding
87.2721% color
86.9788% text-align
86.6841% position relative by default, static not supported
86.6039% font-family
86.5943% font-weight
85.0072% opacity
80.6911% max-width
79.4476% box-sizing border-box only
75.7623% max-height
74.9939% webkit-user-select
57.0292% align-items
56.8182% justify-content space-around not supported well in browser
50.5941% flex-direction
48.5052% border
47.5161% top
46.9136% background
46.1552% cursor
46.1443% margin-left
46.0956% left
46.0848% text-decoration
45.9575% float
45.8391% border-bottom
45.7639% padding-left
45.7128% margin-top
45.7013% line-height
45.5836% background-image
45.0837% z-index
45.0649% right
45.0516% margin-bottom
45.0459% white-space
44.8710% margin-right
44.8476% vertical-align
44.6306% padding-top
44.1466% border-radius
44.0136% border-top
43.9815% padding-bottom
43.9392% padding-right
43.8539% visibility
43.4306% background-position
43.4098% background-repeat
43.0391% clear
42.9100% bottom
42.2092% content
42.0690% box-shadow
41.9004% border-color
41.7341% outline
41.4297% border-right
41.2605% border-left
41.1127% min-height
41.0736% font-style
41.0523% min-width
40.4298% list-style
39.7341% font
38.8999% background-size
38.7811% border-width
38.7718% border-collapse
37.8110% border-style
37.4962% text-overflow ✓ must work with lines
37.3471% text-transform
37.2154% transition
36.5155% overflow-y
36.3025% transform
36.2488% text-indent
35.5075% text-shadow
34.7607% webkit-appearance
34.1925% list-style-type
34.0238% border-spacing
33.6664% word-wrap
31.9961% overflow-x
31.9922% zoom
31.2495% border-bottom-left-radius
31.1306% pointer-events
31.1229% border-top-left-radius
30.2131% border-bottom-color
29.9608% border-top-color
29.4297% border-bottom-right-radius
29.2668% border-top-right-radius
28.6489% letter-spacing
27.8327% animation
26.6738% border-right-width
26.0169% src
25.2661% clip
25.2512% webkit-font-smoothing
25.1971% border-bottom-width
25.0246% border-right-color
24.7790% direction
24.4094% webkit-tap-highlight-color
23.9751% border-left-color
23.9321% border-top-width
23.7902% fill
23.2617% border-left-width
22.7278% table-layout
21.5766% word-break
20.4319% background-clip
19.3198% transform-origin
18.9233% filter
17.7879% resize
16.2501% flex
15.1656% font-variant
14.9181% text-rendering
14.7125% webkit-filter
14.5263% transition-duration
14.3966% transition-property
14.2124% webkit-box-orient
13.5432% outline-offset
12.9300% transition-timing-function
12.2788% unicode-range
12.0880% word-spacing
11.9124% quotes
11.6800% border-bottom-style
11.4263% webkit-background-clip
11.0070% flex-grow
10.5925% backface-visibility
10.4417% animation-name
10.4302% stroke
10.4144% animation-duration
10.2804% touch-action
9.9663% list-style-position
9.8662% order
9.7770% outline-width
9.7504% transition-delay
9.4689% border-top-style
9.3474% webkit-box-pack
9.3078% webkit-box-align
9.2375% page-break-inside
9.1898% webkit-line-clamp
8.9350% list-style-image
8.8339% page-break-after
8.5735% speak
8.4754% unicode-bidi
8.4307% animation-timing-function
8.1464% webkit-box-flex
8.0048% orphans
7.9947% widows
7.6671% flex-wrap ✓ not supported well in browser
7.5756% animation-fill-mode
7.4163% animation-delay
7.3284% border-left-style
7.1586% outline-color
6.9102% flex-shrink
6.7754% perspective
6.7748% border-right-style
6.4619% outline-style
6.0382% animation-iteration-count
5.9838% background-origin
5.9714% fill-opacity
5.9357% will-change
5.3740% stroke-width
5.3172% transform-style
5.2608% overflow-wrap
5.1730% background-attachment
4.9039% counter-increment
4.5950% counter-reset
4.5031% align-self
4.4109% webkit-box-ordinal-group
4.4046% webkit-animation-direction
3.7598% background-position-x
3.6867% border-image
3.6601% background-position-y
3.5749% webkit-user-drag
3.3376% flex-basis
3.1840% align-content
3.1832% flex-flow
3.1774% image-rendering
3.0879% webkit-margin-start
2.9551% font-stretch
2.8934% empty-cells
2.7619% webkit-margin-after
2.7220% perspective-origin
2.6125% webkit-margin-end
2.6089% column-count
2.5880% webkit-text-fill-color
2.5466% webkit-box-direction
2.4618% font-feature-settings
2.3959% webkit-mask-image
2.3431% webkit-padding-end
2.2555% stroke-dasharray
2.1788% user-select
2.1679% object-fit
2.0643% column-gap
2.0459% text-size-adjust
2.0253% caption-side
1.9695% stroke-dashoffset
1.7923% stroke-linecap
1.7861% animation-direction
1.7559% webkit-font-feature-settings
1.7404% stroke-opacity
1.5926% stroke-miterlimit
1.5786% fill-rule
1.4859% webkit-user-modify
1.3439% webkit-border-image
1.3091% animation-play-state
1.2676% contain
1.2029% webkit-padding-start
1.1840% webkit-margin-before
1.1269% page-break-before
1.1222% webkit-margin-top-collapse
1.0418% columns
1.0354% webkit-mask-size
0.9650% border-image-slice
0.9425% stop-color
0.9408% webkit-mask-repeat
0.9125% webkit-box-lines
0.8804% webkit-column-break-inside
0.8752% size
0.8334% font-kerning
0.8034% stroke-linejoin
0.7869% tab-size
0.7689% break-inside
0.7589% webkit-text-stroke-width
0.7353% column-width
0.6924% webkit-mask-position
0.6869% border-image-width
0.6323% border-image-repeat
0.5994% border-image-outset
0.5885% all
0.5859% webkit-text-stroke-color
0.5435% webkit-print-color-adjust
0.5420% webkit-text-stroke
0.5195% writing-mode
0.4741% clip-rule
0.4685% webkit-clip-path
0.4578% text-anchor
0.4535% shape-rendering
0.4526% webkit-column-break-before
0.4494% clip-path
0.4452% webkit-mask
0.4393% mix-blend-mode
0.4166% text-align-last
0.4033% column-rule
0.3990% webkit-mask-box-image
0.3989% font-variant-ligatures
0.3881% column-fill
0.3865% webkit-line-break
0.3857% border-image-source
0.3528% stop-opacity
0.3075% webkit-perspective-origin-y
0.3054% webkit-perspective-origin-x
0.2994% webkit-writing-mode
0.2717% dominant-baseline
0.2634% column-rule-color
0.2586% webkit-box-decoration-break
0.2467% webkit-text-security
0.2374% webkit-background-origin
0.2146% font-variant-caps
0.2005% column-rule-style
0.1976% shape-outside
0.1971% webkit-padding-before
0.1896% break-after
0.1782% webkit-padding-after
0.1774% text-orientation
0.1747% webkit-text-orientation
0.1655% mask
0.1626% alignment-baseline
0.1572% page
0.1530% webkit-column-break-after
0.1521% webkit-box-reflect
0.1504% webkit-text-emphasis-color
0.1499% object-position
0.1470% break-before
0.1455% webkit-margin-collapse
0.1452% baseline-shift
0.1451% hyphens
0.1309% rx
0.1304% ry
0.1256% background-blend-mode
0.1136% font-variant-numeric
0.1135% background-repeat-x
0.1123% background-repeat-y
0.1086% webkit-text-emphasis
0.1058% webkit-rtl-ordering
0.1040% column-rule-width
0.1036% isolation
0.1002% webkit-highlight
0.0843% webkit-transform-origin-y
0.0786% webkit-transform-origin-x
0.0770% webkit-app-region
0.0685% column-span
0.0653% r
0.0611% y
0.0602% x
0.0555% webkit-border-vertical-spacing
0.0545% webkit-border-horizontal-spacing
0.0542% webkit-border-start-width
0.0450% webkit-border-start-color
0.0424% webkit-border-after-width
0.0424% webkit-border-before-width
0.0423% webkit-border-end-width
0.0351% marker
0.0349% webkit-border-end-color
0.0347% webkit-border-after-color
0.0347% webkit-border-before-color
0.0342% mask-type
0.0328% color-interpolation-filters
0.0325% webkit-border-end
0.0319% vector-effect
0.0307% color-rendering

CSS Units and Values

refs: https://drafts.csswg.org/css-values/ 2016-12-11

Textual

  • pre-defined keywords
  • CSS-wide keywords
    • initial
    • inherit
    • unset
  • <custom-ident>: author-defined identifiers ✓
  • <string>: quoted strings ("xxx")
  • <url>: resourec locators (url())

Numeric

  • <integer>
  • <number>
  • <percentage>

Length ##### <length>#####

  • relative
    • font-relative
      • em
      • ex
      • ch
      • ic
      • rem ✓🔧
    • viewport-percentage
      • vw ✓🔧
      • vh ✓🔧
      • vi
      • vb
      • vmin ✓🔧
      • vmax ✓🔧
  • absolute
    • cm ✓🔧
    • mm ✓🔧
    • Q ✓🔧
    • in ✓🔧
    • pc ✓🔧
    • pt ✓🔧
    • px autofixed to number

Quantities

  • <angle>
    • deg
    • grad
    • rad
    • turn
  • <time>
    • s
    • ms
  • <frequency>
    • Hz
    • kHz
  • <resolution>
    • dpi
    • dpcm
    • dppx

Elsewhere

  • <color>
  • <image>
  • <position>

Functional

  • calc()
  • toggle()
  • attr()

JS APIs

refs: https://www.w3.org/standards/techs/js 2016-12-11

Completed Work

Standards
last update spec supported
2016-11-17 Media Source Extensions™ - (media related)
2016-11-08 Geolocation API Specification 2nd Edition ✕ developing
2016-10-27 Pointer Lock -
2016-10-18 Vibration API (Second Edition)
2016-04-19 Web Storage (Second Edition) ✓ async storage module
2015-10-22 Web Notifications
2015-05-19 HTML5 Web Messaging BroadcastChannel developing
2015-02-24 Pointer Events -
2015-02-10 Vibration API
2015-02-03 Server-Sent Events
2015-01-08 Indexed Database API
2014-03-13 Metadata API for Media Resources 1.0 - (media related)
2014-02-11 Progress Events
2014-01-16 JSON-LD 1.0 Processing Algorithms and API -
2013-12-12 Performance Timeline - (perf related)
2013-12-12 User Timing - (perf related)
2013-10-31 Widget Interface -
2013-10-29 Page Visibility (Second Edition) onviewappear/onviewdisappear
2013-10-10 Touch Events
2013-02-21 Selectors API Level 1 -
2012-12-17 Navigation Timing - (perf related)
2012-12-17 High Resolution Time - (perf related)
2008-12-22 Element Traversal Specification -

Drafts

Proposed Recommendations
last update spec supported
2016-09-15 WebIDL Level 1 -
Candidate Recommendations
last update spec supported
2016-12-08 Performance Timeline Level 2 - (perf related)
2016-11-22 Page Visibility Level 2 onviewappear/onviewdisappear
2016-11-01 High Resolution Time Level 2 - (perf related)
2016-08-18 DeviceOrientation Event Specification
2016-07-21 Resource Timing Level 1 - (perf related)
2016-07-14 Presentation API -
2016-07-07 Battery Status API
2016-07-05 Encrypted Media Extensions -
2016-05-19 Media Capture and Streams - (media related)
2014-12-11 Web Cryptography API -
2014-09-09 HTML Media Capture - (media related)
2012-09-20 The WebSocket API
Last Call Drafts
last update spec supported
2011-12-01 Geolocation API Specification Level 2
Other Working Drafts
last update spec supported
2016-12-09 MediaStream Image Capture - (media related)
2016-12-06 MediaStream Recording - (media related)
2016-12-06 Selection API
2016-12-05 Input Events
2016-12-02 Gamepad -
2016-11-29 WebDriver -
2016-11-24 WebRTC 1.0: Real-time Communication Between Browsers
2016-11-22 Pointer Lock 2.0 -
2016-11-07 Remote Playback API - (media related)
2016-11-03 Resource Timing Level 2 - (perf related)
2016-11-02 Audio Output Devices API - (media related)
2016-11-01 Indexed Database API 2.0
2016-11-01 User Timing Level 2 - (perf related)
2016-10-31 The Screen Orientation API
2016-10-31 High Resolution Time Level 3 - (perf related)
2016-10-24 UI Events KeyboardEvent code Values -
2016-10-24 UI Events KeyboardEvent key Values -
2016-10-11 Service Workers 1
2016-09-21 Identifiers for WebRTC’s Statistics API -
2016-09-13 Accelerometer Sensor
2016-09-13 Gyroscope Sensor
2016-09-13 Magnetometer Sensor
2016-08-30 Ambient Light Sensor
2016-08-30 Media Capture from DOM Elements - (media related)
2016-08-30 Generic Sensor API
2016-08-03 Wake Lock API
2016-07-19 Proximity Sensor
2016-07-19 Pointer Events - Level 2 -
2016-07-14 Screen Capture
2016-07-12 Media Capture Depth Stream Extensions - (media related)
2016-05-17 Cooperative Scheduling of Background Tasks
2016-04-22 Navigation Timing Level 2 - (perf related)
2016-04-03 Clipboard API and events clipboard module
2015-12-15 Push API
2015-12-08 Web Audio API - (media related)
2015-10-15 FindText API -
2015-09-24 Web Workers
2015-04-21 File API
2014-02-20 Network Service Discovery
2012-03-06 MediaStream Capture Scenarios - (media related)
2011-12-15 Audio Processing API - (media related)

WeexInstanceVariableS

Weex 实例变量

Updated time: 01/08/2017

每个 Weex 页面的 JS 上下文中都有一个相互独立的 weex 变量,用来持有当前 Weex 页面相关的单例内容或方法。

weex.config

该变量包含了当前 Weex 页面的所有环境信息,包括不仅限于:

  • bundleUrl: string: JS bundle 的 URL。
  • env: Object: 环境对象。
    • weexVersion: string: Weex sdk 版本。
    • appName: string: 应用名字。
    • appVersion: string: 应用版本。
    • platform: string: 平台信息,是 iOS、Android 还是 Web。
    • osName: string: iOS或者android,表示操作系统的名称.
    • osVersion: string: 系统版本。
    • deviceModel: string: 设备型号 (仅原生应用)。
    • deviceWidth: number: 设备宽度。Weex 默认以宽度为 750px 做适配渲染,要获得750px下的屏幕高度,可以通过 height = 750/deviceWidth*deviceHeight 公式获得,可以使用到 CSS 中,用来设置全屏尺寸
    • deviceHeight: number: 设备高度。

weex.requireModule(module: string): Object

获取某个 native module 的所有方法,比如:

1
2
3
4
5
6
7
8
9
10
<template>
<div><text>Hello World</text></div>
</template>
<script>
var modal = weex.requireModule('modal')
modal.toast({
message: 'I am a toast.',
duration: 3
})
</script>

weex.document: Document

返回当前 Weex 页面的文档对象。

NativeDomAPIS

Native DOM APIs

Updated time: 14/06/2017

Weex 在 JS 引擎中,为每个页面都提供了一套 Native DOM APIs,这套接口和 HTML DOM APIs 非常接近,利用这套接口我们可以通过 JavaScript 控制 native 的渲染逻辑。而且 Weex 上层的 Vue 2.0 也是基于这套接口进行适配的。

绝大多数情况下 JS 框架会把 Native DOM APIs 都封装好,开发者不需要直接对 Native DOM 进行操作。

  • Document 类,整个页面文档。
  • Node 类,结点的基础类。
  • Element 类,元素结点,继承自 Node,单个视图单元。
  • Comment 类,注释结点,继承自 Node,无实际意义,通常用作占位符。

每个 Weex 页面都有一个 weex.document 对象,该对象就是一个 Document 类的实例,也是下面所有接口调用的起点。

接下来详细介绍它们的用法:

Document

每个 Document 实例在创建的时候都会自动拥有一个 documentElement 属性,表示文档结点。该文档结点可以拥有一个 body,即文档的主体结点。

注意事项: 文档的主体结点只接受 <div><list><scroller> 三种类型的元素结点。

构造函数

new Document(id: string, url: string?)

成员方法

createElement(tagName: string, props: Object?): Element

  • 创建一个特定类型 tagNameElement 实例,即一个元素结点。props 可以包含 attr 对象和 style 对象。比如 createBody('div', {style: {backgroundColor: '#ffffff'}})

createComment(text: string): Comment

  • 创建一个 Comment 的实例,即一个注释结点,并设置一段文本描述。

createBody(tagName: string, props: Object?): Element

  • 创建文档主体结点,并自动挂载到 documentElement 下。

fireEvent(el: Element, type: string, e: Object?, domChanges: Object?)

触发一个特定类型的事件,并附带一个事件对象 e。当该事件在产生过程中修改了 DOM 的特性或样式,则第四个参数用来描述这些改变,参数格式和上面 createElement 方法的格式相同。

destroy()

  • 销毁当前文档。一旦销毁之后文档将不会再工作。

只读成员变量

**id: string

  • 每个 Document 实例都有一个唯一的 id。这同时也是每个 Weex 页面唯一拥有的 id

URL: string?

  • 如果当前 Weex 页面有 JS bundle URL 的话,这里则会返回 这个 URL。

body: Element

文档的主体结点,概念类似 HTML DOM 里的 document.body

documentElement: Element

  • 文档的对应结点,概念类似 HTML DOM 里的 document.documentElement
  • bodydocumentElement 的关系是:documentElementbody 的父结点。

getRef(id): Node

  • 根据结点 id 获取结点。

Node

构造函数

new Node()

成员

destroy()

只读成员变量或方法

ref: string

  • 每个 Node 实例都有各自的在整个 Document 实例中唯一的 ref 值。

nextSibling: Node?

previousSibling: Node?

parentNode: Node?

  • 上述三个接口和 HTML DOM 的定义吻合。

children: Node[]

  • 该结点拥有的所有子结点的数组。

pureChildren: Node[]

  • 该结点拥有的所有子元素的数组。和 children 的区别是,pureChildren 只包含了 Element 实例而不包含 Comment 实例。

Element 类 继承自 Node

构造函数

new Element(type: string, props: Object?)

  • 创建一个特定类型 type 的元素结点,参数 props 可以包含 attr 对象或 style 对象。

DOM 树操作

appendChild(node: Node)

insertBefore(node: Node, before: Node?)

  • 上述两个接口类似 HTML DOM。

insertAfter(node: Node, after: Node?)

  • 在一个子结点之前插入新结点 after。

removeChild(node: Node, preserved: boolean?)

  • 删除子结点 node,参数 preserved 表示立刻从内存中删除还是暂时保留。

clear()

  • 清除所有的子结点。

DOM 属性本身操作

setAttr(key: string, value: string, silent: boolean?)

setStyle(key: string, value: string, silent: boolean?)

  • 上述两个接口中,当 silent 为真的时候,结点仅更新自己,不会传递命令给客户端渲染层。该参数用来处理用户事件在发生时已经改变结点相关属性的情况下,不会在 Native DOM 也改变之后重复发送命令给客户端。

addEvent(type: string, handler: Function)

removeEvent(type: string)

fireEvent(type: string, e: any)

  • 绑定事件、解绑定事件、触发事件。
特定组件类型的组件方法

特殊的:不同组件类型可以拥有自己特有的方法,比如 <web> 组件支持 refresh 方法,详见各组件的描述,在此情况下,我们会产生特定组件类型的 class,比如 WebElement,它继承自 Element

如:

WebElement 继承自 Element
表示在 Weex 页面中嵌入一个 webview
refresh(): 刷新当前 webview

只读成员变量或方法

ref, nextSibling, previousSibling, parentNode

  • 继承自 Node

nodeType: number

  • 永远是数字 1
    type: string

  • 和构造函数里的 type 一致。
    attr: Object

  • 当前结点的所有特性的键值对。推荐通过 setAttr() 方法进行修改,而不要直接修改这里的对象。
    style: Object

  • 当前结点的所有样式的键值对。推荐通过 setStyle() 方法进行修改,而不要直接修改这里的对象。
    event: Object

  • 当前结点的所有事件绑定。每个事件类型对应一个事件句柄方法。推荐通过 addEvent() / removeEvent() 方法进行修改,而不要直接修改这里的对象。
    toJSON(): Object

  • 返回描述该元素结点的一段 JSON 对象,形如:{ref: string, type: string, attr: Object, style: Object, event: Array(string), children: Array}

Comment 类 继承自 Node

构造函数

new Comment(value: string)

只读成员变量或方法

**`ref, nextSibling, previousSibling, parentNode

  • 继承自 Node
    nodeType: number
  • 永远是数字 8
    type: string

  • 永远是字符串 'comment'
    value: string

  • 和构造函数里的 value 一致。
    toJSON(): Object

返回描述该注释结点的一段 JSON 对象,形如:<!-- value -->

commonEvent

通用事件

Updated time: 14/06/2017

Weex 提供了通过事件触发动作的能力,例如在用户点击组件时执行 JavaScript。下面列出了可被添加到 Weex 组件上以定义事件动作的属性:

click

当组件上发生点击手势时被触发。

注意:

<input><switch> 组件目前不支持 click 事件,请使用 changeinput 事件来代替。

事件对象

  • type: click
  • target: 触发点击事件的目标组件
  • timestamp: 触发点击事件时的时间戳

longpress

如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。

注意:

<input><switch> 组件目前不支持 click 事件,请使用 changeinput 事件来代替。

事件对象

  • type : longpress
  • target : 触发长按事件的目标组件
  • timestamp : 长按事件触发时的时间戳

Appear 事件

如果一个位于某个可滚动区域内的组件被绑定了 appear 事件,那么当这个组件的状态变为在屏幕上可见时,该事件将被触发。

事件对象

  • type : appear
  • target : 触发 Appear 事件的组件对象
  • timestamp : 事件被触发时的时间戳
  • direction : 触发事件时屏幕的滚动方向,updown

Disappear 事件

如果一个位于某个可滚动区域内的组件被绑定了 disappear 事件,那么当这个组件被滑出屏幕变为不可见状态时,该事件将被触发。

事件对象

  • type : disappear
  • target : 触发 Disappear 事件的组件对象
  • timestamp : 事件被触发时的时间戳
  • direction : 触发事件时屏幕的滚动方向,updown

Page 事件

注意:仅支持 iOS 和 Android,H5 暂不支持。

Weex 通过 viewappearviewdisappear 事件提供了简单的页面状态管理能力。

viewappear 事件会在页面就要显示或配置的任何页面动画被执行前触发,例如,当调用 navigator 模块的 push 方法时,该事件将会在打开新页面时被触发。viewdisappear 事件会在页面就要关闭时被触发。

与组件的 appeardisappear 事件不同的是,viewappearviewdisappear 事件关注的是整个页面的状态,所以它们必须绑定到页面的根元素上。

特殊情况下,这两个事件也能被绑定到非根元素的body组件上,例如 wxc-navpage 组件。

事件对象

  • type : viewappearviewdisappear
  • target : 触发事件的组件对象
  • timestamp : 事件被触发时的时间戳

示例

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
42
43
44
45
46
47
48
49
50
51
52
<template>
<div>
<div class="box" @click="onclick" @longpress="onlongpress" @appear="onappear" @disappear="ondisappear"></div>
</div>
</template>
<script>
const modal = weex.requireModule('modal')
export default {
methods: {
onclick (event) {
console.log('onclick:', event)
modal.toast({
message: 'onclick',
duration: 0.8
})
},
onlongpress (event) {
console.log('onlongpress:', event)
modal.toast({
message: 'onlongpress',
duration: 0.8
})
},
onappear (event) {
console.log('onappear:', event)
modal.toast({
message: 'onappear',
duration: 0.8
})
},
ondisappear (event) {
console.log('ondisappear:', event)
modal.toast({
message: 'ondisappear',
duration: 0.8
})
}
}
}
</script>
<style scoped>
.box {
border-width: 2px;
border-style: solid;
border-color: #BBB;
width: 250px;
height: 250px;
margin-top: 250px;
margin-left: 250px;
background-color: #EEE;
}
</style>