data.js 3.6 KB
Newer Older
fxy060608's avatar
init v3  
fxy060608 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import {
  guid,
  hasOwn
} from 'uni-shared'

import {
  VDomSync
} from './vdom-sync'

import {
  MOUNTED_DATA,
  UPDATED_DATA
} from '../../../constants'

import {
  diff
} from './diff'

fxy060608's avatar
fxy060608 已提交
19
export function initData(Vue) {
fxy060608's avatar
init v3  
fxy060608 已提交
20 21 22 23 24
  Vue.prototype._$s = setData
  Vue.prototype._$i = setIfData
  Vue.prototype._$f = setForData
  Vue.prototype._$e = setElseIfData

fxy060608's avatar
fxy060608 已提交
25
  Vue.prototype._$setData = function setData(type, data) {
fxy060608's avatar
init v3  
fxy060608 已提交
26
    this._$vd.push(type, this._$id, data)
fxy060608's avatar
fxy060608 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  }

  Vue.prototype._$mounted = function mounted() {
    if (!this._$vd) {
      return
    }
    diff(this._$newData, this._$data, this._$vdMountedData)
    this._$data = JSON.parse(JSON.stringify(this._$newData))
    console.log(`[${this._$id}] mounted ` + Date.now())
    if (this.mpType === 'page') {
      // 页面 mounted 之后,第一次同步数据
      this._$vd.flush()
    }
  }

  Vue.prototype._$updated = function updated() {
    if (!this._$vd) {
      return
    }
    diff(this._$newData, this._$data, this._$vdUpdatedData)
    this._$data = JSON.parse(JSON.stringify(this._$newData))
    console.log(`[${this._$id}] updated ` + Date.now())
fxy060608's avatar
fxy060608 已提交
49
    this._$vd.initialized && this.$nextTick(this._$vd.flush.bind(this._$vd))
fxy060608's avatar
init v3  
fxy060608 已提交
50 51 52
  }

  Object.defineProperty(Vue.prototype, '_$vd', {
fxy060608's avatar
fxy060608 已提交
53
    get() {
fxy060608's avatar
init v3  
fxy060608 已提交
54 55 56 57 58
      return this.$root._$vdomSync
    }
  })

  Vue.mixin({
fxy060608's avatar
fxy060608 已提交
59
    beforeCreate() {
fxy060608's avatar
init v3  
fxy060608 已提交
60 61 62 63 64 65 66 67 68 69 70 71
      if (this.$options.mpType) {
        this.mpType = this.$options.mpType
      }
      if (this.mpType === 'app') {
        return
      }
      if (this.mpType === 'page') {
        this._$vdomSync = new VDomSync(this.$options.pageId, this.$options.pagePath)
      }
      if (this._$vd) {
        this._$id = guid()
        this._$vd.addVm(this)
fxy060608's avatar
fxy060608 已提交
72 73
        this._$vdMountedData = Object.create(null)
        this._$setData(MOUNTED_DATA, this._$vdMountedData)
fxy060608's avatar
init v3  
fxy060608 已提交
74 75 76 77 78 79
        console.log(`[${this._$id}] beforeCreate ` + Date.now())
        // 目前全量采集做 diff(iOS 需要保留全量状态做 restore),理论上可以差量采集
        this._$data = Object.create(null)
        this._$newData = Object.create(null)
      }
    },
fxy060608's avatar
fxy060608 已提交
80
    beforeUpdate() {
fxy060608's avatar
init v3  
fxy060608 已提交
81 82 83
      if (!this._$vd) {
        return
      }
fxy060608's avatar
fxy060608 已提交
84 85
      this._$vdUpdatedData = Object.create(null)
      this._$setData(UPDATED_DATA, this._$vdUpdatedData)
fxy060608's avatar
init v3  
fxy060608 已提交
86 87 88
      console.log(`[${this._$id}] beforeUpdate ` + Date.now())
      this._$newData = Object.create(null)
    },
fxy060608's avatar
fxy060608 已提交
89
    beforeDestroy() {
fxy060608's avatar
init v3  
fxy060608 已提交
90 91 92 93
      if (!this._$vd) {
        return
      }
      this._$vd.removeVm(this)
fxy060608's avatar
fxy060608 已提交
94
      this._$vdomSync && this._$vdomSync.destroy()
fxy060608's avatar
init v3  
fxy060608 已提交
95 96 97 98
    }
  })
}

fxy060608's avatar
fxy060608 已提交
99
function setData(id, name, value) {
fxy060608's avatar
init v3  
fxy060608 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
  const diffData = this._$newData[id] || (this._$newData[id] = {})

  if (typeof name !== 'string') {
    for (let key in name) {
      diffData[key] = name[key]
    }
    return name
  }

  if (name === 'a-_i') {
    return value
  }
  return (diffData[name] = value)
}

fxy060608's avatar
fxy060608 已提交
115 116 117 118 119 120 121 122
function setForData(id, value) {
  const diffData = this._$newData[id] || (this._$newData[id] = {})
  const vForData = diffData['v-for'] || (diffData['v-for'] = [])

  if (value.forItems) {
    return value.forItems
  }

fxy060608's avatar
init v3  
fxy060608 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135
  const {
    forIndex,
    key
  } = value

  if (!hasOwn(value, 'keyIndex')) {
    vForData[forIndex] = key
  } else {
    (vForData[forIndex] || (vForData[forIndex] = {}))['k' + value.keyIndex] = key
  }
  return key
}

fxy060608's avatar
fxy060608 已提交
136
function setIfData(id, value) {
fxy060608's avatar
init v3  
fxy060608 已提交
137 138 139
  return ((this._$newData[id] || (this._$newData[id] = {}))['v-if'] = value)
}

fxy060608's avatar
fxy060608 已提交
140
function setElseIfData(id, value) {
fxy060608's avatar
init v3  
fxy060608 已提交
141 142
  return ((this._$newData[id] || (this._$newData[id] = {}))['v-else-if'] = value)
}