在 Weex 中使用 Vue.js

  • 只含有运行时的构建版本
  • 平台的差异
    • 执行环境
    • DOM
    • 样式
    • 事件
  • Web 渲染器
  • 单文件组件
    • 编译目标
    • 使用weex-loader
  • 支持的功能
    • 全局配置
    • 全局 API
    • 选项
    • 生命周期钩子
    • 实例属性
    • 实例方法
    • 模板指令
    • 特殊属性
    • 内置组件

在 WeexSDK v0.10.0在Weex中使用Vue.js - 图1 (发布于 2016 年 2 月 17 日)以及后续的版本中,集成了 v2 版本的 Vue.js。Vue 是一套构建用户界面的渐进式框架,详情请参阅其官方网站在Weex中使用Vue.js - 图2。

如果没有特别指示,文章中的 "Vue.js" 或者 "Vue" 都指的是 v2 版本的 Vue。

只含有运行时的构建版本

如果你熟悉 Vue.js,你应该知道 Vue.js 有两种构建版本: 运行时 + 编译器 与 只包含运行时在Weex中使用Vue.js - 图3。它们之间的区别在于编译器是否需要能够在运行时编译 template 选项。由于运行时构建版本比完整版本的构建版本轻约 30%(Vue 官方估算),为了更好的性能和更小的代码体积,Weex 集成的是运行时版本的 Vue。 具体来说,差异如下: * 定义组件时不支持 template在Weex中使用Vue.js - 图4 选项。 * 不支持使用 x-templates在Weex中使用Vue.js - 图5。 * 不支持使用 Vue.compile在Weex中使用Vue.js - 图6。

平台的差异

Vue.js 最初是为 Web 平台设计的。虽然可以基于Weex开发原生应用程序,但是仍然存在许多Weex 与 Web 平台的差异。 与 Web 平台的主要差异是: 执行环境、DOM、样式和事件。

执行环境

Weex 主要用于编写多页的应用程序,每个页面都对应了原生开发中的 View 或者 Activity ,并且保持自己的上下文。即使 Weex 的所有页面都使用的都是同一个 Javascript 引擎的实例(virtual machine),每个页面是执行环境也是互相隔离的(基于 Sandbox 技术)。

使用 BroadcastChannel 可以实现跨页通信。 具体来讲,每个页面的 Vue 变量都是不同的实例,即使是写在 Vue 上的“全局”配置(Vue.config.xxx)也只会影响 Weex 上的单个页面。 在此基础上,一些 Vue 的 SPA (单页面应用)技术,如 Vuex在Weex中使用Vue.js - 图7 和 vue-router在Weex中使用Vue.js - 图8 也将单页内生效。更通俗地说,“页面”概念在 SPA 技术中是虚拟的,但在 Weex 上却是真实的。即便如此,Vuex 和 vue-router 都是独立的库,都有自己的概念和使用场景,仍然可以在 Weex 里使用 Vuex 和 vue-router。

DOM

因为在 Android 和 iOS 上没有 DOM(Document Object Model),如果你要手动操作和生成 DOM 元素的话可能会遇到一些兼容性问题。在你使用现代前端框架的情况下,操作数据与组件而不是生成的元素是一个比较好的做法。 一些与 DOM 相关的特性,比如 v-html,vm.$el,template 选项,在不同的平台上可能无法获得相同的反应。 准确来说,vm.$el在Weex中使用Vue.js - 图9属性类型在web环境下是HTMLElement,但是在移动端并没有这个类型。实际上,它是一个由 Weex 文档对象模型 定义的特殊数据结构。

样式

样式表和 CSS 规则是由 Weex js 框架和原生渲染引擎管理的。要实现完整的 CSS 对象模型(CSSOM:CSS Object Model)并支持所有的 CSS 规则是非常困难的,而且没有这个必要。 出现性能考虑,Weex 目前只支持单个类选择器,并且只支持 CSS 规则的子集 。详情请参阅 通用样式 与 文本样式 。 在 Weex 里, 每一个 Vue 组件的样式都是 scoped在Weex中使用Vue.js - 图10 。

事件

目前在 Weex 里不支持事件冒泡和捕获,因此 Weex 原生组件不支持事件修饰符在Weex中使用Vue.js - 图11,例如.prevent,.capture,.stop,.self 。 此外,按键修饰符在Weex中使用Vue.js - 图12以及系统修饰键在Weex中使用Vue.js - 图13 例如 .enter,.tab,.ctrl,.shift 在移动端基本没有意义,在 Weex 中也不支持。

Web 渲染器

如果你想在网络上呈现你的页面,你需要 weex-vue-render在Weex中使用Vue.js - 图14 来实现它。 weex-vue-render是 Vue DSL 的 Web 渲染器, 它在 Web 上实现了 Weex 的内置组件和内置模块。详情请参阅这里在Weex中使用Vue.js - 图15。

单文件组件

Vue 中的单文件组件在Weex中使用Vue.js - 图16(即*.vue文件)是一种特殊的文件格式,扩展名为.vue。这个模板会在构建时编译到render函数里。 此外,所有的编辑器里都支持一个好的语法高亮插件在Weex中使用Vue.js - 图17。

在 Weex 中使用单个文件组件语法是一种很好的做法。 TIP 在 Weex 中使用 Vue 的单个文件组件语法是一种最佳实践。 因为针对 Weex 的 Web 平台的编译工具并不一样,如果你直接写的 render 函数,则绕过了 weex-loader 编译模板的过程,这样的话你需要自行处理平台差异的细节。

编译目标

因为平台的差异以及为了提高网络性能,*.vue文件需要用两种不同的方式来编译: * 对于 Web 平台来说,你可以用任何正式的方式来编译源文件,例如 使用 Webpack在Weex中使用Vue.js - 图18 + vue-loader在Weex中使用Vue.js - 图19 或者 Browserify + vueify 来编译*.vue文件。 * 对于安卓与 iOS 平台来说, 你需要使用 weex-loader在Weex中使用Vue.js - 图20 来编译*.vue文件。不同的平台使用不同的bundles,可以充分利用平台原有的特性,减少构建时的兼容性代码。但是源代码仍然是一样的,唯一的区别是编译它的方法。

使用weex-loader

weex-loader在Weex中使用Vue.js - 图21 是一个 webpack 的 loader在Weex中使用Vue.js - 图22,它能把*.vue文件转化为简单的javascript 模块用于安卓以及 iOS 平台。所有的特性和配置都是跟 vue-loader在Weex中使用Vue.js - 图23 一样的。 需要注意的是,如果 Webpack 的 entry 配置项是一个 *.vue 文件的话,你仍需要传递一个额外的 entry 参数作为标记。 1. const webpackConfig = { 2. // Add the entry parameter for the .vue file 3. entry: './path/to/App.vue?entry=true' 4. 5. /* ... */ 6. 7. use: { 8. loaders: [{ 9. // matches the .vue file path which contains the entry parameter 10. test: /.vue(\?^^]+)?$/, 11. loaders: ['weex-loader'] 12. }] 13. } 14. }

如果你现在用的是.js文件做入口文件,你不需要写那些额外的参数。 推荐 webpack 配置的入口文件使用 javascript 文件。 1. { 2. entry: './path/to/entry.js' 3. }

TIP 无论什么情况下都使用 javascript 文件作为入口文件。

支持的功能

全局配置

Vue “全局”配置只会影响 Weex 上的单一页面,配置不会在不同的 Weex 页面之间共享。 Vue 全局配置| 是否支持| 说明
---|---|---
Vue.config.silent在Weex中使用Vue.js - 图24| 支持| -
Vue.config.optionMergeStrategies在Weex中使用Vue.js - 图25| 支持| -
Vue.config.devtools在Weex中使用Vue.js - 图26| 不支持| 只在 Web 环境下支持
Vue.config.errorHandler在Weex中使用Vue.js - 图27| 支持| -
Vue.config.warnHandler在Weex中使用Vue.js - 图28| 支持| -
Vue.config.ignoredElements在Weex中使用Vue.js - 图29| 支持| 不推荐
Vue.config.keyCodes在Weex中使用Vue.js - 图30| 不支持| 在移动端无用
Vue.config.performance在Weex中使用Vue.js - 图31| 不支持| 与 devtools 一样
Vue.config.productionTip在Weex中使用Vue.js - 图32| 支持| -

全局 API

Vue 全局 API 是否支持 说明
Vue.extend在Weex中使用Vue.js - 图33 支持 -
Vue.nextTick在Weex中使用Vue.js - 图34 支持 -
Vue.set在Weex中使用Vue.js - 图35 支持 -
Vue.delete在Weex中使用Vue.js - 图36 支持 -
Vue.directive在Weex中使用Vue.js - 图37 支持 -
Vue.filter在Weex中使用Vue.js - 图38 支持 -
Vue.component在Weex中使用Vue.js - 图39 支持 -
Vue.use在Weex中使用Vue.js - 图40 支持 -
Vue.mixin在Weex中使用Vue.js - 图41 支持 -
Vue.version在Weex中使用Vue.js - 图42 支持 -
Vue.compile在Weex中使用Vue.js - 图43 不支持 Weex 用的是 只包含运行时构建在Weex中使用Vue.js - 图44
### 选项
Vue 选项 是否支持 说明
--- --- ---
data在Weex中使用Vue.js - 图45 支持 -
props在Weex中使用Vue.js - 图46 支持 -
propsData在Weex中使用Vue.js - 图47 支持 -
computed在Weex中使用Vue.js - 图48 支持 -
methods在Weex中使用Vue.js - 图49 支持 -
watch在Weex中使用Vue.js - 图50 支持 -
el在Weex中使用Vue.js - 图51 支持 在移动端el的值是无意义的
template在Weex中使用Vue.js - 图52 不支持 Weex 用的是 只包含运行时构建在Weex中使用Vue.js - 图53
render在Weex中使用Vue.js - 图54 支持 不推荐
renderError在Weex中使用Vue.js - 图55 支持 -
directives在Weex中使用Vue.js - 图56 支持 -
filters在Weex中使用Vue.js - 图57 支持 -
components在Weex中使用Vue.js - 图58 支持 -
parent在Weex中使用Vue.js - 图59 支持 不推荐
mixins在Weex中使用Vue.js - 图60 支持 -
extends在Weex中使用Vue.js - 图61 支持 -
provide/inject在Weex中使用Vue.js - 图62 支持 不推荐
name在Weex中使用Vue.js - 图63 支持 -
delimiters在Weex中使用Vue.js - 图64 支持 不推荐
functional在Weex中使用Vue.js - 图65 支持 -
model在Weex中使用Vue.js - 图66 支持 -
inheritAttrs在Weex中使用Vue.js - 图67 支持 -
comments在Weex中使用Vue.js - 图68 不支持 -
### 生命周期钩子
Vue 组件的实例生命周期钩子将在特定的阶段发出,详情请参考 Vue 组件的生命周期图示在Weex中使用Vue.js - 图69。
Vue 生命周期钩子 是否支持 说明
--- --- ---
beforeCreate在Weex中使用Vue.js - 图70 支持 -
created在Weex中使用Vue.js - 图71 支持 -
beforeMount在Weex中使用Vue.js - 图72 支持 -
mounted在Weex中使用Vue.js - 图73 支持 和 Web 端不完全一样(下文有详解)
beforeUpdate在Weex中使用Vue.js - 图74 支持 -
updated在Weex中使用Vue.js - 图75 支持 -
activated在Weex中使用Vue.js - 图76 不支持 不支持<keep-alive>
deactivated在Weex中使用Vue.js - 图77 不支持 不支持<keep-alive>
beforeDestroy在Weex中使用Vue.js - 图78 支持 -
destroyed在Weex中使用Vue.js - 图79 支持 -
errorCaptured在Weex中使用Vue.js - 图80 支持 在 Vue 2.5.0+, Weex SDK 0.18+ 中新增
关于 "mounted" 生命周期
和浏览不同的是,Weex 的渲染流程是异步 的,而且渲染出来的结果都是原生系统中的 View,这些数据都无法被 javascript 直接获取到。因此在 Weex 上,Vue 的 mounted 生命周期在当前组件的 virtual-dom (Vue 里的 VNode) 构建完成后就会触发,此时相应的原生视图未必已经渲染完成。
### 实例属性
Vue 实例属性 是否支持 说明
--- --- ---
vm.$data在Weex中使用Vue.js - 图81 支持 -
vm.$props在Weex中使用Vue.js - 图82 支持 -
vm.$el在Weex中使用Vue.js - 图83 支持 移动端没有HTMLElement
vm.$options在Weex中使用Vue.js - 图84 支持 -
vm.$parent在Weex中使用Vue.js - 图85 支持 -
vm.$root在Weex中使用Vue.js - 图86 支持 -
vm.$children在Weex中使用Vue.js - 图87 支持 -
vm.$slots在Weex中使用Vue.js - 图88 支持 -
vm.$scopedSlots在Weex中使用Vue.js - 图89 支持 -
vm.$refs在Weex中使用Vue.js - 图90 支持 -
vm.$isServer在Weex中使用Vue.js - 图91 支持 永远是false
vm.$attrs在Weex中使用Vue.js - 图92 支持 -
vm.$listeners在Weex中使用Vue.js - 图93 支持 -
### 实例方法
Vue 实例方法 是否支持 说明
--- --- ---
vm.$watch()在Weex中使用Vue.js - 图94 支持 -
vm.$set()在Weex中使用Vue.js - 图95 支持 -
vm.$delete()在Weex中使用Vue.js - 图96 支持 -
vm.$on()在Weex中使用Vue.js - 图97 支持 -
vm.$once()在Weex中使用Vue.js - 图98 支持 -
vm.$off()在Weex中使用Vue.js - 图99 支持 -
vm.$emit()在Weex中使用Vue.js - 图100 支持 -
vm.$mount()在Weex中使用Vue.js - 图101 不支持 你不需要手动安装 Vue 实例
vm.$forceUpdate()在Weex中使用Vue.js - 图102 支持 -
vm.$nextTick()在Weex中使用Vue.js - 图103 支持 -
vm.$destroy()在Weex中使用Vue.js - 图104 支持 -
### 模板指令
Vue 指令 是否支持 说明
--- --- ---
v-text在Weex中使用Vue.js - 图105 支持 -
v-html在Weex中使用Vue.js - 图106 不支持 Weex 中没有 HTML 解析器,这不是很好的实现
v-show在Weex中使用Vue.js - 图107 不支持 不支持 display: none;
v-if在Weex中使用Vue.js - 图108 支持 -
v-else在Weex中使用Vue.js - 图109 支持 -
v-else-if在Weex中使用Vue.js - 图110 支持 -
v-for在Weex中使用Vue.js - 图111 支持 -
v-on在Weex中使用Vue.js - 图112 支持 不支持事件修饰符在Weex中使用Vue.js - 图113
v-bind在Weex中使用Vue.js - 图114 支持 -
v-model在Weex中使用Vue.js - 图115 支持 -
v-pre在Weex中使用Vue.js - 图116 支持 -
v-cloak在Weex中使用Vue.js - 图117 不支持 只支持单类名选择器
v-once在Weex中使用Vue.js - 图118 支持 -
### 特殊属性
Vue 特殊属性 是否支持 说明
--- --- ---
key在Weex中使用Vue.js - 图119 支持 -
ref在Weex中使用Vue.js - 图120 支持 -
slot在Weex中使用Vue.js - 图121 支持 -
slot-scope在Weex中使用Vue.js - 图122 支持 在 Vue 2.5.0+, Weex SDK 0.18+ 中新增
scope在Weex中使用Vue.js - 图123 支持 不推荐
is在Weex中使用Vue.js - 图124 支持 -
### 内置组件
Vue 内置组件 是否支持 说明
--- --- ---
component在Weex中使用Vue.js - 图125 支持 -
transition在Weex中使用Vue.js - 图126 不支持 在移动端 enter 与 leave 的概念可能有点不同, 并且 Weex 不支持display: none;
transition-group在Weex中使用Vue.js - 图127 不支持 跟 transition 一样
keep-alive在Weex中使用Vue.js - 图128 不支持 移动端的原生组件不能被前端缓存
slot在Weex中使用Vue.js - 图129 支持 -