import { isPlainObject } from 'uni-shared' import { V_FOR, B_STYLE } from '../../constants' function setResult (data, k, v) { data[k] = v } function diffObject (newObj, oldObj, every = true) { let result, key, cur, old for (key in newObj) { cur = newObj[key] old = oldObj[key] if (old !== cur) { if (!every) { return newObj } setResult(result || (result = Object.create(null)), key, cur) } } return result } function diffArray (newArr, oldArr) { const newLen = newArr.length if (newLen !== oldArr.length) { return newArr } if (isPlainObject(newArr[0])) { for (let i = 0; i < newLen; i++) { if (diffObject(newArr[i], oldArr[i], false)) { return newArr } } } else { for (let i = 0; i < newLen; i++) { if (newArr[i] !== oldArr[i]) { return newArr } } } } function diffElmData (newObj, oldObj) { let result, key, cur, old for (key in newObj) { cur = newObj[key] old = oldObj[key] if (old !== cur) { // 全量同步 style (因为 style 可能会动态删除部分样式) if (key === B_STYLE && isPlainObject(cur) && isPlainObject(old)) { if (Object.keys(cur).length !== Object.keys(old).length) { // 长度不等 setResult(result || (result = Object.create(null)), B_STYLE, cur) } else { const style = diffObject(cur, old, false) style && setResult(result || (result = Object.create(null)), B_STYLE, style) } } else if (key === V_FOR && Array.isArray(cur) && Array.isArray(old)) { const vFor = diffArray(cur, old) vFor && setResult(result || (result = Object.create(null)), V_FOR, vFor) } else { setResult(result || (result = Object.create(null)), key, cur) } } } return result } export function diff (newData, oldData, result) { let id, cur, old for (id in newData) { cur = newData[id] old = oldData[id] if (!old) { setResult(result, id, cur) continue } const idObj = diffElmData(cur, old) idObj && setResult(result, id, idObj) } return result }