# Use Vue.js in Weex
Weex integrated the v2 version of Vue.js since WeexSDK v0.10.0 is released at 2016/02/17. Vue is a progressive front-end framework for building user interfaces. Please refer to its official website for more information.
If there is no special instructions, the "Vue.js" or "Vue" in this article all refers to the v2 version of Vue.js.
# Runtime-only Build
If you are familiar with Vue.js, you should know that there are two available builds of Vue.js: the Runtime + Compiler build and the Runtime-only build. The difference between them is whether to include the compiler which is able to compile the template
option at runtime.
Since the runtime-only builds are roughly 30% lighter-weight than their full-build counterparts (according to Vue's official website), Weex is using the runtime-only build of Vue.js for better performance and less code size.
Specifically, the differences are as follows:
- The
template
option is not supported when defining a component. - Not support
x-templates
. - Not support
Vue.compile
.
# Platform Differences
Vue.js was designed for the Web platform at the beginning. Although it can develop native apps based on Weex, there are still many platform differences between Weex and web.
In short, the key platform differences are running context, DOM API, styles and events.
# Running Context
Weex is mostly used to write multi-page applications, each page is a native View or Activity on mobile, and has its own context. Although Weex is using the same javascript engine virtual machine for each page, but execution context of them are separated by the Sandbox technology of Weex.
You can use BroadcastChannel to communicate between different pages.
In particular, the Vue
variable are different in each pages, and even the "global" config of Vue (Vue.config.xxx
) only affect the single page on Weex.
On this basis, some SPA (single-page application) technologies of Vue, such as Vuex and vue-router will also take effect within the single page. More colloquially, the "page" concept is virtual in SPA technologies, but it is real on Weex. However, Vuex and vue-router are standalone libraries, they all have their own concept and usage scenario, you can still use Vuex and vue-router on Weex.
# DOM
Because there is no DOM (document object model) on Android and iOS, if you are manipulating and generating DOM elements manually, it may have some compatibility issues. It is a good practice to manipulate data and components instead of generated elements when you are using modern front-end frameworks.
Some DOM-related features, such as v-html
, vm.$el
, template
option, may not have the same behavior on different platforms.
To be more specific, the type of vm.$el
property is HTMLElement
on the web, but it is not that type on mobile environments. Actually it's a special data structure defined by Weex document object model.
# Styles
The style sheet and CSS rules in managed by Weex js framework and native render engines. It would be very difficult and unnecessary to implement the whole CSSOM spec and support all CSS rules.
For performance reasons, Weex only support single class selector currently, and only support a subset of CSS Rules. Please refer to common styles and text styles for more details.
In Weex, styles are scoped by force for each Vue component.
# Events
Event bubbling and capturing are not supported in Weex currently, therefore, event modifiers such as .prevent
, .capture
, .stop
, .self
are not supported on Weex native components.
Moreover, the keyboard event modifiers and system modifier keys, such as .enter
, .tab
, .ctrl
, .shift
mostly are meaningless on mobile device, which are also not supported in Weex.
# The Web Renderer
If you want to render your page on the web, you need to require the vue-render-for-apache-weex to achieve it.
WARNING
vue-render-for-apache-weex
is a third party plugin, and is not developed nor maintained by Apache Weex
vue-render-for-apache-weex
is a web renderer for Vue DSL, it implemented the built-in components and built-in modules of Weex on the web. Please refer to its repo for more details.
# Single File Component
Single file component (as known as the *.vue
files) of Vue is a special file format with a .vue
extension. The template inside will be compiled into the render
function at build time.
Moreover, there are a good deals of syntax highlight plugins for all kind of editors.
TIP
It's a good practice to use single file component syntax in Weex.
Because the compiler tools are different between Weex and Vue, you have to handle all these platform differences if you are writing render
function manually.
# Compile Targets
Because of the platform difference and to improve the performance on the web, the *.vue
file should be compiled in two different ways:
- For the web platform, you can compile source files in any official way, such as Webpack + vue-loader or Browserify + vueify.
- For Android and iOS platforms, you should use weex-loader to compile the
*.vue
files.
Use different bundles for different platforms is to make good use of the platform original features and reduce compatibility code at build time. But the source code is still the same, the only difference is the way to compile it.
# Use weex-loader
weex-loader is a loader of webpack that can transform *.vue
file into a plain javascript module for Android and iOS platform. All features and configurations of it are same with vue-loader (v14).
One thing should be noted that if the entry option of your Webpack config is a *.vue
file, you also need to pass an additional entry
parameter.
const webpackConfig = {
// Add the entry parameter for the .vue file
entry: './path/to/App.vue?entry=true'
/* ... */
use: {
loaders: [{
// matches the .vue file path which contains the entry parameter
test: /\.vue(\?^^]+)?$/,
loaders: ['weex-loader']
}]
}
}
You don't need to write those additional parameters if you are using .js
file as entry file. It's a good practice to using javascript file as the entry file of webpack config.
{
entry: './path/to/entry.js'
}
TIP
Always use javascript file as the entry file.
Example of using weex-loader compile targets
- execute
npm init
in terminal - update
package.json
,add belows content into it
"dependencies": {
"babel-loader": "^8.0.6",
"weex-loader": "^0.7.12",
"webpack": "^2.2.1"
},
"scripts": {
"build": "webpack --config webpack.config.js"
},
- create
webpack.config.js
,modify<your-input-file>
and<your-output-file>
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: '<your-input-file>',
output: {
path: path.resolve(__dirname, './'),
filename: <your-output-file>
},
module: {
rules: [
{
test: /\.vue(\?[^?]+)?$/,
loaders: ['weex-loader']
},
{
test: /\.js$/,
loaders: ['babel-loader']
}
]
},
plugins: [
new webpack.BannerPlugin({
raw: true ,
banner: '// { "framework": "Vue" }\n'
})
]
}
- execute
npm run build
in terminal - Done
Example of using weex-cli compile targets
- install weex-cli:
npm install weex-toolkit -g
- execute
weex compile [resource file] [product address]
- Done
# Supported Features
# Global Config
The Vue "Global" config only affect the single page on Weex, the configuration will not be shared between different Weex pages.
Vue Global Config | Supported | Notes |
---|---|---|
Vue.config.silent | Yes | - |
Vue.config.optionMergeStrategies | Yes | - |
Vue.config.devtools | No | Only supported on the web. |
Vue.config.errorHandler | Yes | - |
Vue.config.warnHandler | Yes | - |
Vue.config.ignoredElements | Yes | Not Recommend. |
Vue.config.keyCodes | No | Useless on the mobile. |
Vue.config.performance | No | Same with devtools. |
Vue.config.productionTip | Yes | - |
# Global API
Vue Global API | Supported | Notes |
---|---|---|
Vue.extend | Yes | - |
Vue.nextTick | Yes | - |
Vue.set | Yes | - |
Vue.delete | Yes | - |
Vue.directive | Yes | - |
Vue.filter | Yes | - |
Vue.component | Yes | - |
Vue.use | Yes | - |
Vue.mixin | Yes | - |
Vue.version | Yes | - |
Vue.compile | No | Weex is using the runtime-only build. |
# Options
Vue Option | Supported | Notes |
---|---|---|
data | Yes | - |
props | Yes | - |
propsData | Yes | - |
computed | Yes | - |
methods | Yes | - |
watch | Yes | - |
el | Yes | The value of el is meaningless on the mobile. |
template | No | Weex is using the runtime-only build. |
render | Yes | Not Recommend. |
renderError | Yes | - |
directives | Yes | - |
filters | Yes | - |
components | Yes | - |
parent | Yes | Not Recommend. |
mixins | Yes | - |
extends | Yes | - |
provide/inject | Yes | Not Recommend. |
name | Yes | - |
delimiters | Yes | Not Recommend. |
functional | Yes | - |
model | Yes | - |
inheritAttrs | Yes | - |
comments | No | - |
# Lifecycle Hooks
Instance lifecycle hooks of Vue components will be emitted at particular stages, refer to the lifecycle diagram of Vue component for more details.
Vue Lifecycle Hook | Supported | Notes |
---|---|---|
beforeCreate | Yes | - |
created | Yes | - |
beforeMount | Yes | - |
mounted | Yes | Not exactly the same with web. (See the following tips) |
beforeUpdate | Yes | - |
updated | Yes | - |
activated | No | Not support <keep-alive> yet. |
deactivated | No | Not support <keep-alive> yet. |
beforeDestroy | Yes | - |
destroyed | Yes | - |
errorCaptured | Yes | New in Vue 2.5.0+, Weex SDK 0.18+ |
About the "mounted" lifecycle.
Unlike browsers, the render process of Weex is asynchronous by default and the render result are all native views which can't be accessed by javascript directly. So the mounted
lifecycle will be emitted once the virtual-dom (VNode
of Vue) is constructed, at that time, the corresponding native views many not rendered finish yet.
# Instance Properties
Vue Instance Property | Supported | Notes |
---|---|---|
vm.$data | Yes | - |
vm.$props | Yes | - |
vm.$el | Yes | The value is not HTMLElement on the mobile. |
vm.$options | Yes | - |
vm.$parent | Yes | - |
vm.$root | Yes | - |
vm.$children | Yes | - |
vm.$slots | Yes | - |
vm.$scopedSlots | Yes | - |
vm.$refs | Yes | - |
vm.$isServer | Yes | Always false . |
vm.$attrs | Yes | - |
vm.$listeners | Yes | - |
# Instance Methods
Vue Instance Method | Supported | Notes |
---|---|---|
vm.$watch() | Yes | - |
vm.$set() | Yes | - |
vm.$delete() | Yes | - |
vm.$on() | Yes | - |
vm.$once() | Yes | - |
vm.$off() | Yes | - |
vm.$emit() | Yes | - |
vm.$mount() | No | You don't need to mount Vue instance manually. |
vm.$forceUpdate() | Yes | - |
vm.$nextTick() | Yes | - |
vm.$destroy() | Yes | - |
# Directives
Vue Directive | Supported | Notes |
---|---|---|
v-text | Yes | - |
v-html | No | No HTML parser in Weex, and it is not good practice. |
v-show | No | Not support display: none; yet. |
v-if | Yes | - |
v-else | Yes | - |
v-else-if | Yes | - |
v-for | Yes | - |
v-on | Yes | Not support event modifiers. |
v-bind | Yes | - |
v-model | Yes | - |
v-pre | Yes | - |
v-cloak | No | Only support single class selector. |
v-once | Yes | - |
# Special Attributes
Vue Special Attribute | Supported | Notes |
---|---|---|
key | Yes | - |
ref | Yes | - |
slot | Yes | - |
slot-scope | Yes | New in Vue 2.5.0+, Weex SDK 0.18+ |
scope | Yes | Not Recommend. |
is | Yes | - |
# Built-In Components
Vue Built-In Component | Supported | Notes |
---|---|---|
component | Yes | - |
transition | No | The concept of enter and leave maybe different on the mobile, and Weex does not support display: none; yet. |
transition-group | No | Same with transition. |
keep-alive | No | Native components on the mobile can not be cached at front-end. |
slot | Yes | - |