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

fxy060608's avatar
fxy060608 已提交
5
import {
fxy060608's avatar
fxy060608 已提交
6 7
  V_FOR,
  B_STYLE
fxy060608's avatar
fxy060608 已提交
8 9
} 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
      // 全量同步 style (因为 style 可能会动态删除部分样式)
fxy060608's avatar
fxy060608 已提交
56 57 58 59 60 61 62 63
      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)) {
fxy060608's avatar
fxy060608 已提交
64 65
        const vFor = diffArray(cur, old)
        vFor && setResult(result || (result = Object.create(null)), V_FOR, vFor)
fxy060608's avatar
fxy060608 已提交
66 67 68
      } else {
        setResult(result || (result = Object.create(null)), key, cur)
      }
fxy060608's avatar
init v3  
fxy060608 已提交
69 70
    }
  }
fxy060608's avatar
fxy060608 已提交
71
  return result
fxy060608's avatar
init v3  
fxy060608 已提交
72 73
}

fxy060608's avatar
fxy060608 已提交
74
export function diff (newData, oldData, result) {
fxy060608's avatar
init v3  
fxy060608 已提交
75 76 77 78 79 80 81 82
  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 已提交
83
    const idObj = diffElmData(cur, old)
fxy060608's avatar
fxy060608 已提交
84
    idObj && setResult(result, id, idObj)
fxy060608's avatar
init v3  
fxy060608 已提交
85 86 87
  }
  return result
}