Weex 初探
Weex 初探
Weex 介绍
Weex 是阿里于 2016 年开源的一款开发框架,它的介绍是:
Weex 是一个使用 Web 开发体验来开发高性能原生应用的框架。
它使用了 Web 技术来开发 Android、IOS 应用,从而达到更快的迭代速度,同时降低了开发原生应用的门槛,
达到生产力和性能共存。
Weex 项目结构
Weex 设计之初是为了和原有应用进行兼容开发,和 NativeScript 不同,它只需要在项目中添加 Weex 的 SDK 即可使用。
它的定位不是全部应用,目标是针对部分变动频繁的应用。它是一种解耦的应用,每个页面相对独立,通过路由的方式对调用各页面,
通过 API 的方式与设备进行交互。所以可以看到官网上 Weex 的结构图:


使用 Weex 构建一个简单的应用
Weex 做一个简单一些的例子还是比较合适的。本文以仿开眼部分功能为例做一小应用。先看下效果图:

项目搭建前准备工作
首先需要准备好 npm 环境、Android 环境,IOS 环境,由于在 mac 下直接安装 xcode 就具备 IOS 环境了,且 npm 是前端必备开发环境的,就无需再安装了。Android 环境的安装可以直接安装 Android Studio,一键配置好环境。
打开控制台,全局安装 weex
npm i -g weex-toolkit weex weex-debugger
创建项目:
weex create weex-kaiyan
cd weex-kaiyan
weex platform add android
weex platform add ios
按照提示操作即可。安装速度都不是很快,需要耐心等候。为了方便开发,我们采用 airbnb 的代码规范,先在 devDependencies 安装相关依赖(或者全局安装eslint,用 eslint 的init 功能也可以):
"eslint": "^4.13.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-friendly-formatter": "^3.0.0",
"eslint-import-resolver-webpack": "^0.8.3",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-vue": "^4.0.0",
在 .eslintrc.js 中添加
extends: ['plugin:vue/recommended', 'airbnb-base'],
在 vscode 中启用 lint 功能:
"eslint.validate": [
"javascript",
"javascriptreact",
"html",
"vue"
],
"eslint.options": {
"plugins": ["html"]
},
然后准备好要访问的 api (https://github.com/kaikaixue/Eyepetizer/blob/master/app/src/main/java/com/xk/eyepetizer/api),这样做完了准备工作,可以开始开发了。
目录结构大概是这样子:
├── README.md
├── android.config.json
├── configs
│ ├── config.js
│ ├── helper.js
│ ├── logo.png
│ ├── plugin.js
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.common.conf.js
│ ├── webpack.dev.conf.js
│ ├── webpack.prod.conf.js
│ └── webpack.test.conf.js
├── ios.config.json
├── npm-shrinkwrap.json
├── package.json
├── platforms
│ ├── android
│ ├── ios
│ └── platforms.json
├── plugins
│ └── plugins.json
├── src
│ ├── api
│ │ └── index.js
│ ├── components
│ │ ├── card-list-scroller.vue
│ │ ├── card-video-no-author.vue
│ │ ├── card-video.vue
│ │ └── tab.vue
│ ├── entry.js
│ ├── index.vue
│ ├── mixin-common.js
│ ├── mixin-preload.js
│ ├── mixin-router.js
│ ├── router.js
│ └── views
│ ├── categories.vue
│ ├── categoryHome.vue
│ ├── home.vue
│ ├── rank.vue
│ └── videoDetail.vue
├── web
│ ├── assets
│ │ ├── preview.css
│ │ └── qrcode.js
│ ├── index.html
│ └── preview.html
└── webpack.config.js
其中 config 文件下是用于放 webpack 打包的配置, src 就是我们的代码目录,platform 里面放 native 代码,
web 文件夹是我们的 web 的 html 模板。
项目配置
要实现三端开发,默认的 weex 项目模板是不行的,它的设计是为 Native 准备的,不考虑单页应用的方式。
虽然不推荐三端同时开发(兼容三端效率会比较低),但为研究怎么实现我们还是做一下。先安装单页应用必备 vue-router
修改 entry.js
然后修改 src/entry.js ,添加手动挂载 vue 的代码,假定我们 src 目录下有个 router.js,
还有一个所有文件用的mixin,修改完成后的代码如下:
import Vue from 'vue';
import weex from 'weex-vue-render';
import App from './index.vue';
import router from './router';
import mixin from './mixin-router';
weex.init(Vue);
Vue.mixin(mixin);
App.el = '#root';
App.router = router;
const app = new Vue(App);
export default app;
在 native 端这个 entry.js 是没用的,native 端是直接使用由 weex 打包生成的 js 文件,
包括挂载都是框架做的,我们不需要处理,所以它只是给 web 使用的。
设置入口
然后设置主入口:build/webpack.common.conf.js中webEntry为固定值:
const webEntry = {
'index': helper.rootNode(config.entryFilePath)
};
同时注释掉读取文件内容并注入entry中
// if (extname === '.vue') {
// const entryFile = path.join(vueWebTemp, dir, path.basename(file, extname) + '.js');
// fs.outputFileSync(path.join(entryFile), getEntryFileContent(entryFile, fullpath));
// webEntry[name] = path.join(entryFile) + '?entry=true';
// }
添加代理
在 webpack 中添加代理,由于 web 端有跨域问题,我们在 configs/config.js 中添加
proxyTable: {
'/api': {
target: 'https://baobab.kaiyanapp.com/',
changeOrigin: true,
}
},
编写代码
公用模块
现在开始像正常写 vue 一样开始码代码吧。要先注意的一点是 native 端不支持 vue-router 的特性,
需要使用 navigator 模块进行 push 操作,所以我们需要单独写个模块,通过 mixin 方式进行兼容 页面跳转,
参考 https://www.jianshu.com/p/497f1a9ff33f:
const isWeex = weex.config.env.platform.toLowerCase() !== 'web';
const nav = weex.requireModule('navigator');
export default {
methods: {
push(path, option = {}) {
if (isWeex) {
const toUrl = weex.config.bundleUrl.split('/').slice(0, -1).join('/') + '/' + path.replace(/^\//, '') + '.js';// 将a.js的绝对地址转为b.js的绝对地址
nav.push({
url: toUrl,
animated: option.animated || 'true',
});
} else {
this.$router.push(path);// 使用vue-router
}
},
pop(option = {}) {
if (isWeex) {
nav.pop({
animated: option.animated || 'true',
});
} else {
window.history.back();
}
},
},
};
这样我们在写跳转时候就可以写成:
this.push('/videoDetail')
同时准备好你需要的 api 库模块(我用的 axios),以及其他公众模块,比如说 storage 。Weex 中的 Storage 模块是为了兼容 web 版本,接口和 web 版本的 LocalStorage 比较类似,只是异步形式。为方便,我们可以将回调式转为 Promise 式:
function callStorage(type) {
return function callMethod(...args) {
const storage = this.$storage;
return new Promise((resolve, reject) => {
const callback = (e) => {
if (e && e.result === 'success') {
resolve(e.data);
} else {
reject(e);
}
};
storage[type].call(storage, ...args, callback);
});
};
}
class Storage {
constructor() {
this.$storage = weex.requireModule('storage');
}
setItem = callStorage('setItem')
getItem = callStorage('getItem')
removeItem = callStorage('removeItem')
}
然后在 Mixin 中使用它即可。如果你有精力的话,可以设计一个基于 storage 的数据传递模块。
开发页面
开发页面就和写 vue 一样啦,只是要注意一些点:
- Weex 支持的元素类型是有限的,用到哪种需要到官网手册中去查询
- 每个页面是独立,一定要记住这一点,因此 mixin 之类的公用库,需要手动引入到页面中
- css 选择器只支持一级,比如 .classA 不支持 .classA .classB 这种类型,你需要为设置样式的每个元素添加 className,需要防止变量冲突(web 端是单页应用,可能会有问题)
Native 端配置
包括在开发阶段,我们也是需要对 native 端进行效果验证的。Weex 提供了一个简单的命令:
weex run android
weex run ios
npm run dev
如果已经配置了 IOS 环境,直接运行命令就可以了。不过默认的主页是 index.js,
可以在 android.config.json 和 ios.config.json 中分别配置 WeexBundle 选项即可。
需要注意的是,运行状态下默认是打开本地文件的,而运行命令是不会放 views 文件夹目录过去,
需要手动拷贝一下。安卓下面由于访问本地文件的接口在 7.0 下有问题,
建议在 app_config.xml 中修改 launch_locally 为 false, 并指定好远程地址。
调试没问题后,我们按照 Android 和 IOS 各自的方案进行打包即可.
总结
由于自己对 Native 开发了解得不多,所以好多东西一知半解,而且 Weex 的包总能发现各种小问题,
需要强大的耐心去解决或者规避这些问题,只能祝使用的人好运吧。新出的 weex-ui 虽然已经开源好久了,
有时间可以尝试下,不过由于核心模块没有开源,好多组件不能使用,先观望一段时间,等有好的点子再试试。
Weex 初探的更多相关文章
- 【如花美眷】初探weex
我想我更喜欢weex的原因,应该是weex可以直接运行在浏览器中,而不是像react-native需要运行在模拟设备中. 我想这个原因足以让我使用vue而不是RN. 初探就是稍微运行一下,来看步骤 可 ...
- React Native初探
前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...
- 最火移动端跨平台方案盘点:React Native、weex、Flutter
1.前言 跨平台一直是老生常谈的话题,cordova.ionic.react-native.weex.kotlin-native.flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头. ...
- 初探领域驱动设计(2)Repository在DDD中的应用
概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...
- ReactNative&weex&DeviceOne对比
React Native出来有一段时间了,国内的weex和deviceone是近期发布的,我可以说从2011年就开始关注快速开发的跨平台平台技术了,接触过phoneGap.数字天堂.appcan等早期 ...
- CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探
CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...
- 阿里的weex框架到底是什么
title: 阿里的weex框架到底是什么 date: 2016-09-27 10:22:34 tags: vue, weex category: 技术总结 --- weex 工作原理 首先看下官方的 ...
- 从273二手车的M站点初探js模块化编程
前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...
- JavaScript学习(一) —— 环境搭建与JavaScript初探
1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...
随机推荐
- qt中的事件机制
事件 1.QEvent -->类型 -> QKeyEvent QEvent::KeyRelease QEvent::MouseMove -> QMouseEvent 2.事件处理过程 ...
- docker设置固定ip地址
Docker安装后,默认会创建下面三种网络类型 $ docker network ls NETWORK ID NAME DRIVER SCOPE 9781b1f585ae bridge bridge ...
- R语言-来自Prosper的贷款数据探索
案例分析:Prosper是美国的一家P2P在线借贷平台,网站撮合了一些有闲钱的人和一些急用钱的人.用户若有贷款需求,可在网站上列出期望数额和可承受的最大利率.潜在贷方则为数额和利率展开竞价. 本项目拟 ...
- NOIP2017滚粗记
NOIP2017滚粗记 扯淡 考完联赛后一直在搞文化... 联赛过去了不知道多少天了才来写这东西.... Day0 早自习知道了要期中考试. 感觉心态炸裂了. 上午在乱敲板子.... 打了一堆莫名其妙 ...
- [bzoj2286][Sdoi 2011]消耗战
[bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...
- eslint规则
碰到eslint报错, 把错误的提示拷贝在这里Ctrl + F找到复制到eslint.js里面就行了. "off"或者0,不启用这个规则 "warn"或者1,出 ...
- IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理
1.前言 一个安全的信息系统,合法身份检查是必须环节.尤其IM这种以“人”为中心的社交体系,身份认证更是必不可少. 一些PC时代小型IM系统中,身份认证可能直接做到长连接中(也就是整个IM系统都是以长 ...
- puppeteer,新款headless chrome!
puppeteer puppeteer是一种谷歌开发的Headless Chrome,因为puppeteer的出现,业内许多自动化测试库停止维护,比如PhantomJS,Selenium IDE fo ...
- R学习笔记:了解R的使用
R是一种区分大小写的解释性语言,只支持单行注释,注释由符号#开头,当前行出现在#之后的任何文本都会被R解释器忽略.R脚本的一次执行叫做一个会话(Session),可以通过函数quit()退出当前的会话 ...
- MySQL主从复制_复制过滤
关于主从过滤,建议只在从服务器做设定,在Master 端为保证二进制日志的完整, 不建议使用二进制日志过滤. Master 可用参数: binlog-do-db= #定义白名单,仅将制定数据库的相关操 ...