feat: multi-store injection supported
This commit is contained in:
parent
441286595c
commit
72c06186c3
|
@ -12,6 +12,7 @@ package-lock.json
|
|||
.idea/
|
||||
|
||||
vue
|
||||
vue-ms
|
||||
/packages/*/node_modules
|
||||
/packages/*/yarn.lock
|
||||
/packages/*/yarn-error.log
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
const OBJECTTYPE = '[object Object]'
|
||||
const ARRAYTYPE = '[object Array]'
|
||||
|
||||
export function getUsing(data, paths) {
|
||||
const obj = []
|
||||
paths.forEach((path, index) => {
|
||||
|
@ -43,71 +40,26 @@ export function getTargetByPath(origin, path) {
|
|||
return current
|
||||
}
|
||||
|
||||
export function getPath(obj) {
|
||||
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
||||
const result = {}
|
||||
obj.forEach(item => {
|
||||
if (typeof item === 'string') {
|
||||
result[item] = true
|
||||
} else {
|
||||
const tempPath = item[Object.keys(item)[0]]
|
||||
if (typeof tempPath === 'string') {
|
||||
result[tempPath] = true
|
||||
} else if (typeof tempPath[0] === 'string') {
|
||||
result[tempPath[0]] = true
|
||||
} else {
|
||||
tempPath[0].forEach(path => (result[path] = true))
|
||||
}
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
return getUpdatePath(obj)
|
||||
}
|
||||
|
||||
export function getUpdatePath(data) {
|
||||
export function getPath(obj, out, name) {
|
||||
const result = {}
|
||||
dataToPath(data, result)
|
||||
obj.forEach(item => {
|
||||
if (typeof item === 'string') {
|
||||
result[item] = true
|
||||
} else {
|
||||
const tempPath = item[Object.keys(item)[0]]
|
||||
if (typeof tempPath === 'string') {
|
||||
result[tempPath] = true
|
||||
} else if (typeof tempPath[0] === 'string') {
|
||||
result[tempPath[0]] = true
|
||||
} else {
|
||||
tempPath[0].forEach(path => (result[path] = true))
|
||||
}
|
||||
}
|
||||
})
|
||||
out && (out[name] = result)
|
||||
return result
|
||||
}
|
||||
|
||||
function dataToPath(data, result) {
|
||||
Object.keys(data).forEach(key => {
|
||||
result[key] = true
|
||||
const type = Object.prototype.toString.call(data[key])
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(data[key], key, result)
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(data[key], key, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function _objToPath(data, path, result) {
|
||||
Object.keys(data).forEach(key => {
|
||||
result[path + '.' + key] = true
|
||||
delete result[path]
|
||||
const type = Object.prototype.toString.call(data[key])
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(data[key], path + '.' + key, result)
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(data[key], path + '.' + key, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function _arrayToPath(data, path, result) {
|
||||
data.forEach((item, index) => {
|
||||
result[path + '[' + index + ']'] = true
|
||||
delete result[path]
|
||||
const type = Object.prototype.toString.call(item)
|
||||
if (type === OBJECTTYPE) {
|
||||
_objToPath(item, path + '[' + index + ']', result)
|
||||
} else if (type === ARRAYTYPE) {
|
||||
_arrayToPath(item, path + '[' + index + ']', result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function needUpdate(diffResult, updatePath) {
|
||||
for (let keyA in diffResult) {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { obaa } from './obaa'
|
||||
import { getPath, needUpdate, fixPath } from './path'
|
||||
|
||||
const components = []
|
||||
const updateSelfComponents = []
|
||||
let store
|
||||
let isMultiStore = false
|
||||
|
||||
export function $(options) {
|
||||
const beforeCreate = options.beforeCreate
|
||||
|
@ -14,60 +13,80 @@ export function $(options) {
|
|||
|
||||
if (options.store) {
|
||||
store = options.store
|
||||
|
||||
obaa(store.data, (prop, val, old, path) => {
|
||||
const patch = {}
|
||||
|
||||
patch[fixPath(path + '-' + prop)] = true
|
||||
components.forEach(component => {
|
||||
if (
|
||||
component.__$updatePath_ &&
|
||||
needUpdate(patch, component.__$updatePath_)
|
||||
) {
|
||||
recUpdate(component)
|
||||
if (store.data) {
|
||||
observe(store)
|
||||
} else {
|
||||
isMultiStore = true
|
||||
for (let key in store) {
|
||||
if (store[key].data) {
|
||||
observe(store[key], key)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
updateSelfComponents.forEach(component => {
|
||||
if (
|
||||
component.__$updateSelfPath_ &&
|
||||
needUpdate(patch, component.__$updateSelfPath_)
|
||||
) {
|
||||
component.$forceUpdate()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
options.beforeCreate = function() {
|
||||
options.beforeCreate = function () {
|
||||
this.$store = store
|
||||
if (use) {
|
||||
this.__$updatePath_ = getPath(use)
|
||||
components.push(this)
|
||||
}
|
||||
if (useSelf) {
|
||||
this.__$updateSelfPath_ = getPath(useSelf)
|
||||
updateSelfComponents.push(this)
|
||||
if (isMultiStore) {
|
||||
if (use) {
|
||||
let updatePath = {}
|
||||
for (let storeName in use) {
|
||||
getPath(use[storeName], updatePath, storeName)
|
||||
store[storeName].components.push(this)
|
||||
}
|
||||
this.__$updatePath_ = updatePath
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (useSelf) {
|
||||
let updateSelfPath = {}
|
||||
for (let storeName in useSelf) {
|
||||
getPath(useSelf[storeName], updateSelfPath, storeName)
|
||||
store[storeName].updateSelfComponents.push(this)
|
||||
}
|
||||
this.__$updateSelfPath_ = updateSelfPath
|
||||
}
|
||||
} else {
|
||||
if (use) {
|
||||
this.__$updatePath_ = getPath(use)
|
||||
store.components.push(this)
|
||||
}
|
||||
if (useSelf) {
|
||||
this.__$updateSelfPath_ = getPath(useSelf)
|
||||
store.updateSelfComponents.push(this)
|
||||
}
|
||||
}
|
||||
beforeCreate && beforeCreate.apply(this, arguments)
|
||||
}
|
||||
|
||||
options.destroyed = function() {
|
||||
for (let i = 0, len = components.length; i < len; i++) {
|
||||
if (components[i] === this) {
|
||||
components.splice(i, 1)
|
||||
break
|
||||
options.destroyed = function () {
|
||||
if (isMultiStore) {
|
||||
for (let key in store) {
|
||||
removeItem(this, store[key].components)
|
||||
removeItem(this, store[key].updateSelfComponents)
|
||||
}
|
||||
} else {
|
||||
removeItem(this, store.updateSelfComponents)
|
||||
removeItem(this, store.components)
|
||||
}
|
||||
|
||||
destroyed && destroyed.apply(this, arguments)
|
||||
}
|
||||
|
||||
options.computed.state = function() {
|
||||
options.computed.state = function () {
|
||||
if (isMultiStore) {
|
||||
let state = {}
|
||||
Object.keys(store).forEach(k => {
|
||||
state[k] = store[k].data
|
||||
})
|
||||
return state
|
||||
}
|
||||
return this.$store.data
|
||||
}
|
||||
|
||||
options.computed.store = function() {
|
||||
options.computed.store = function () {
|
||||
return this.$store
|
||||
}
|
||||
|
||||
|
@ -80,3 +99,44 @@ function recUpdate(root) {
|
|||
recUpdate(child)
|
||||
})
|
||||
}
|
||||
|
||||
function observe(store, storeName) {
|
||||
store.components = []
|
||||
store.updateSelfComponents = []
|
||||
|
||||
obaa(store.data, (prop, val, old, path) => {
|
||||
const patch = {}
|
||||
|
||||
patch[fixPath(path + '-' + prop)] = true
|
||||
store.components.forEach(component => {
|
||||
const p = component.__$updatePath_
|
||||
if (storeName) {
|
||||
if (p && p[storeName] && needUpdate(patch, p[storeName])) {
|
||||
recUpdate(component)
|
||||
}
|
||||
} else if (p && needUpdate(patch, p)) {
|
||||
recUpdate(component)
|
||||
}
|
||||
})
|
||||
|
||||
store.updateSelfComponents.forEach(component => {
|
||||
const sp = component.__$updateSelfPath_
|
||||
if (storeName) {
|
||||
if (sp && sp[storeName] && needUpdate(patch, sp[storeName])) {
|
||||
component.$forceUpdate()
|
||||
}
|
||||
} else if (sp && needUpdate(patch, sp)) {
|
||||
component.$forceUpdate()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function removeItem(item, arr) {
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
if (arr[i] === item) {
|
||||
arr.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue