util.js 2.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 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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
const VARS = ['true', 'false', 'null']
const NUMBER_RE = /^-?\d*(\.\d+)?$/

const ID = '_i'
const ITERATOR = '$i'
const DATA_ROOT = '$r'

function isVar (str) {
  if (!str) {
    return false
  }
  const firstLetter = str[0]
  if (
    firstLetter === '"' || // string
    firstLetter === '\'' || // string
    VARS.includes(str) || // boolean | null
    NUMBER_RE.test(str) // number
  ) {
    return false
  }
  return true
}

function addAttr (el, name, value) {
  el.attrsMap[name] = value
  el.attrsList.push({
    name,
    value
  })
}

function updateEleId (el, it) {
  if (el.type !== 1) {
    return
  }
  const id = el.attrsMap[ID]
  const newId = Number.isInteger(id) ? `("${id}-"+${it})` : `(${id}+${it})`
  addAttr(el, ID, newId)
  const attr = el.attrs.find(attr => attr.name === ID)
  attr.value = newId
  el.children.forEach(child => {
    updateEleId(child, it)
  })
}

function getBindingAttr (el, name) {
  return getAndRemoveAttr(el, ':' + name) ||
    getAndRemoveAttr(el, 'v-bind:' + name)
}

function getAndRemoveAttr (el, name) {
  let val
  if ((val = el.attrsMap[name]) != null) {
    const list = el.attrsList
    for (let i = 0, l = list.length; i < l; i++) {
      if (list[i].name === name) {
        list.splice(i, 1)
        break
      }
    }
  }
  delete el.attrsMap[name]
  return val
}

function updateForEleId (el) {
  if (el.for) {
    if (!el.iterator1) {
      el.iterator1 = ITERATOR
    }
    updateEleId(el, el.iterator2 || el.iterator1)
  }
}

function getForEl (el) {
  if (el.for) {
    return el
  }
  if (el.parent && el.parent.for && el.parent.tag === 'template') {
    return el.parent
  }
}

function processForKey (el) {
  const forEl = getForEl(el)
  if (forEl && !el.key) {
    if (!isVar(forEl.for)) { // <view v-for="10"></view>
      return
    }
    const it = forEl.iterator2 || forEl.iterator1 || ITERATOR
    if (forEl.tag === 'template') {
      if (forEl !== el) {
        const keyIndex = forEl.children.indexOf(el)
        el.key = `'${forEl.forId}-${keyIndex}-'+${it}`
      } else { // 当 template 下只有文本节点
        if (el.children && el.children.length && !el.children.find(child => child.key)) {
          el.children[0].key = `'${forEl.forId}-0-'+${it}`
          return true
        }
      }
    } else {
      el.key = `'${forEl.forId}-'+${it}`
    }
  }
}

module.exports = {
  ID,
  DATA_ROOT,
  ITERATOR,
  isVar,
  addAttr,
  getForEl,
  processForKey,
  updateForEleId,
  getBindingAttr,
fxy060608's avatar
fxy060608 已提交
117 118 119 120
  getAndRemoveAttr,
  hasOwn: function (obj, key) {
    return hasOwnProperty.call(obj, key)
  }
fxy060608's avatar
init v3  
fxy060608 已提交
121
}