• 基于Vue2全家桶的移动端AppDEMO实现


    搭建项目

    项目结构

    本项目才用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里面进行统一的管理,然后再对应的模块里面来处理这些方法,在不同的模块里面我们只能操作对应模块的数据和状态,这对于状态管理来说简直是非常完美。

  • 相关阅读:
    读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第三部分)
    Spring Boot进阶系列一
    职场进阶之七种武器
    大龄IT程序员的救赎之道
    Web Service
    生产者消费者问题
    SpringBoot集成Apache Shiro
    简单模拟医院叫号系统
    IT小团队管理者的突围之道
    内部推荐
  • 原文地址:https://www.cnblogs.com/IT-TOP/p/vue.html
Copyright © 2020-2023  润新知