天天看点

Vue+Vux项目实践

利用脚手架搭建项目架构,此步骤不予此地说明,不明之处可上git、百度或者留言。

本项目实践代码,均可执行。

代码尚未优化,大牛请绕路。

提供完整的路由,services`````````````

   ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    <title>insurance-weixin</title>
  </head>
  <body>
    <div id="app-box"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
      

   ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

main.js

import Vue from 'vue'
import Vuex from 'vuex'
import VueRouter from 'vue-router'
import FastClick from 'fastclick'
import {WechatPlugin, AjaxPlugin, LoadingPlugin, ToastPlugin, AlertPlugin} from 'vux'
import App from './app.vue'

/**
 * 加载插件
 */
Vue.use(Vuex)
Vue.use(VueRouter)
Vue.use(WechatPlugin)
Vue.use(AjaxPlugin)
Vue.use(LoadingPlugin)
Vue.use(ToastPlugin)
Vue.use(AlertPlugin)

/**
 * 定义常量
 */
const domainName = 'localhost:8010'
const serverName = 'localhost:3000'
const apiPrefix = serverName + '/api/outer'
const loginTimeOutErrorCode = 'login_timeout_error'

/**
 * 设置vuex
 */
const store = new Vuex.Store({})
store.registerModule('vux', {
  state: {
    loading: false,
    showBack: true,
    title: ''
  },
  mutations: {
    updateLoading (state, loading) {
      state.loading = loading
    },
    updateShowBack (state, showBack) {
      state.showBack = showBack
    },
    updateTitle (state, title) {
      state.title = title
    }
  }
})

/**
 * 设置路由
 */
const routes = [
  // 初始页
  {
    path: '/',
    component: function (resolve) {
      require(['./components/init.vue'], resolve)
    }
  },
  // 主页
  {
    path: '/index',
    component: function (resolve) {
      require(['./components/index.vue'], resolve)
    },
    children: [
      // 测试页
      {
        path: 'test',
        component: function (resolve) {
          require(['./components/tests/page.vue'], resolve)
        }
      }
    ]
  },
  // 绑定页
  {
    path: '/bind',
    component: function (resolve) {
      require(['./components/bind.vue'], resolve)
    }
  }
]
const router = new VueRouter({
  routes
})
router.beforeEach(function (to, from, next) {
  store.commit('updateLoading', true)
  store.commit('updateShowBack', true)
  next()
})
router.afterEach(function (to) {
  store.commit('updateLoading', false)
})

/**
 * 点击延迟
 */
FastClick.attach(document.body)

/**
 * 日志输出开关
 */
Vue.config.productionTip = true

/**
 * 定义全局公用常量
 */
Vue.prototype.domainName = domainName
Vue.prototype.serverName = serverName
Vue.prototype.apiPrefix = apiPrefix

/**
 * 定义全局公用方法
 */
Vue.prototype.http = function (opts) {
  let vue = this
  vue.$vux.loading.show({
    text: 'Loading'
  })

  vue.$http({
    method: opts.method,
    url: apiPrefix + opts.url,
    headers: opts.headers || {},
    params: opts.params || {},
    data: opts.data || {}
  }).then(function (response) {
    vue.$vux.loading.hide()

    opts.success(response.data.data)
  }).catch(function (error) {
    vue.$vux.loading.hide()

    if (!opts.error) {
      let response = error.response
      let errorMessage = '请求失败'

      if (response && response.data) {
        if (response.data.code === loginTimeOutErrorCode) {
          window.location.href = '/'
        }
        errorMessage = response.data.message
      }

      vue.$vux.alert.show({
        title: '提示',
        content: errorMessage
      })
    } else {
      opts.error(error.response.data.data)
    }
  })
}

Vue.prototype.get = function (opts) {
  opts.method = 'get'
  this.http(opts)
}

Vue.prototype.post = function (opts) {
  opts.method = 'post'
  this.http(opts)
}

Vue.prototype.put = function (opts) {
  opts.method = 'put'
  this.http(opts)
}

Vue.prototype.delete = function (opts) {
  opts.method = 'delete'
  this.http(opts)
}

Vue.prototype.valid = function (opts) {
  let vue = this
  let valid = true

  if (opts.ref && !opts.ref.valid) {
    valid = false
  }

  if (opts.ignoreRefs) {
    let newRefs = []
    for (let i in opts.refs) {
      let ref = opts.refs[i]
      for (let j in opts.ignoreRefs) {
        let ignoreRef = opts.ignoreRefs[j]
        if (ref !== ignoreRef) {
          newRefs.push(ref)
        }
      }
    }
    opts.refs = newRefs
  }

  for (let i in opts.refs) {
    if (!opts.refs[i].valid) {
      valid = false
      break
    }
  }

  if (valid) {
    opts.success()
  } else if (opts.error) {
    opts.error()
  } else {
    vue.$vux.toast.show({
      text: '请检查输入'
    })
  }
}

Vue.prototype.closeShowBack = function () {
  this.$store.commit('updateShowBack', false)
}

Vue.prototype.updateTitle = function (value) {
  this.$store.commit('updateTitle', value)
}

/**
 * 创建实例
 */
new Vue({
  store,
  router,
  render: h => h(App)
}).$mount('#app-box')
      

app.vue

<template>
  <div id="app">
    <loading v-model="isLoading"></loading>
    <transition>
      <router-view></router-view>
    </transition>
  </div>
</template>

<script>
  import {Loading} from 'vux'
  import {mapState} from 'vuex'

  export default {
    name: 'app',
    components: {
      Loading
    },
    computed: {
      ...mapState({
        isLoading: state => state.vux.isLoading
      })
    }
  }
</script>

<style less">
  @import '~vux/src/styles/reset.less';

  body {
    background-color: #fbf9fe;
  }
</style>
      

components/index.vue

<template>
  <div style="height:100%;">
    <top style="margin-bottom:46px"></top>
    <transition>
      <router-view></router-view>
    </transition>
    <bottom></bottom>
  </div>
</template>

<script>
  import Top from './layouts/top.vue'
  import Bottom from './layouts/bottom.vue'

  export default {
    components: {
      Top,
      Bottom
    }
  }
</script>

<style>
  html, body {
    height: 100%;
    width: 100%;
    overflow-x: hidden;
  }
</style>
      

components/tests/page.vue

<template>
  <div>
    <page @loadMore="loadMore" @refresh="refresh">
      <div>
        <p v-for="i in n">placeholder {{i}}</p>
      </div>
    </page>
  </div>
</template>

<script>
  import Page from '../kits/page.vue'
  import {cookie} from 'vux'
  export default {
    components: {
      Page
    },
    created () {
      let vue = this
      vue.closeShowBack()
      vue.updateTitle('测试页面'),
      //获取常量
        console.log(0)
      vue.get({
        url: '/test/constants',
        headers: {
          'token': cookie.get('token')
        },
        success: function (data) {
          cookie.set('constants',JSON.stringify(data),{
            expires: 1
          })
        }
      })

    },
    data () {
      return {
        n: 10,
      }
    },
    methods: {
      loadMore () {
        this.n += 10
      },
      refresh () {
        this.n = 10
      },
    }
  }
</script>
      

components/tests/page.vue代码中的 import Page from '../kits/page.vue'是我自己写的下拉刷新上啦加在的组件,运行的话删掉这些引用就可以了。

本次记录摘要是从刚刚完成的项目中抽离的部分代码(注:本项目实践代码,可运行,可运行,可运行,可运行)

Vue+Vux项目实践
Vue+Vux项目实践
Vue+Vux项目实践

如若遇到什么问题,可小窗我哦。