service.js 4.8 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 75 76
  }
}

fxy060608's avatar
fxy060608 已提交
77 78 79 80 81 82 83 84 85 86 87 88
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)
    }
  })
}

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

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

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

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

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

fxy060608's avatar
fxy060608 已提交
133
  parseIs(el, genVar)
fxy060608's avatar
fxy060608 已提交
134
  parseRef(el, genVar)
135
  parseFor(el, createGenVar, isScopedSlot, checkAutoFill(el))
fxy060608's avatar
fxy060608 已提交
136
  parseKey(el, isScopedSlot)
fxy060608's avatar
init v3  
fxy060608 已提交
137

fxy060608's avatar
fxy060608 已提交
138
  parseIf(el, createGenVar, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
139
  parseBinding(el, genVar)
fxy060608's avatar
fxy060608 已提交
140
  parseDirs(el, genVar, ['model'])
fxy060608's avatar
init v3  
fxy060608 已提交
141

fxy060608's avatar
fxy060608 已提交
142 143 144 145
  parseWxsProps(el, {
    isAppService: true
  })

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

fxy060608's avatar
fxy060608 已提交
152
  parseProps(el, genVar)
fxy060608's avatar
fxy060608 已提交
153 154 155 156 157

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

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

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

function genData (el) {
  delete el.$parentIterator3

fxy060608's avatar
fxy060608 已提交
194
  genVModel(el)
fxy060608's avatar
fxy060608 已提交
195 196 197 198

  return ''
}

fxy060608's avatar
init v3  
fxy060608 已提交
199
module.exports = {
fxy060608's avatar
fxy060608 已提交
200
  preTransformNode,
fxy060608's avatar
init v3  
fxy060608 已提交
201 202
  postTransformNode,
  genData
fxy060608's avatar
fxy060608 已提交
203
}