A simple tutorial for Weex

Jinjiang Zhao
6 min readApr 28, 2016

--

update: For some personal reasons I am not in Weex team any more (Sorry for that). And Weex has been donated and moved to Apache Foundation. You can open an issue, make a PR or find more information about Weex there.

What is Weex?

Weex is a cross-platform mobile app UI solution. It works well in iOS and Android. Developers can just write template/CSS/JavaScript once to build native UI as fast as possible. In addition, Weex has a HTML5 port. If there’s no native way to show this, it can also be rendered in a browser/WebView.

http://alibaba.github.io/weex/

The syntax of Weex is deeply inspired from Vue.js, a very powerful but lightweight and high-perf JavaScript framework, which has announced v2.0 preview this week.

Well, let’s start.

Have a Look

First, download Weex Playground App for Android. The app will provide a Weex render engine and some examples written by Weex.

Weex Playground App in the left-bottom corner
First sight of Weex Playground App

You can just have a try to click the items to open a Weex example. We support some basic native components like <text>, <image>, <slider> etc. At the same time, you can open the “List (Advanced)” example to see the perf of Weex in Android. All these examples are written of template/CSS/JavaScript but very fast and smooth than the browser/WebView.

You must ask how I can write them own? Yes you can. I will show you how to do this and introduce how it works during the show.

Have a Try

At the beginning, you need a Node.js tool named weex-toolkit in npm. Just have Node.js and run npm install -g weex-toolkit in your local machine and finish it.

$ npm install -g weex-toolkit

> websocket@1.0.22 install /usr/local/lib/node_modules/weex-toolkit/node_modules/websocket
> (node-gyp rebuild 2> builderror.log) || (exit 0)

CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
SOLINK_MODULE(target) Release/bufferutil.node
CXX(target) Release/obj.target/validation/src/validation.o
SOLINK_MODULE(target) Release/validation.node
/usr/local/bin/weex -> /usr/local/lib/node_modules/weex-toolkit/bin/weex.js
weex-toolkit@0.0.22 /usr/local/lib/node_modules/weex-toolkit
├── opener@1.4.1
├── node-watch@0.3.5
├── underscore@1.8.3
├── qrcode-terminal@0.10.0
├── yargs@3.32.0 (decamelize@1.2.0, camelcase@2.1.1, y18n@3.2.1, window-size@0.1.4, os-locale@1.4.0, cliui@3.2.0, string-width@1.0.1)
├── lie@3.0.2 (immediate@3.0.5, inline-process-browser@1.0.0, unreachable-branch-transform@0.3.0, es3ify@0.1.4)
├── fs-extra@0.26.7 (path-is-absolute@1.0.0, klaw@1.2.0, jsonfile@2.3.0, graceful-fs@4.1.3, rimraf@2.5.2)
├── websocket@1.0.22 (yaeti@0.0.6, nan@2.0.9, typedarray-to-buffer@3.0.5, debug@2.2.0)
├── weex-transformer@0.3.1 (printf@0.2.3, weex-templater@0.2.1, md5@2.1.0, parse5@2.1.5, chalk@1.1.3, commander@2.9.0, weex-styler@0.0.17, weex-scripter@0.1.4)
└── http-server@0.8.5 (corser@2.0.0, colors@1.0.3, optimist@0.6.1, http-proxy@1.13.2, union@0.4.4, ecstatic@0.7.6, portfinder@0.4.0)
$

After installation, you can get a cli tool named weex.

This cli could build your Weex file to JavaScript which can be requested by Weex Playground App. you can just create a local file named live.we:

<template>
<div>
<text>Hello World!</text>
</div>
</template>

and when run:

weex live.we

Now you may see a QRCode in your terminal screen (you can adjust the terminal font size to assure its visibility). Now look back to Weex Playground App, you may found a qr-scan icon in the right-top corner. Click it and scan the QRCode. You already open it!

Now let’s do something more. We add some style to make the text larger:

<template>
<div>
<text style="font-size: 48px;">Hello World!</text>
</div>
</template>
Hello World

And save the file. You will see the Playground App Refreshed! Yes the Weex cli will watch the file changing and use websocket to tell Playground App to refresh. So the text has already been larger.

It’s all HTML and CSS syntax here. The template describes the UI structure by tag name, attributes, style, text content and child nodes. And the style attribute shows the detail style.

We go on to add class, event, <script> and data-binding:

<template>
<div class="wrapper" onclick="update">
<image class="thumb" src="http://alibaba.github.io/weex/img/weex_logo_blue@3x.png"></image>
<text style="font-size: 48px;">Hello {{who}}!</text>
</div>
</template>

<style>
.wrapper {align-items: center; margin-top: 80px;}
.thumb {width: 360px; height: 82px;}
</style>

<script>
module.exports = {
data: function () {
return {who: 'World'}
},
methods: {
update: function (e) {
this.who = 'Weex'
}
}
}
</script>
<image> + <text> with flexbox layout

Save it and let it refresh, you would see a Weex logo and text “Hello World!” in the center. The <style> tag provides all styles connected to <template> with its class names. It’s aligned by CSS flexbox layout property align-items.

The text content has data-binding with data who, which is defined in <script>. The <script> exports everything through module.exports. When click/tap the screen, a method named foo will be fired to change the value of who. So the rendering result becomes “Hello Weex!”

With this case you know how to write <template>, <style> and <script>. And how to write tags, attributes, style, events, data-binding, methods …

Next is display logic. We provide two often-used display logic: if and repeat:

<template>
<div>
<text repeat="list" if="value % 2" style="font-size: 48px;">
{{value}}
</text>
</div>
</template>
<script>
module.exports = {
data: function () {
return {
list: [{value: 1}, {value: 2}, {value: 3}, {value: 4}, {value: 5}]
}
}
}
</script>
repeat and if directives in Weex

In this case both repeat=”list” and repeat=”{{list}}” is ok. So does if=”…”. This case will show three piece of text “1 3 5”.

If you want to build more complex UI. We recommend you use custom components. To try this, you could create another file named foo.we and write it with:

<!-- foo.we -->
<template>
<text style="font-size: 48px; color: {{color}}">{{content}}</text>
</template><script>
module.exports = {
data: function () {
return {
color: '', content: ''
}
}
}
</script>

and use <foo> element in main file live.we:

<template>
<div>
<foo color="#ff0000" content="Hello foo component"></foo>
</div>
</template>

also you can repeat the custom component and pass data through.

<template>
<div>
<foo repeat="list" color="{{a}}" content="Hello {{b}}"></foo>
</div>
</template>

<script>
module.exports = {
data: function () {
return {
list: [
{a: '#ff0000', b: 'Yellow'},
{a: '#00ff00', b: 'Green'},
{a: '#0000ff', b: 'Blue'}
]
}
}
}
</script>

How the *.we files work?

In the back, actually, weex-toolkit transform the template/CSS into javascript first, and combines <script> content together to build a JS Bundle out. For exmple:

<template>
<div>
<text style="color: #ff0000" class="a">Hello {{who}}</text>
</div>
</template>
<style>
.a {font-size: 48px;}
</style>
<script>
module.exports = {
data: function () {
return {
who: 'World'
}
}
}
</script>

will be transformed into:

// origin script code
module.exports = {
data: function () {
return {
who: 'World'
}
}
}

// style content into JSON
module.exports.style = {a: {fontSize: 48}}

// template content into JavaScript object
module.exports.template = {
type: 'div',
children: [{
type: 'text',
style: {color: '#ff0000'},
attr: {value: function () {return 'Hello ' + this.who}}
}]
}

And this code is easy to run in a JavaScript environment. So actually at the runtime. We don’t need HTML parser or CSS parser, we just need a JavaScript engine. The QRCode generated by weex-toolkit is actually the URL of the temp JS Bundle file. If you are familiar with this format of JS Bundle, you can even write JS Bundle directly, make a QRCode of the JS Bundle file, and use Playground App to scan it to preview.

That’s Weex. We have more native component, style and features to be public and open source soon. Before this happen, if you apply for access in the website. You will have opportunity to get it as a private repo invitation today.

Please Enjoy!

--

--