配置中心实现:皮肤、国际化、权限控制

# 实例

// 配置类 src/config/config.js
class Config {
  constructor() {
    this._config = {}
  }
  register(type, value) {
    this._config[type] = value
  }
  get(type) {
    return this._config[type]
  }
}

export default new Config()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 主题类 src/config/theme.js
import config from './config'

export const init = () => {
  config.register('theme', {
    blue: {
      primary: '#007fff',
      highlight: '#00a6ff',
    },
    red: {
      primary: '#a83733',
      highlight: '#c34b49',
    },
  })
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 国际化 src/config/locale.js
import config from './config'

export const init = () => {
  config.register('locale', {
    zh: {
      module: {
        hot: '热门',
        new: '最新',
        top: '热榜',
        about: '关于我',
      },
    },
    en: {
      module: {
        hot: 'hot',
        new: 'new',
        top: 'top',
        about: 'about',
      },
    },
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 权限 src/config/permission.js
import config from './config'

export const PERMISSIONS = {
  ABOUT_PAGE: Symbol('ABOUT_PAGE'),
}

export const init = () => {
  config.register('permission', {
    CEO: {
      [PERMISSIONS.ABOUT_PAGE]: true,
    },
    COO: {
      [PERMISSIONS.ABOUT_PAGE]: false,
    },
  })
}

export const getPermissionByRole = (role) => config.get('permission')[role]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 在main.js中初始化
...

import { init as themeInit } from './config/theme'
import { init as localeInit } from './config/locale'
import { init as permissionInit } from './config/permission'
import App from './App.vue'

Vue.directive('intersect', intersect)

themeInit() 
localeInit()
permissionInit()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// App.vue
<template>
  <div>
    <div class="m-top" :style="{ background: theme.primary }">
      <router-link class="m-link"
        :style="{ background: $route.name === nav.path ? theme.highlight : theme.primary }"
        v-for="nav in navs" :key="nav.path" :to="nav.path">
        {{ module[nav.id] }}
      </router-link>
    </div>
    <div class="m-content">
      <router-view></router-view>
    </div>
    <div class="m-side">
      <div>
        <span>主题切换:</span>
        <button @click="themeType = 'blue'"></button>
        <button @click="themeType = 'red'"></button>
      </div>
      <div>
        <span>语言:</span>
        <button @click="language = 'zh'"></button>
        <button @click="language = 'en'"></button>
      </div>
    </div>
  </div>
</template>

<script>
import { TYPES } from './module/topic/store'
import config from './config/config'

export default {
  data() {
    return {
       themeType: 'blue',
       language: 'zh',
    }
  },
  computed: {
    theme() {
      return config.get('theme')[this.themeType]
    },
    module() {
      return config.get('locale')[this.language].module
    },
    navs() {
      return [
        { id: 'hot', path: TYPES.HOT },
        { id: 'new', path: TYPES.NEW },
        { id: 'top', path: TYPES.TOP },
        { id: 'about', path: 'about' },
      ]
    },
  },
}
</script>

<style>
...

.m-side {
  position: fixed;
  top: 100px;
  left: 50%;
  margin-left: 520px;
  width: 200px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 权限状态  /src/store.js
import Vue from 'vue'
import Vuex from 'vuex'
import { store as topic } from './module/topic/store'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user: {
      role: 'COO',
    },
  },
  modules: {
    topic,
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 路由配置  src/router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import { routes as topic } from './module/topic/router'
import store from './store'
import { PERMISSIONS, getPermissionByRole } from './config/permission'

Vue.use(VueRouter)

const getPermission = (permission) => getPermissionByRole(store.state.user.role)[permission]

export default new VueRouter({
  routes: [
    {
      name: 'about',
      path: '/about',
      component: () => import('./views/UAbout.vue'),
      beforeEnter(to, from, next) {
        getPermission(PERMISSIONS.ABOUT_PAGE) ? next() : next('/403')
      },
    },
    {
      name: '403',
      path: '/403',
      component: () => import('./views/403.vue')
    },
    ...topic,
    { path: '/', redirect: '/hot' }
  ],
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31