基于Vue2全家桶的移動端AppDEMO實現

pusong0 7年前發布 | 92K 次閱讀 Vue.js Vue.js開發

好久沒更新過Vue的小文章,上次做了一個基于Vue+Mint-ui的移動端AppDemo,集成了推送功能,然后通過cordova打包生成apk,移動端表現還不錯,今天把這個小東西分享出來,希望有更多的小伙伴能夠用Vue去做一些有意思的東西,本人才疏學淺,有說的不對的地方,還請大家多多指教。下面按照慣例放上demo地址和源碼地址,希望大家能給我點下star:

Demo (進去需要先注冊才能登錄,用的localstorage,隨便寫符合格式的就行)

Demo基于Vue2源碼

Demo基于Vue1的源碼

搭建項目

項目結構

本項目才用Vue-cli腳手架自動生成,這是一個Vue生態系統中一個偉大創舉。這意味著我們不需要手動構建我們的項目,而它就可以很快地為我們生成。下圖是一個完整的項目結構,如圖所示:

  • components:包含所有的頁面組件

  • vuex:包含vuex相關文件

  • modules:存放每個頁面單獨的state和mutation

  • static:靜態文件存放(圖片和圖標庫等)

  • index.html:渲染的頁面

  • main.js:應用入口點,包含根實例

  • App.vue:主頁面組件

項目流程:

  • 安裝Vue-cli(要有node與npm)

npm i -g vue-cli
  • 創建一個webpack項目,并且下載依賴

vue init webpack vue-demo-orderApp
cd vue-demo-orderApp
npm i
  • 安裝Vue-router,Vuex和Mint-ui

npm install vue-router vuex --save
npm install mint-ui --save
  • 熱加載打開頁面(生產的時候運行 npm run build )

npm run dev

項目的框架已經搭建好了,接下來就是為項目添磚加瓦。

頁面結構分析

--

本項目為一個demo項目,主要為了練習vue2的使用,結構上借鑒了官方的寫法,界面為通用的app樣式,才用餓了么團隊的Mint-Ui的制作。

這個demo的每一個頁面都是一個.vue文件,利用Vue的單文件組件,非常便于管理每個頁面的狀態,樣式和數據,首頁主要是展示頁,和操作面板頁。下面是主頁的代碼:

<template>
    <div class="index-container">
        <!-- 輪播圖部分 -->
        <mt-swipe :auto="4000">
            <mt-swipe-item><div class="banner1 banner" style="background:url('./static/banner1.jpg');background-size: cover;"></div></mt-swipe-item>
            <mt-swipe-item><div class="banner2 banner" style="background:url('./static/banner2.jpg');background-size: cover;"></div></mt-swipe-item>
        </mt-swipe>
        <!-- 訂單同步狀態部分 -->
        <mt-popup
          class="status" 
          v-model="popupVisible"
          popup-transition="popup-fade"
          position="top">
          同步{{ orders_status }}
        </mt-popup>
        <!-- 首頁功能欄部分 -->
        <ul class="icon-list">
            <li class="icon">
                <router-link to="order" class="iconlink"></router-link>
                <img src="../assets/scan.png" class="clear">
                <h4>訂單管理</h4>
                <p>掃描盤點,手工盤點</p>
                <i></i>
            </li>
            <li class="icon">
                <router-link to="goods" class="iconlink"></router-link>
                <img src="../assets/ana.png" class="clear">
                <h4>渠道管理</h4>
                <p>掃描盤點,手工盤點</p>
                <i></i>
            </li>
            <li class="icon">
                <router-link to="order" class="iconlink"></router-link>
                <img src="../assets/store.png" class="clear">
                <h4>訂單發布</h4>
                <p>掃描盤點,手工盤點</p>
                <i></i>
            </li>
            <li class="icon" @click="getOrders()">
                <router-link to="test" class="iconlink"></router-link>
                <img src="../assets/goods.png" class="clear">
                <h4>訂單同步</h4>
                <p>快速同步渠道訂單,方便快捷</p>
                <i></i>
            </li>
            <li class="icon">
                <router-link to="personinfo" class="iconlink"></router-link>
                <img src="../assets/download.png" class="clear">
                <h4>個人中心</h4>
                <p>信息管理,logo更換</p>
                <i></i>
            </li>                     
        </ul>
    </div>  
</template>
<script type="text/javascript">
    import { MessageBox } from 'mint-ui'
    import { mapState } from 'vuex'

    export default{
        created:function(){
            if(window.localStorage.user == null){
                this.$router.push({path: '/login'})
            }
        },
        data(){
            let popupVisible = false
            let orders_status
            return {popupVisible, orders_status}
        },
        computed:mapState({
            orders_status: state => state.news.orders_status,
        }),
        methods:{
            getOrders: function(){
                const that = this
                this.$store.dispatch('synchroOrder', this).then(function(){
                    that.popupVisible = true
                })
            }
        }
    }
</script>

先看代碼部分Vue2相比Vue1相比還是變化很多的,首先就是計算屬性比以前更好用了,其次是生命周期部分和以前相比變化很大,這點要注意下。其次是Vue2更推崇ES6的寫法,并且支持了promise,這是非常好的地方,而且官方的迭代文檔也寫的很全,基本上很容易從1迭代到2。并且Vue2不再支持雙向綁定(sync)這個方法了,它使用了一種更好的方式來進行父子組件之間的通信(emit),這樣子組件就不會影響到父組件的狀態。下面我放出這個主頁Vue1的代碼,大家可以比較一下:

<template>
    <div class="index-container">
        <mt-swipe :auto="4000">
            <mt-swipe-item><div class="banner1 banner" style="background:url('./static/banner1.jpg');background-size: cover;"></div></mt-swipe-item>
            <mt-swipe-item><div class="banner2 banner" style="background:url('./static/banner2.jpg');background-size: cover;"></div></mt-swipe-item>
        </mt-swipe>
        <ul class="icon-list">
            <li class="icon">
                <img src="../assets/scan.png" class="clear">
                <h4>訂單管理</h4>
                <p>掃描盤點,手工盤點</p>
                <i></i>
            </li>
            <li class="icon">
                <img src="../assets/ana.png" class="clear">
                <h4>渠道管理</h4>
                <p>掃描盤點,手工盤點</p>
                <i></i>
            </li>
            <li class="icon">
                <img src="../assets/store.png" class="clear">
                <h4>訂單發布</h4>
                <p>掃描盤點,手工盤點</p>
                <i></i>
            </li>
            <li class="icon" @click="getOrders(this)">
                <img src="../assets/goods.png" class="clear">
                <h4>訂單同步</h4>
                <p>快速同步渠道訂單,方便快捷</p>
                <i></i>
            </li>
            <li class="icon">
                <img src="../assets/download.png" class="clear">
                <h4>個人中心</h4>
                <p>信息管理,logo更換</p>
                <i></i>
            </li>                     
        </ul>
        <mt-popup
          :visible.sync="popupVisible"
          popup-transition="popup-fade"
          position="top">
        同步成功</mt-popup>
    </div>  
</template>
<script type="text/javascript">
    import { synchroOrder } from '../vuex/action'
    import { MessageBox } from 'mint-ui'
    export default{
        init:function(){
            if(window.localStorage.user == null){
                //window.location.href = window.location.origin + window.location.pathname + '#!/login'
                console.log('請登錄')
                this.$router.go({path:'/login'})
            }
        },
        data(){
            let popupVisible = false
            return {popupVisible}
        },
        vuex:{
            getters:{
                order_status: state => state.orders_status
            },
            actions:{
                synchroOrder
            }
        },
        methods:{
            getOrders: function(that){
                this.synchroOrder(that)
                if(this.order_status){
                    this.popupVisible = !this.popupVisible
                }
            }
        }
    }

上面的代碼比較可以看出,VueX和Vue-router的變化也很大,這里我就詳細說這兩者的變化了,有啥問題可以討論討論,大概說下,首先是Vue-router部分,不再支持以前V-link的這種方式了,變為采用router-link這種方式。VueX方面我感覺變化最大的就是寫法和以前不一樣了。Vuex才用 this.$store.dispatch('xxx') 來派發一個action,通過commit委托給mutation來執行相應的操作,并且支持異步的寫法,就是ES6的promise,給一段官方的異步寫法:

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

。還有一個明顯的變化是mapActions和mapState屬性,mapActions可以用來指明一個組件的方法去調用store.dispatch()方法。通過mapState屬性我們可以去定義一些計算函數和鍵值對,主要是為了方便運用多個states屬性和getters。還有一個比較大的變化就是Vuex2可以支持將store轉變為Module的寫法,來更細致的去管理狀態。我的這個小demo也用上了這個新特性,它能讓大型的頁面也能有很好的狀態管理。

可以對比一下同一個項目基于Vue1和Vue2的寫法。這樣更能夠直觀的去了解到不同之處,并且可以去細想一下作者為什么這個改,這對我們編程思想的提示是很有幫助的。

基于模塊化的Vuex

將不同的Vuex狀態放在對應的頁面狀態模塊里,這樣當需要管理的數據很多的時候也能從容的應對。

可以看下這里面是怎么寫的,下面是news.js里面的:

import * as types from '../mutation-types'

const state = {
    news:{},
    orders_status: '成功',
    selected:'首頁'
}

const mutations = {
    [types.SYNCHRO_ORDER](state, items){
        state.news = items
        console.log(state.news.length)
        if(state.news.length != 0){
            state.orders_status = '成功'
        }
        else{
            state.orders_status = '失敗'
        }
    },
    [types.CHANGE_SELECTED](state, item){
        state.selected = item
    }
}

export default{
    state,
    mutations
}

下面是mution-types.js

export const CHANGE_ORDER = 'CHANGE_ORDER'
export const CHANGE_STATUS = 'CHANGE_STATUS'
export const DISPLAY_STATUS = 'DISPLAY_STATUS'
export const CHANGE_PERSON = 'CHANGE_PERSON'
export const SYNCHRO_ORDER = 'SYNCHRO_ORDER'
export const CHANGE_POP = 'CHANGE_POP'
export const CHANGE_SELECTED = 'CHANGE_SELECTED'

可以看到我們將所有的mutaions方法都放在了mution-types里面進行統一的管理,然后再對應的模塊里面來處理這些方法,在不同的模塊里面我們只能操作對應模塊的數據和狀態,這對于狀態管理來說簡直是非常完美。

 

來自:https://segmentfault.com/a/1190000008213141

 

 本文由用戶 pusong0 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!