weex官方demo weex-hackernews代碼解讀(上)


一、介紹

weex 是阿里出品的一個類似RN的框架,可以使用前端技術來開發移動應用,實現一份代碼支持H5,IOS和Android。最新版本的weex已默認將vue.js作為前端框架,而weex-hacknews則是weex官方出品的,首個使用 Weex 和 Vue 開發的 Hacker News 原生應用,在項目中使用了 Vuex 和 vue-router等官方組件 。因此這個應用可以作為weex-vue開發的典范,分析該項目代碼可以了解如何使用weex技術棧進行開發,實現同一份代碼在 iOS、Android、Web 下都能完整地工作。

1、下載

下載地址:https://github.com/weexteam/weex-hackernews

使用git clone項目或者直接下載zip包

2、安裝

安裝依賴:

npm install

編譯代碼:

npm run build

啟動 Web 服務

npm run serve

   

3、訪問

啟動服務后會監聽 1337 端口,訪問 http://127.0.0.1:1337/index.html 即可在瀏覽器中預覽頁面。

Chrome瀏覽器打開,F12進入開發者模式,啟用手機模擬,可以看到如下的效果

3.1 首頁

   

3.2 評論頁

   

更多的請自行安裝體驗。

   

二、代碼分析

   

將項目里的src導入到IDE里,可以看到代碼結構如下:

   

   

1、簡單說明

  1. components ——vue組件
  2. views ——視圖
  3. store ——Vuex
  4. mixins——擴展
  5. filters——vue.js 的filter
  6. App.vue 主UI界面
  7. entry.js 入口程序
  8. router.js ——vue-router

   

2、入口程序

上代碼:

   

該段代碼主要實現將各個組件和擴展導入,執行各種初始化工作,包括view、store、router等核心功能。暫且說這么多,后面再詳說。

   

3、vue-router

3.1 vue-router介紹

vue-router (https://github.com/vuejs/vue-router)是vue.js生態里重要的一環,是vue.js官方router ,它與Vue.js核心深度集成,使得使用Vue.js構建單頁面應用程序變得輕而易舉,包含如下特性:

  • 嵌套路由/視圖映射
  • 基於組件的路由器配置
  • 路由參數,查詢,通配符
  • 集成Vue.js頁面過渡效果
  • 導航控制
  • 歷史記錄:HTML5 history mode 或者 hash mode

   

我們從hackernews項目來看如何使用vue-router:

   

3.2 代碼分析

  • 首先,需要import Router from 'vue-router',導入Router,然后Vue.use(Router)
  • rourter是基於組件的路由配置,所以還需要導入各種View
  • 最重要的,router需要返回Router的實例對象,關鍵是配置routes,如代碼所示,routes是一個json-array,里面的每一個json-object包含了path和component
    • path支持字符串、通配符
    • component返回一個View
    • 看到這里大概就理解了router的原理,通過path去匹配,然后返回匹配的View,比如訪問主頁,route里配置的是redirect:'/top', 則會跳轉到top
    • 項目里,top,new,show等都是StoriesView,只是類型不同,所以createStoriesView函數用於實例化不同類型的StoriesView
  • 路由跳轉
    • 跳轉:包含兩種方式,聲明和編程。
      • <router-link :to="...">
      • router.push(...)
        • router.push({ path: 'home' })
        • router.push('home')
        • router.push({ name: 'user', params: { userId: 123 }})

    • 這里順帶提一下mixins,在入口代碼里有

    // register global mixins.

    Vue.mixin(mixins)

    我們來看mixins

       

    • Vue.mixin 混合是一種靈活的分布式復用 Vue 組件的方式,所有混合對象的選項將被混入該組件本身的選項,因此上述代碼實現為Vue組件增加jump方法,而jump的核心就是路由的跳轉。mixin后,可以在vue組件里使用jump方法。例如:<div class="link" @click="jump('/top')">

       

    4、vuex

       

    4.1 vuex介紹

    Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也集成到 Vue 的官方調試工具 devtools extension,提供了諸如零配置的 time-travel 調試、狀態快照導入導出等高級調試功能。

       

    狀態管理模式,開發中大型單頁應用時需要使用到,Vuex 借鑒了 Flux、Redux等成熟框架的思想開發而成。什么是"狀態管理模式"呢,我們來看官方的說明:

       

    讓我們從一個簡單的 Vue 計數應用開始:

    new Vue({
    // state
    data () {
    return {
    count: 0
    }
    },
    // view
    template: `
    <div>{{ count }}</div>
    `,
    // actions
    methods: {
    increment () {
    this.count++
    }
    }
    })

    這個狀態自管理應用包含以下幾個部分:

    • state,驅動應用的數據源;
    • view,以聲明方式將state映射到視圖;
    • actions,響應在view上的用戶輸入導致的狀態變化。

    以下是一個表示"單向數據流"理念的極簡示意:

    但是,當我們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:

    • 多個視圖依賴於同一狀態。
    • 來自不同視圖的行為需要變更同一狀態。

       

    我們可以把組件的共享狀態抽取出來,以一個全局單例模式管理。這樣組件樹構成了一個巨大的"視圖",不管在樹的哪個位置,任何組件都能獲取狀態或者觸發行為。另外,通過定義和隔離狀態管理中的各種概念並強制遵守一定的規則,代碼將會變得更結構化且易維護。

    Vuex包含State,Getters,Mutations ,Actions 和Modules 五大核心概念

    • State : Vuex 使用 單一狀態樹,State是全局唯一數據源,可以理解為state為數據庫
    • Getters可以認為是 store 的計算屬性,類似面向對象類里的get,set
    • mutation:更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation,每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)
    • Actions Action 類似於 mutation,不同在於:
      • Action 提交的是 mutation,而不是直接變更狀態
      • Action 可以包含任意異步操作
    • Modules : 使用單一狀態樹,導致應用的所有狀態集中到一個很大的對象。但是,當應用變得很大時,store 對象會變得臃腫不堪,Vuex 允許將 store 分割到模塊(module),每個模塊擁有自己的 state、mutation、action、getters

         

    再來看下面的圖,Sate作為全局數據源,可以通過Action提交Mutation來改變State,State改變后自動Render到Vue的component,同時可以安裝vue.js提供的devtools查看mutation變更記錄。

4.2 代碼分析

   

4.2.1 導入Vuex

import Vuex from 'vuex'

   

4.2.2 定義Store,實例化Vuex.Store

   

4.2.3 定義state 和getters

state是全局唯一數據,定義了包含items,lists等需要展示到UI上的數據,getters可以理解為state的一個切片或者視圖函數,返回符合條件的特定數據。

   

4.2.4 mutation

回顧下前面說的,state的所有改變必須是通過mutation,我們來看實現:

每個mutation是一個函數,第一個參數是state,第二個是所謂的載荷,理解為變化的數據

   

mutation如何調用的呢?

  • store.commit('mutation名稱')
  • store.commit('mutation名稱', {

    參數: 參數值

    })

       

Vuex 規定mutation必須是同步函數,不能為異步。

   

   

4.2.5 數據API

   

store最主要的功能就是獲取和存儲數據,如何獲取數據呢?

weex中通過stream提供網絡訪問功能,通過stream.fetch獲取,注意fetch.js里fetch函數返回的是一個Promise對象

關於Promise,不了解的可以查看(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise)

   

store/fetch.js

   

4.2.6 action

   

進入store/action.js

   

看code:

   

export function FETCH_LIST_DATA({commit,dispatch,state},{type}){

commit('SET_ACTIVE_TYPE',{type})

return fetchIdsByType(type)

.then(ids=>commit('SET_LIST',{type,ids}))

.then(()=>dispatch('ENSURE_ACTIVE_ITEMS'))

}

   

  • 定義了一個名為FETCH_LIST_DATA的action
  • Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,可以調用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters
  • 為什么FETCH_LIST_DATA的第一個參數是{commit,dispatch,state}?因為使用了ES2015 的 參數解構 來簡化代碼
  • commit('SET_ACTIVE_TYPE',{type}) 實現調用名為SET_ACTIVE_TYPE mutation,傳遞的參數為type,可以回過頭去看下mutation的定義
  • fetchIdsByType返回的是Promise對象,后面兩個then理解為異步結果回調函數,則調用SET_LIST Mutation

   

   

5、filters過濾器

   

filter是vue.js的一個特性,

過濾器是一個通過輸入數據,能夠及時對數據進行處理並返回一個數據結果的簡單函數。Vue有很多很便利的過濾器,可以參考官方文檔, http://cn.vuejs.org/api/#過濾器 ,過濾器通常會使用管道標志 " | ", 比如:

   

{{ msg | capitalize }}

// 'abc' => 'ABC'

   

項目里的定義如下:

   

   

提供了獲取host,以及格式化時間的filter

   

看下如何使用過濾器

   

<text class="text-cellsmall-text">|{{comment.time|timeAgo}} ago</text>

 

第二部分見:

weex官方demo weex-hackernews代碼解讀(下)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM