refactor: support updating on demand

This commit is contained in:
dntzhang 2019-10-03 15:59:13 +08:00
parent bafda41eef
commit bdff385236
6 changed files with 169 additions and 21 deletions

View File

@ -2,5 +2,5 @@ import create from '../../utils/create'
create({
use: ['logs']
})

View File

@ -5,7 +5,12 @@ import store from '../../store'
const app = getApp()
create(store, {
use: [
'motto',
'userInfo',
'hasUserInfo',
'canIUse',
],
//事件处理函数
bindViewTap: function () {
wx.navigateTo({

View File

@ -5,6 +5,7 @@ import store from '../../store'
const util = require('../../utils/util.js')
create(store, {
use: ['logs'],
onLoad: function () {
this.store.data.logs = (wx.getStorageSync('logs') || []).map(log => {
return util.formatTime(new Date(log))

View File

@ -9,5 +9,7 @@ export default {
return this.motto.split('').reverse().join('')
}
},
//无脑全部更新,组件或页面不需要声明 use
//updateAll: true,
debug: true
}

View File

@ -5,6 +5,7 @@
*/
import obaa from './obaa'
import { getPath, needUpdate, fixPath } from './path'
const ARRAYTYPE = '[object Array]'
const OBJECTTYPE = '[object Object]'
@ -26,6 +27,7 @@ function create(store, option) {
option.onLoad = function (e) {
this.store = store
option.use && (this.__updatePath = getPath(option.use))
store.instances[this.route] = []
store.instances[this.route].push(this)
@ -41,7 +43,7 @@ function create(store, option) {
store.lifetimes = store.lifetimes || {}
store.ready = store.lifetimes.ready = function () {
const page = getCurrentPages()[getCurrentPages().length - 1]
store.use && (this.__updatePath = getPath(store.use))
this.store = page.store
store.data = this.store.data
@ -78,8 +80,10 @@ function observeStore(store) {
function _update(kv, store) {
for (let key in store.instances) {
store.instances[key].forEach(ins => {
ins.setData.call(ins, kv)
updateStoreByFnProp(ins, store.data)
if(store.updateAll || needUpdate(kv,ins.__updatePath)){
ins.setData.call(ins, kv)
updateStoreByFnProp(ins, store.data)
}
})
}
store.onChange && store.onChange(kv)
@ -192,22 +196,7 @@ function type(obj) {
function fixPath(path) {
let mpPath = ''
const arr = path.replace('#-', '').split('-')
arr.forEach((item, index) => {
if (index) {
if (isNaN(parseInt(item))) {
mpPath += '.' + item
} else {
mpPath += '[' + item + ']'
}
} else {
mpPath += item
}
})
return mpPath
}

151
packages/omix/utils/path.js Normal file
View File

@ -0,0 +1,151 @@
const OBJECTTYPE = '[object Object]'
const ARRAYTYPE = '[object Array]'
export function getUsing(data, paths) {
const obj = []
paths.forEach((path, index) => {
const isPath = typeof path === 'string'
if (isPath) {
obj[index] = getTargetByPath(data, path)
} else {
const key = Object.keys(path)[0]
const value = path[key]
if (typeof value === 'string') {
obj[index] = getTargetByPath(data, value)
} else {
const tempPath = value[0]
if (typeof tempPath === 'string') {
const tempVal = getTargetByPath(data, tempPath)
obj[index] = value[1] ? value[1](tempVal) : tempVal
} else {
const args = []
tempPath.forEach(path => {
args.push(getTargetByPath(data, path))
})
obj[index] = value[1].apply(null, args)
}
}
obj[key] = obj[index]
}
})
return obj
}
export function getTargetByPath(origin, path) {
const arr = path
.replace(/]/g, '')
.replace(/\[/g, '.')
.split('.')
let current = origin
for (let i = 0, len = arr.length; i < len; i++) {
current = current[arr[i]]
}
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) {
const result = {}
dataToPath(data, 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) {
if (updatePath[keyA]) {
return true
}
for (let keyB in updatePath) {
if (includePath(keyA, keyB)) {
return true
}
}
}
return false
}
function includePath(pathA, pathB) {
if (pathA.indexOf(pathB) === 0) {
const next = pathA.substr(pathB.length, 1)
if (next === '[' || next === '.') {
return true
}
}
return false
}
export function fixPath(path) {
let mpPath = ''
const arr = path.replace('#-', '').split('-')
arr.forEach((item, index) => {
if (index) {
if (isNaN(Number(item))) {
mpPath += '.' + item
} else {
mpPath += '[' + item + ']'
}
} else {
mpPath += item
}
})
return mpPath
}