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:

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 weex-vue-render to achieve it.

weex-vue-render 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

  1. execute npm init in terminal
  2. 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"
  },
  1. 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'
		})
	]
}
  1. execute npm run build in terminal
  2. Done

Example of using weex-toolkit compile targets

  1. install weex-toolkitnpm install weex-toolkit -g
  2. execute weex compile [resource file] [product address]
  3. 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 ConfigSupportedNotes
Vue.config.silentYes-
Vue.config.optionMergeStrategiesYes-
Vue.config.devtoolsNoOnly supported on the web.
Vue.config.errorHandlerYes-
Vue.config.warnHandlerYes-
Vue.config.ignoredElementsYesNot Recommend.
Vue.config.keyCodesNoUseless on the mobile.
Vue.config.performanceNoSame with devtools.
Vue.config.productionTipYes-

Global API

Vue Global APISupportedNotes
Vue.extendYes-
Vue.nextTickYes-
Vue.setYes-
Vue.deleteYes-
Vue.directiveYes-
Vue.filterYes-
Vue.componentYes-
Vue.useYes-
Vue.mixinYes-
Vue.versionYes-
Vue.compileNoWeex is using the runtime-only build.

Options

Vue OptionSupportedNotes
dataYes-
propsYes-
propsDataYes-
computedYes-
methodsYes-
watchYes-
elYesThe value of el is meaningless on the mobile.
templateNoWeex is using the runtime-only build.
renderYesNot Recommend.
renderErrorYes-
directivesYes-
filtersYes-
componentsYes-
parentYesNot Recommend.
mixinsYes-
extendsYes-
provide/injectYesNot Recommend.
nameYes-
delimitersYesNot Recommend.
functionalYes-
modelYes-
inheritAttrsYes-
commentsNo-

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 HookSupportedNotes
beforeCreateYes-
createdYes-
beforeMountYes-
mountedYesNot exactly the same with web. (See the following tips)
beforeUpdateYes-
updatedYes-
activatedNoNot support <keep-alive> yet.
deactivatedNoNot support <keep-alive> yet.
beforeDestroyYes-
destroyedYes-
errorCapturedYesNew 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 PropertySupportedNotes
vm.$dataYes-
vm.$propsYes-
vm.$elYesThe value is not HTMLElement on the mobile.
vm.$optionsYes-
vm.$parentYes-
vm.$rootYes-
vm.$childrenYes-
vm.$slotsYes-
vm.$scopedSlotsYes-
vm.$refsYes-
vm.$isServerYesAlways false.
vm.$attrsYes-
vm.$listenersYes-

Instance Methods

Vue Instance MethodSupportedNotes
vm.$watch()Yes-
vm.$set()Yes-
vm.$delete()Yes-
vm.$on()Yes-
vm.$once()Yes-
vm.$off()Yes-
vm.$emit()Yes-
vm.$mount()NoYou don't need to mount Vue instance manually.
vm.$forceUpdate()Yes-
vm.$nextTick()Yes-
vm.$destroy()Yes-

Directives

Vue DirectiveSupportedNotes
v-textYes-
v-htmlNoNo HTML parser in Weex, and it is not good practice.
v-showNoNot support display: none; yet.
v-ifYes-
v-elseYes-
v-else-ifYes-
v-forYes-
v-onYesNot support event modifiers.
v-bindYes-
v-modelYes-
v-preYes-
v-cloakNoOnly support single class selector.
v-onceYes-

Special Attributes

Vue Special AttributeSupportedNotes
keyYes-
refYes-
slotYes-
slot-scopeYesNew in Vue 2.5.0+, Weex SDK 0.18+
scopeYesNot Recommend.
isYes-

Built-In Components

Vue Built-In ComponentSupportedNotes
componentYes-
transitionNoThe concept of enter and leave maybe different on the mobile, and Weex does not support display: none; yet.
transition-groupNoSame with transition.
keep-aliveNoNative components on the mobile can not be cached at front-end.
slotYes-
Last Updated: 8/7/2019
Excellent docUnusable doc