Weex 初探

Weex 初探

Weex 介紹

Weex 是阿里於 2016 年開源的一款開發框架,它的介紹是:javascript

Weex 是一個使用 Web 開發體驗來開發高性能原生應用的框架。css

它使用了 Web 技術來開發 Android、IOS 應用,從而達到更快的迭代速度,同時下降了開發原生應用的門檻,
達到生產力和性能共存。html

Weex 項目結構

Weex 設計之初是爲了和原有應用進行兼容開發,和 NativeScript 不一樣,它只須要在項目中添加 Weex 的 SDK 便可使用。
它的定位不是所有應用,目標是針對部分變更頻繁的應用。它是一種解耦的應用,每一個頁面相對獨立,經過路由的方式對調用各頁面,
經過 API 的方式與設備進行交互。因此能夠看到官網上 Weex 的結構圖:前端

weex 結構圖

weex工程結構

使用 Weex 構建一個簡單的應用

Weex 作一個簡單一些的例子仍是比較合適的。本文以仿開眼部分功能爲例作一小應用。先看下效果圖:vue

應用效果圖

項目搭建前準備工做

首先須要準備好 npm 環境、Android 環境,IOS 環境,因爲在 mac 下直接安裝 xcode 就具有 IOS 環境了,且 npm 是前端必備開發環境的,就無需再安裝了。Android 環境的安裝能夠直接安裝 Android Studio,一鍵配置好環境。java

打開控制檯,全局安裝 weexreact

npm i -g weex-toolkit weex weex-debugger

建立項目:android

weex create weex-kaiyan
cd weex-kaiyan
weex platform add android
weex platform add ios

按照提示操做便可。安裝速度都不是很快,須要耐心等候。爲了方便開發,咱們採用 airbnb 的代碼規範,先在 devDependencies 安裝相關依賴(或者全局安裝eslint,用 eslint 的init 功能也能夠):webpack

"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 中添加ios

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 雖然已經開源很久了, 有時間能夠嘗試下,不過因爲核心模塊沒有開源,好多組件不能使用,先觀望一段時間,等有好的點子再試試。

相關文章
相關標籤/搜索