veui
Version:
Baidu Enterprise UI for Vue.js.
115 lines (100 loc) • 2.98 kB
JavaScript
import { isObject, startsWith, forEach } from 'lodash'
import Vue from 'vue'
import i18n from './i18n'
import { createContext } from './context'
export class ConfigManager {
store = new Vue({
data: {
store: {},
watchers: {}
},
methods: {
setConfig (obj, key, val, ns, override) {
if (isObject(key)) {
ns = val
val = key
Object.keys(val).forEach((k) => {
this.setConfig(obj, k, val[k], ns, override)
})
return
}
if (typeof key !== 'string') {
throw new Error('[veui-config] Config key must be a string value.')
}
let k = ns ? `${ns}.${key}` : key
if (!(k in obj) || override) {
this.setConfigItem(obj, k, val)
}
},
setConfigItem (obj, key, val) {
this.$set(obj, key, val)
let relatedWatcherKeys = Object.keys(this.watchers).filter((k) =>
startsWith(k, key)
)
relatedWatcherKeys.forEach((watcherKey) => this.unwatch(watcherKey))
this.transformValue(obj, key, null)
},
// 为了 @@xxx 和 i18n 配置联动起来
transformValue (context, key, path) {
if (!context || context._isVue || context._Ctor) {
return
}
let watcherKey = path ? `${path}.${key}` : key
let val = context[key]
let watcher = this.watchers[watcherKey]
if (typeof val === 'string') {
if (startsWith(val, '@@')) {
let i18nKey = val.substring(2)
if (watcher && watcher.key !== i18nKey) {
// already watched another i18n key before, unwatch it
watcher.unwatch()
}
this.watchers[watcherKey] = {
key: i18nKey,
unwatch: i18n.watch(i18nKey, (val) => {
context[key] = val
})
}
context[key] = i18n.get(i18nKey)
}
} else if (isObject(val) || Array.isArray(val)) {
// recursively replace pointers
forEach(val, (_, k) => {
this.transformValue(val, k, watcherKey)
})
}
},
unwatch (key) {
let watcher = this.watchers[key]
if (watcher) {
watcher.unwatch()
delete this.watchers[key]
}
},
set (key, val, ns) {
this.setConfig(this.store, key, val, ns, true)
},
defaults (key, val, ns) {
this.setConfig(this.store, key, val, ns, false)
},
get (key) {
return this.store[key]
}
}
})
set (key, val, ns) {
this.store.set(key, val, ns)
}
defaults (key, val, ns) {
this.store.defaults(key, val, ns)
}
get (path) {
return this.store.get(path)
}
getAll () {
return this.store.store
}
}
let config = new ConfigManager()
export let configContext = createContext('veui-context', () => config.getAll())
export default config