service.js 5.0 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
  parseRef,
fxy060608's avatar
fxy060608 已提交
21 22 23 24 25 26 27 28 29
  parseIf,
  parseFor,
  parseText,
  parseDirs,
  parseAttrs,
  parseProps,
  parseBinding
} = require('./parser/base-parser')

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

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

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

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

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

fxy060608's avatar
fxy060608 已提交
51
function parseKey (el, isScopedSlot) {
fxy060608's avatar
init v3  
fxy060608 已提交
52 53 54 55
  // add default key
  if (processForKey(el)) {
    el = el.children[0] // 当 template 下仅文本时,处理第一个动态文本
  }
fxy060608's avatar
fxy060608 已提交
56 57
  if (!el.key || el.key.indexOf(SET_DATA) === 0) {
    return
fxy060608's avatar
init v3  
fxy060608 已提交
58
  }
fxy060608's avatar
fxy060608 已提交
59 60
  const forEl = getForEl(el)
  if (!forEl) {
fxy060608's avatar
fxy060608 已提交
61
    return isVar(el.key) && (el.key = createGenVar(el.attrsMap[ID], isScopedSlot)('a-key', el.key))
fxy060608's avatar
init v3  
fxy060608 已提交
62
  }
fxy060608's avatar
fxy060608 已提交
63 64
  if (!isVar(forEl.for)) {
    return
fxy060608's avatar
init v3  
fxy060608 已提交
65
  }
fxy060608's avatar
fxy060608 已提交
66 67
  const forId = forEl.forId
  const it = forEl.iterator2
fxy060608's avatar
fxy060608 已提交
68
  const genVar = createGenVar(forId, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
69 70 71 72 73
  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 已提交
74
  }
Q
qiang 已提交
75 76 77
  if (el.tag === 'slot') {
    el.attrs.push({ name: 'key', value: el.key })
  }
fxy060608's avatar
init v3  
fxy060608 已提交
78 79
}

fxy060608's avatar
fxy060608 已提交
80 81 82 83 84 85
function parseComponentAttrs (el, genVar) {
  el.attrs && el.attrs.forEach(attr => {
    const {
      name,
      value
    } = attr
fxy060608's avatar
fxy060608 已提交
86
    if (isVar(value) && (name === 'id' || name.indexOf('data-') === 0)) {
fxy060608's avatar
fxy060608 已提交
87 88 89 90 91
      attr.value = genVar('a-' + name, value)
    }
  })
}

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

fxy060608's avatar
fxy060608 已提交
110
function transformNode (el, parent, state, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
111 112
  if (el.type === 3) {
    // fixed by xxxxxx 注意:保持平台一致性,trim 一下,理论上service不需要,保险起见也处理一遍
fxy060608's avatar
fxy060608 已提交
113
    el.text = el.text.trim()
fxy060608's avatar
init v3  
fxy060608 已提交
114 115
    return
  }
fxy060608's avatar
fxy060608 已提交
116
  parseBlock(el, parent)
fxy060608's avatar
fxy060608 已提交
117
  parseEvent(el)
fxy060608's avatar
init v3  
fxy060608 已提交
118

fxy060608's avatar
fxy060608 已提交
119
  updateForEleId(el, state)
fxy060608's avatar
fxy060608 已提交
120
  updateScopedSlotEleId(el, state)
121

fxy060608's avatar
fxy060608 已提交
122
  if (el.type === 2) {
fxy060608's avatar
fxy060608 已提交
123 124 125 126
    let pid = parent.attrsMap[ID]
    if (isScopedSlot && String(pid).indexOf('_si') === -1) {
      pid = getNewId(pid, '_si')
    }
fxy060608's avatar
fxy060608 已提交
127
    return parseText(el, parent, {
128
      childIndex: state.childIndex || 0,
fxy060608's avatar
fxy060608 已提交
129 130 131
      index: 0,
      service: true,
      // <uni-popup>{{content}}</uni-popup>
fxy060608's avatar
fxy060608 已提交
132
      genVar: createGenVar(pid, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
133
    })
fxy060608's avatar
fxy060608 已提交
134 135
  }

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

fxy060608's avatar
fxy060608 已提交
138
  parseIs(el, genVar)
fxy060608's avatar
fxy060608 已提交
139
  parseRef(el, genVar)
140
  parseFor(el, createGenVar, isScopedSlot, checkAutoFill(el))
fxy060608's avatar
fxy060608 已提交
141
  parseKey(el, isScopedSlot)
fxy060608's avatar
init v3  
fxy060608 已提交
142

fxy060608's avatar
fxy060608 已提交
143
  parseIf(el, createGenVar, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
144
  parseBinding(el, genVar)
fxy060608's avatar
fxy060608 已提交
145
  parseDirs(el, genVar, ['model'])
fxy060608's avatar
init v3  
fxy060608 已提交
146

fxy060608's avatar
fxy060608 已提交
147 148 149 150
  parseWxsProps(el, {
    isAppService: true
  })

fxy060608's avatar
fxy060608 已提交
151 152
  if (!isComponent(el.tag)) {
    parseAttrs(el, genVar)
fxy060608's avatar
fxy060608 已提交
153 154
  } else { // 目前的方案需要同步dataset
    parseComponentAttrs(el, genVar)
fxy060608's avatar
fxy060608 已提交
155
  }
fxy060608's avatar
init v3  
fxy060608 已提交
156

fxy060608's avatar
fxy060608 已提交
157
  parseProps(el, genVar)
fxy060608's avatar
fxy060608 已提交
158 159 160 161 162

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

fxy060608's avatar
fxy060608 已提交
165
function postTransformNode (el, options) {
fxy060608's avatar
fxy060608 已提交
166
  if (!el.parent) { // 从根节点开始递归处理
167 168 169 170 171
    if (options.root) { // 当根节点是由if,elseif,else组成
      parseIf(options.root, createGenVar)
    } else {
      options.root = el
    }
fxy060608's avatar
fxy060608 已提交
172
    traverseNode(el, false, {
fxy060608's avatar
fxy060608 已提交
173
      createGenVar,
fxy060608's avatar
fxy060608 已提交
174
      forIteratorId: 0,
fxy060608's avatar
fxy060608 已提交
175
      transformNode,
fxy060608's avatar
fxy060608 已提交
176
      filterModules: options.filterModules
fxy060608's avatar
fxy060608 已提交
177
    })
fxy060608's avatar
fxy060608 已提交
178
    optimize(el, options)
fxy060608's avatar
fxy060608 已提交
179 180
  }
}
fxy060608's avatar
fxy060608 已提交
181

fxy060608's avatar
fxy060608 已提交
182
function genVModel (el, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
183 184 185 186 187 188
  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 已提交
189
    prop.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', prop.value)
fxy060608's avatar
fxy060608 已提交
190
  }
fxy060608's avatar
fxy060608 已提交
191
  if (el.model) {
fxy060608's avatar
fxy060608 已提交
192
    el.model.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', el.model.value)
fxy060608's avatar
fxy060608 已提交
193 194 195 196 197 198
  }
}

function genData (el) {
  delete el.$parentIterator3

fxy060608's avatar
fxy060608 已提交
199
  genVModel(el)
fxy060608's avatar
fxy060608 已提交
200 201 202 203

  return ''
}

fxy060608's avatar
init v3  
fxy060608 已提交
204
module.exports = {
fxy060608's avatar
fxy060608 已提交
205
  preTransformNode,
fxy060608's avatar
init v3  
fxy060608 已提交
206 207
  postTransformNode,
  genData
fxy060608's avatar
fxy060608 已提交
208
}