diff.js 1.9 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4
import {
  isPlainObject
} from 'uni-shared'

fxy060608's avatar
fxy060608 已提交
5 6 7 8 9
import {
  V_FOR,
  B_STYLE
} from '../../constants'

fxy060608's avatar
init v3  
fxy060608 已提交
10 11 12 13
function setResult (data, k, v) {
  data[k] = v
}

fxy060608's avatar
fxy060608 已提交
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
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) {
fxy060608's avatar
fxy060608 已提交
50
  let result, key, cur, old
fxy060608's avatar
init v3  
fxy060608 已提交
51 52 53 54
  for (key in newObj) {
    cur = newObj[key]
    old = oldObj[key]
    if (old !== cur) {
fxy060608's avatar
fxy060608 已提交
55
      if (key === B_STYLE && isPlainObject(cur) && isPlainObject(old)) {
fxy060608's avatar
fxy060608 已提交
56
        const style = diffObject(cur, old)
fxy060608's avatar
fxy060608 已提交
57 58 59 60
        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)
fxy060608's avatar
fxy060608 已提交
61 62 63
      } else {
        setResult(result || (result = Object.create(null)), key, cur)
      }
fxy060608's avatar
init v3  
fxy060608 已提交
64 65
    }
  }
fxy060608's avatar
fxy060608 已提交
66
  return result
fxy060608's avatar
init v3  
fxy060608 已提交
67 68
}

fxy060608's avatar
fxy060608 已提交
69
export function diff (newData, oldData, result) {
fxy060608's avatar
init v3  
fxy060608 已提交
70 71 72 73 74 75 76 77
  let id, cur, old
  for (id in newData) {
    cur = newData[id]
    old = oldData[id]
    if (!old) {
      setResult(result, id, cur)
      continue
    }
fxy060608's avatar
fxy060608 已提交
78
    const idObj = diffElmData(cur, old)
fxy060608's avatar
fxy060608 已提交
79
    idObj && setResult(result, id, idObj)
fxy060608's avatar
init v3  
fxy060608 已提交
80 81 82
  }
  return result
}