Vue多項目管理

在Vue-cli 3.X環境下,基於同一類型的活動,能夠多個頁面複用,大部分組件能夠公用的背景

Multiple處理方式

  • 每個活動建立一個分支,在不一樣的分支上各自維護
  • 若是須要維護複用代碼時,任選某一分支進行修改,經過git cherry-pick <commit id>進行平行遷移。

Monorepo處理方式

僅在同一分鐘下進行多項目的維護,各個功能模塊解構,經過項目配置項進行個性化配置。前端

目錄結構

|-src  
  |- views
    |- index.js // 通用頁面的統一入口
    |- Company
      |- index.vue // 通用頁面Company結構、樣式、邏輯
      |- index.js  // Company頁面路由
    |- Rule
      |- index.vue
      |- index.js
  |- components
  |- core
    |- instance  // 和app實例掛鉤的方法
    |- libs  // 和app實例無關的方法
  |- assets
    |- images
    |- fonts
  |- store
    |- index.js  // 通用狀態
    |- types.js  // 事件類型
  |- config
    |- proA.js  // 項目資源配置
    |- proB.js
  |- projects  // 項目定製資源
    |- proA
    |- proB

不一樣項目的區別徹底在於config/文件的配置和projects/下的項目定義;同級其他目錄是各個項目通用的內容。vue

提取公共頁面 & 路由

公共頁面示例:
// src/views/Company/index.vue
<template>
 ...
</template>
<script>
...
</script>
<style scoped>
...
</style>
公共頁面路由
// src/views/Company/index.js
export default [
  {
    path: '/company',
    name: 'company',
    component: () => import(/* webpackChunkName: "company" */ './index.vue'),
    meta: {
      title: '公司簡介'
    }
  }
]
公共頁面統一入口
// src/views/index.js
export { default as companyRoute } from './Company/index.js'
export { default as ruleRoute } from './Rule/index.js'
定製項目中的公共頁面
// src/config/proA.js
import {
  companyRoute,
  ruleRoute
} from '../views/index.js'
...
export const logoUrl = '' // 還能夠定製其它的內容

export const routes = [
  ...companyRoute,
  ...ruleRoute
]
項目中使用公共頁面

src/projects/proA爲例:webpack

目錄結構
|- assets
|- components
|- mixins
|- router
|- store
|- pages
|- App.vue
|- main.js
項目主路由
// src/projects/proA/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import { routes } from '../../config/proA'
import Home from '../pages/Home'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      redirect: '/home'
    },
    {
      path: '/home',
      name: 'Home',
      component: Home,
      meta: {
        title: ''
      }
    },
    ...routes
  ]
})

其中:Home/index.vue是定製化的。git

狀態管理

多項目是獨立運行時,狀態提取不會互相干擾,若一次性運行多個項目,通用狀態會被修改。
通用狀態提取
// src/store/index.js
import types from './types'

export const initialState = {
  userInfo: {},
  ...
}
export function getGetters (store) {
  return {
    userId: () => store.userInfo.userID,
    ...
  }
}
export function getMutations (store) {
  return {
    [types.INITIALMUTATIONTYPES.USER_INFO] (val) {
      store.userInfo = val
    },
    ...
  }
}

config/proA.js文件中追加:web

...
export * from '../store/index.js'
export * from '../store/types.js'
...
項目中使用
小型項目,使用 vue.observable管理狀態
定義項目的主狀態管理
// src/projects/proA/store/index.js

import vue from 'vue'
import { initialState, getGetters, getMutations } from '../../../config/proA'

export const store = vue.observable({
  ...initialState,
  customState: '', // 項目私有狀態
  ...
})
store._getters = {
  ...getGetters(store),
  customGetter() {  // 項目私有
      return store.customState
  },
  ...
}
store._mutations = {
  ...getMutation(store),
  ...  // 項目私有
}
export const mutation = {
  ...getMutations(store),
  ...  // 項目私有
}
定義輔助方法mapGetters
拷貝 vuex部分代碼到 src/core/libs/helpers.js文件中
export const mapGetters = (getters) => {
  const res = {}
  if (!isValidMap(getters)) {
    console.error('[vuex] mapGetters: mapper parameter must be either an Array or an Object')
  }
  normalizeMap(getters).forEach(({ key, val }) => {
    res[key] = function mappedGetter () {
      if (!(val in this.$store._getters)) {
        console.error(`[vuex] unknown getter: ${val}`)
        return
      }
      return this.$store._getters[val]()
    }
  })
  return res
}
export function normalizeMap (map) {
  if (!isValidMap(map)) {
    return []
  }
  return Array.isArray(map)
    ? map.map(key => ({ key, val: key }))
    : Object.keys(map).map(key => ({ key, val: map[key] }))
}
export function isValidMap (map) {
  return Array.isArray(map) || isObject(map)
}
export function isObject (obj) {
  return obj !== null && typeof obj === 'object'
}

/src/core/libs/index.js中追加:vue-router

export * from './helpers'
*.vue中使用
// src/projects/proA/pages/Home/index.vue
<script>
...
import { mapGetters } from '../../../core/libs/'

export default {
  data () {
    return {
      ...
    }
  },
  computed: {
    ...mapGetters([
        'userId'
    ]),
    ...
  }
...
</script>

參考文檔

相關文章
相關標籤/搜索