service.js 4.7 KB
Newer Older
fxy060608's avatar
init v3  
fxy060608 已提交
1 2
const {
  ID,
fxy060608's avatar
fxy060608 已提交
3 4
  V_FOR,
  SET_DATA,
fxy060608's avatar
fxy060608 已提交
5
  isVar,
fxy060608's avatar
fxy060608 已提交
6
  getNewId,
fxy060608's avatar
init v3  
fxy060608 已提交
7 8
  getForEl,
  processForKey,
fxy060608's avatar
fxy060608 已提交
9
  updateForEleId,
fxy060608's avatar
fxy060608 已提交
10 11
  traverseNode,
  updateScopedSlotEleId
fxy060608's avatar
init v3  
fxy060608 已提交
12 13
} = require('./util')

fxy060608's avatar
fxy060608 已提交
14 15 16 17
const {
  isComponent
} = require('../util')

fxy060608's avatar
fxy060608 已提交
18
const {
fxy060608's avatar
fxy060608 已提交
19
  parseIs,
fxy060608's avatar
fxy060608 已提交
20 21 22 23 24 25 26 27 28
  parseIf,
  parseFor,
  parseText,
  parseDirs,
  parseAttrs,
  parseProps,
  parseBinding
} = require('./parser/base-parser')

fxy060608's avatar
fxy060608 已提交
29 30
const parseEvent = require('./parser/event-parser')
const parseBlock = require('./parser/block-parser')
fxy060608's avatar
init v3  
fxy060608 已提交
31

fxy060608's avatar
fxy060608 已提交
32 33 34
const parseWxsProps = require('./parser/wxs-props-parser')
const parseWxsEvents = require('./parser/wxs-events-parser')

fxy060608's avatar
fxy060608 已提交
35
const preTransformNode = require('./pre-transform-node')
fxy060608's avatar
init v3  
fxy060608 已提交
36

fxy060608's avatar
fxy060608 已提交
37 38
const optimize = require('./optimizer')

fxy060608's avatar
fxy060608 已提交
39 40 41 42 43 44
function createGenVar (id, isScopedSlot) {
  if (isScopedSlot) {
    return function genVar (name, value) {
      return `_svm.${SET_DATA}(${id},'${name}',${value})`
    }
  }
fxy060608's avatar
fxy060608 已提交
45 46
  return function genVar (name, value) {
    return `${SET_DATA}(${id},'${name}',${value})`
fxy060608's avatar
init v3  
fxy060608 已提交
47 48 49
  }
}

fxy060608's avatar
fxy060608 已提交
50
function parseKey (el, isScopedSlot) {
fxy060608's avatar
init v3  
fxy060608 已提交
51 52 53 54
  // add default key
  if (processForKey(el)) {
    el = el.children[0] // 当 template 下仅文本时,处理第一个动态文本
  }
fxy060608's avatar
fxy060608 已提交
55 56
  if (!el.key || el.key.indexOf(SET_DATA) === 0) {
    return
fxy060608's avatar
init v3  
fxy060608 已提交
57
  }
fxy060608's avatar
fxy060608 已提交
58 59
  const forEl = getForEl(el)
  if (!forEl) {
fxy060608's avatar
fxy060608 已提交
60
    return isVar(el.key) && (el.key = createGenVar(el.attrsMap[ID], isScopedSlot)('a-key', el.key))
fxy060608's avatar
init v3  
fxy060608 已提交
61
  }
fxy060608's avatar
fxy060608 已提交
62 63
  if (!isVar(forEl.for)) {
    return
fxy060608's avatar
init v3  
fxy060608 已提交
64
  }
fxy060608's avatar
fxy060608 已提交
65 66
  const forId = forEl.forId
  const it = forEl.iterator2
fxy060608's avatar
fxy060608 已提交
67
  const genVar = createGenVar(forId, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
68 69 70 71 72
  if (forEl === el) { // <view v-for="item in items" :key="item.id"></view>
    el.key = genVar(V_FOR, `{forIndex:${it},key:${el.key}}`)
  } else { // <template v-for="item in items"><view :key="item.id+'1'"></view><view :key="item.id+'2'"></view></template>
    const keyIndex = forEl.children.indexOf(el)
    el.key = genVar(V_FOR, `{forIndex:${it},keyIndex:${keyIndex},key:${el.key}}`)
fxy060608's avatar
init v3  
fxy060608 已提交
73 74 75
  }
}

fxy060608's avatar
fxy060608 已提交
76 77 78 79 80 81 82 83 84 85 86 87
function parseComponentAttrs (el, genVar) {
  el.attrs && el.attrs.forEach(attr => {
    const {
      name,
      value
    } = attr
    if (name.indexOf('data-') === 0) {
      attr.value = genVar('a-' + name, value)
    }
  })
}

88 89 90 91 92 93 94
function checkAutoFill (el) {
  if (
    el.for &&
    (
      el.tag === 'template' ||
      el.tag === 'block'
    ) &&
95 96 97 98 99
    !el.children.find(child =>
      child.type === 1 &&
      child.tag !== 'template' &&
      child.tag !== 'block'
    )
100 101 102 103 104 105
  ) {
    return true
  }
  return false
}

fxy060608's avatar
fxy060608 已提交
106
function transformNode (el, parent, state, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
107
  if (el.type === 3) {
fxy060608's avatar
init v3  
fxy060608 已提交
108 109
    return
  }
fxy060608's avatar
fxy060608 已提交
110
  parseBlock(el, parent)
fxy060608's avatar
fxy060608 已提交
111
  parseEvent(el)
fxy060608's avatar
init v3  
fxy060608 已提交
112

fxy060608's avatar
fxy060608 已提交
113
  updateForEleId(el, state)
fxy060608's avatar
fxy060608 已提交
114
  updateScopedSlotEleId(el, state)
115

fxy060608's avatar
fxy060608 已提交
116
  if (el.type === 2) {
fxy060608's avatar
fxy060608 已提交
117 118 119 120
    let pid = parent.attrsMap[ID]
    if (isScopedSlot && String(pid).indexOf('_si') === -1) {
      pid = getNewId(pid, '_si')
    }
fxy060608's avatar
fxy060608 已提交
121 122 123 124
    return parseText(el, parent, {
      index: 0,
      service: true,
      // <uni-popup>{{content}}</uni-popup>
fxy060608's avatar
fxy060608 已提交
125
      genVar: createGenVar(pid, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
126
    })
fxy060608's avatar
fxy060608 已提交
127 128
  }

fxy060608's avatar
fxy060608 已提交
129
  const genVar = createGenVar(el.attrsMap[ID], isScopedSlot)
fxy060608's avatar
fxy060608 已提交
130

fxy060608's avatar
fxy060608 已提交
131
  parseIs(el, genVar)
132
  parseFor(el, createGenVar, isScopedSlot, checkAutoFill(el))
fxy060608's avatar
fxy060608 已提交
133
  parseKey(el, isScopedSlot)
fxy060608's avatar
init v3  
fxy060608 已提交
134

fxy060608's avatar
fxy060608 已提交
135
  parseIf(el, createGenVar, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
136
  parseBinding(el, genVar)
fxy060608's avatar
fxy060608 已提交
137
  parseDirs(el, genVar, ['model'])
fxy060608's avatar
init v3  
fxy060608 已提交
138

fxy060608's avatar
fxy060608 已提交
139 140 141 142
  parseWxsProps(el, {
    isAppService: true
  })

fxy060608's avatar
fxy060608 已提交
143 144
  if (!isComponent(el.tag)) {
    parseAttrs(el, genVar)
fxy060608's avatar
fxy060608 已提交
145 146
  } else { // 目前的方案需要同步dataset
    parseComponentAttrs(el, genVar)
fxy060608's avatar
fxy060608 已提交
147
  }
fxy060608's avatar
init v3  
fxy060608 已提交
148

fxy060608's avatar
fxy060608 已提交
149
  parseProps(el, genVar)
fxy060608's avatar
fxy060608 已提交
150 151 152 153 154

  parseWxsEvents(el, {
    filterModules: state.filterModules,
    isAppService: true
  })
fxy060608's avatar
init v3  
fxy060608 已提交
155 156
}

fxy060608's avatar
fxy060608 已提交
157
function postTransformNode (el, options) {
fxy060608's avatar
fxy060608 已提交
158
  if (!el.parent) { // 从根节点开始递归处理
159 160 161 162 163
    if (options.root) { // 当根节点是由if,elseif,else组成
      parseIf(options.root, createGenVar)
    } else {
      options.root = el
    }
fxy060608's avatar
fxy060608 已提交
164 165
    traverseNode(el, false, {
      forIteratorId: 0,
fxy060608's avatar
fxy060608 已提交
166 167
      transformNode,
      filterModules: options.filterModules
fxy060608's avatar
fxy060608 已提交
168
    })
fxy060608's avatar
fxy060608 已提交
169
    optimize(el, options)
fxy060608's avatar
fxy060608 已提交
170 171
  }
}
fxy060608's avatar
fxy060608 已提交
172

fxy060608's avatar
fxy060608 已提交
173
function genVModel (el, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
174 175 176 177 178 179
  if (
    (el.tag === 'input' || el.tag === 'textarea') &&
    el.directives &&
    el.directives.find(dir => dir.name === 'model')
  ) {
    const prop = el.props.find(prop => prop.name === 'value')
fxy060608's avatar
fxy060608 已提交
180
    prop.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', prop.value)
fxy060608's avatar
fxy060608 已提交
181
  }
fxy060608's avatar
fxy060608 已提交
182
  if (el.model) {
fxy060608's avatar
fxy060608 已提交
183
    el.model.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', el.model.value)
fxy060608's avatar
fxy060608 已提交
184 185 186 187 188 189
  }
}

function genData (el) {
  delete el.$parentIterator3

fxy060608's avatar
fxy060608 已提交
190
  genVModel(el)
fxy060608's avatar
fxy060608 已提交
191 192 193 194

  return ''
}

fxy060608's avatar
init v3  
fxy060608 已提交
195
module.exports = {
fxy060608's avatar
fxy060608 已提交
196
  preTransformNode,
fxy060608's avatar
init v3  
fxy060608 已提交
197 198
  postTransformNode,
  genData
fxy060608's avatar
fxy060608 已提交
199
}