Weex
基本概念
- 阿里巴巴公司与2016年6月开源的一种用于构建移动跨平台的UI框架
- 基于JS开发框架
- 基于Vue.js
Vue: 一种渐进式 JavaScript框架
- Facebook在2015年3月在F8开发者大会上开源的跨平台UI框架
- 基于JS开发框架
- 基于React.js
React: 用于构建用户界面的 JavaScript 库
Weex和React Native的异同
相同点:
- CSS属性通用
- 都使用JS开发
- 都可以直接在Chrome中调试JS代码
- 需要Node.js基础环境
不同点:
Weex基于Vue.js , 以下是HelloWorld代码示例
<template>
<div class="container">
<div class="cell">
<image class="thumb" src="http://t.cn/RGE3AJt"></image>
<text class="title">JavaScript</text>
</div>
</div>
</template>
<style>
.cell { margin-top: 10; margin-left: 10; flex-direction: row; }
.thumb { width: 200; height: 200; }
.title { text-align: center; flex: 1; color: grey; font-size: 50; }
</style>
React Native基于React.js,以下是HelloWorld代码示例
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
class HelloWorldApp extends Component {
render() {
return (
<Text>Hello world!</Text>
);
}
}
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);
Weex的基本安装
环境搭建:
- 安装Node.js, 命令行输入
brew install node
- 安装weex-toolkit, 命令行输入
npm install -g weex-toolkit
- 检查weex是否安装成功,命令行输入
weex -v
- weex-toolkit也支持直接升级子依赖,命令
weex update weex-devtool@latest
@后标注版本号,latest表示最新的
初始化 Weex 项目:
weex create awesome-project
执行完命令后,在 awesome-project目录中就创建了一个 Weex 和 Vue 的模版项目
源码结构:
package.json:配置开发使用的node_modules依赖,及其它一些设置
start文件:启动程序文件,里面包换编译和启动脚本
examples:示例Demo
android/ios/html: 各平台代码
build:打包各平台的脚本,配置在package.json中。
开发:
cd 进入项目所在路径
- 先通过
npm install
安装项目依赖 -
npm run dev
实现项目编译 -
npm run serve
开启轻量服务器 - 打开浏览器,进入 http://localhost:8080/index.html 即可看到 weex h5 页面
- 初始化时已经创建好了基本的示例,可以在 src/index.vue 中查看。
整体架构
Weex 表面上是一个客户端技术,但实际上它串联起了从本地开发、云端部署到分发的整个链路。
开发者首先可在本地像编写 web 页面一样编写一个 app 的界面,然后通过命令行工具将之编译成一段 JavaScript 代码,生成一个 Weex 的 JS bundle;
在移动应用客户端里,Weex SDK 会准备好一个 JavaScript 执行环境,并且在用户打开一个 Weex 页面时在这个执行环境中执行相应的 JS bundle,并将执行过程中产生的各种命令发送到 native 端进行界面渲染、数据存储、网络通信、调用设备功能及用户交互响应等功能;
同时,如果用户希望使用浏览器访问这个界面,那么他可以在浏览器里打开一个相同的 web 页面,这个页面和移动应用使用相同的页面源代码,但被编译成适合Web展示的JS Bundle,通过浏览器里的 JavaScript 引擎及 Weex SDK 运行起来的。
[图片上传失败...(image-9b3303-1533698804331)]
运行时性能
React 和 Vue 都是非常快的,所以速度并不是在它们之中做选择的决定性因素。
优化
在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,重新渲染整个组件子树。
在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染。你可以理解为每一个组件都已经自动获得了 shouldComponentUpdate,并且没有上述的子树问题限制。
HTML & CSS
在 React 中,一切都是 JavaScript。不仅仅是 HTML 可以用 JSX 来表达,现在的潮流也越来越多地将 CSS 也纳入到 JavaScript 中来处理。这类方案有其优点,但也存在一些不是每个开发者都能接受的取舍。
Vue 的整体思想是拥抱经典的 Web 技术,并在其上进行扩展。
跨平台
ReactNative支持Android,iOS两个平台,需要自己扩展去支持web
Weex可以支持Android,iOS,web三个平台
打包
ReactNative官方只能将ReactNative基础js库和业务js一起打成一个js bundle,没有提供分包的功能,需要制作分包打包工具
Weex默认打的js bundle只包含业务js代码,体积小很多,基础js库包含在Weex sdk中
生命周期
<template>
<div>
<text class="title" v-for="(value, i) in list" :key="i" >{{value}}</text>
</div>
</template>
<style scoped>
.title {font-size: 48px;}
</style>
<script>
var initMessage
module.exports = {
data: function () {
return {
list: ['Lifecycle List']
}
},
init: function () {
initMessage = 'component init: nothing more happen even the data initialization'
console.log('init:', this.list)
},
created: function () {
this.list.push(initMessage)
this.list.push('component created: data observed')
console.log('created:', this.list)
},
mounted: function () {
this.list.push('component mounted: virtual dom generated')
console.log('mounted:', this.list)
}
}
</script>
- 生命周期函数依次为 init 、created 、mounted ,它们和 data 、methods 等属性是平级的;
- init 内一般用于初始化一些内部变量,绑定一些自定义事件,这时还没有数据绑定,没有创建vdom,所以不能通过this获取到data和methods,也不能获取vdom的节点
- created 完成了数据绑定 ,但还未开始编译模板,可以通过this获取data和methods,但不能获取vdom的节点
- mounted 完成了数据绑定和页面布局,可以获取vdom的节点
- data 中应该放数据源,对于复杂的数据对象,建议用
取值 -> 修改 -> 赋值
的方式更新数据,否则可能会导致页面不停刷新; - methods 中可以放需要自定义实现的函数,不需要将生命周期函数放在 methods 中实现;
样式设置
写法一:直接给组件style属性赋值
<template>
<div @click="update">
<text style="font-size: 48px; color: #0000ff">Hello</text>
<text :style="{ fontSize: size, color: color }">Hello</text>
</div>
</template>
写法二:利用class关键字
<template>
<div @click="update">
<text class="a">Hello</text>
<text class="b">Hello</text>
<text :class="['a', x]">Hello</text>
</div>
</template>
<style scoped>
.a {font-size: 48px;}
.b {color: #ff0000;}
</style>
<script>
module.exports = {
data: {
x: ''
},
methods: {
update: function (e) {
this.x = 'b'
console.log('x', this.x)
}
}
}
</script>
- template 只支持一个根节点,多个根节点将无法被
Weex 正常的识别和处理 - 为了简化页面设计和实现,屏幕的宽度统一为 750 像素,不同设备屏幕都会按照比例转化为这一尺寸进行长度计算
- Weex 目前只支持像素,并且 px 单位可以忽略不写,直接使用对应的数值
- 子元素的样式不会继承自父元素,比如 color 和 font-size 等样式作用在 <text> 上层的 <div> 上是无效的
- Weex 只支持了其中的一部分,比如盒模型、flexbox、position 等布局属性,以及 font-size、color 等其它样式
- 通过 style 、 template 、 script 将样式、视图和数据逻辑进行了分离,前端开发经过这么多年的发展,html、css和js的分开编写应当是顺理成章的
事件绑定
使用 @click 关键字声明方法,并在 methods 中实现相应的方法
<template>
<div>
<text class="title">Hello {{name}}</text>
<text class="btn" @click="update">Update 1</text>
<text class="btn" @click="update($event)">Update 1</text>
<text class="btn" @click="setName(temp, $event)">Update 2</text>
<text class="btn" @click="setName('John')">Update 3</text>
</div>
</template>
<style scoped>
.title {font-size: 48px;}
.subtitle {font-size: 36px;}
.btn {font-size: 36px; text-align: center; color: white; background-color: gray; padding: 20px; border-radius: 5px;}
</style>
<script>
module.exports = {
data: function () {
return {
name: 'Steve',
temp: 'Mike'
}
},
methods: {
update: function (e) {
this.setName('David')
console.log('setName', this.name)
},
setName: function (value) {
this.name = value
console.log('name', this.name)
}
}
}
</script>
- {{name}}是Vue.js的数据绑定语法,只要对 name 的值进行了变更,则会立即生效。
- data中定义数据,类似于成员变量,methods定义方法,可以把module.exports看做一个类。
-
<template>
标签中包含一个<div>
标签,给<div>
标签中同级的<text>标签分别绑定一个点击事件,并可以选择传参或者不传;例如:@click="update"点击后会执行update方法,将'David'赋值给变量name,则第一个<text>标签中的文本值随之变化。