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

fxy060608's avatar
fxy060608 已提交
13
const {
fxy060608's avatar
fxy060608 已提交
14 15
  parseIs,
  parseRef,
fxy060608's avatar
fxy060608 已提交
16 17 18 19 20 21 22 23
  parseIf,
  parseFor,
  parseText,
  parseAttrs,
  parseProps,
  parseBinding
} = require('./parser/base-parser')

fxy060608's avatar
fxy060608 已提交
24 25 26 27
const parseTag = require('./parser/tag-parser')
const parseEvent = require('./parser/event-parser')
const parseBlock = require('./parser/block-parser')
const parseComponent = require('./parser/component-parser')
fxy060608's avatar
init v3  
fxy060608 已提交
28

fxy060608's avatar
fxy060608 已提交
29 30 31
const parseWxsProps = require('./parser/wxs-props-parser')
const parseWxsEvents = require('./parser/wxs-events-parser')

fxy060608's avatar
fxy060608 已提交
32
const basePreTransformNode = require('./pre-transform-node')
fxy060608's avatar
init v3  
fxy060608 已提交
33

fxy060608's avatar
fxy060608 已提交
34 35 36 37 38 39
function createGenVar (id, isScopedSlot) {
  if (isScopedSlot) {
    return function genVar (name, value) {
      return `_svm.${GET_DATA}(${id},'${name}')`
    }
  }
fxy060608's avatar
fxy060608 已提交
40 41
  return function genVar (name) {
    return `${GET_DATA}(${id},'${name}')`
fxy060608's avatar
init v3  
fxy060608 已提交
42 43 44
  }
}

fxy060608's avatar
fxy060608 已提交
45
function parseKey (el, isScopedSlot) {
fxy060608's avatar
init v3  
fxy060608 已提交
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
  // add default key
  processForKey(el)

  if (el.key) { // renderList key
    const forEl = getForEl(el)
    if (forEl) {
      if (!isVar(forEl.for)) {
        return
      }
      if (forEl === el) { // <view v-for="item in items" :key="item.id"></view>
        el.key = forEl.alias
      } 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 = `${forEl.alias}['k${keyIndex}']`
      }
    } else {
fxy060608's avatar
fxy060608 已提交
62
      isVar(el.key) && (el.key = createGenVar(el.attrsMap[ID], isScopedSlot)('a-key'))
fxy060608's avatar
init v3  
fxy060608 已提交
63 64 65 66
    }
  }
}

fxy060608's avatar
fxy060608 已提交
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
function parseDirs (el, genVar, ignoreDirs, includeDirs = []) {
  if (!el.directives) {
    return
  }
  el.directives = el.directives.filter(dir => {
    if (includeDirs.indexOf(dir.name) !== -1) {
      if (ignoreDirs.indexOf(dir.name) === -1) {
        dir.value && (dir.value = genVar('v-' + dir.name, dir.value))
        dir.isDynamicArg && (dir.arg = genVar('v-' + dir.name + '-arg', dir.arg))
      }
      return true
    }
  })
}

const includeDirs = [
  'text',
  'html',
  'bind',
  'model',
  'show',
  'if',
  'else',
  'else-if',
  'for',
  'on',
  'bind',
  'slot',
  'pre',
  'cloak',
  'once'
]

const ignoreDirs = ['model']

fxy060608's avatar
fxy060608 已提交
102
function transformNode (el, parent, state, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
103 104 105
  if (el.type === 3) {
    // fixed by xxxxxx 注意:保持平台一致性,trim 一下
    el.text = el.text.trim()
fxy060608's avatar
fxy060608 已提交
106 107
    return
  }
fxy060608's avatar
fxy060608 已提交
108
  parseBlock(el, parent)
fxy060608's avatar
fxy060608 已提交
109 110
  parseComponent(el)
  parseEvent(el)
fxy060608's avatar
fxy060608 已提交
111
  // 更新 id
fxy060608's avatar
fxy060608 已提交
112
  updateForEleId(el, state)
fxy060608's avatar
fxy060608 已提交
113
  updateScopedSlotEleId(el, state)
fxy060608's avatar
init v3  
fxy060608 已提交
114

fxy060608's avatar
fxy060608 已提交
115
  if (el.type === 2) {
fxy060608's avatar
fxy060608 已提交
116 117 118 119
    let pid = parent.attrsMap[ID]
    if (isScopedSlot && String(pid).indexOf('_si') === -1) {
      pid = getNewId(pid, '_si')
    }
fxy060608's avatar
fxy060608 已提交
120
    return parseText(el, parent, {
121
      childIndex: state.childIndex || 0,
fxy060608's avatar
fxy060608 已提交
122 123 124
      index: 0,
      view: 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)
fxy060608's avatar
fxy060608 已提交
132
  parseRef(el, genVar)
fxy060608's avatar
fxy060608 已提交
133
  if (parseFor(el, createGenVar, isScopedSlot)) {
fxy060608's avatar
fxy060608 已提交
134 135 136 137
    if (el.alias[0] === '{') { // <div><li v-for=" { a, b }  in items"></li></div>
      el.alias = '$item'
    }
  }
fxy060608's avatar
fxy060608 已提交
138
  parseKey(el, isScopedSlot)
fxy060608's avatar
init v3  
fxy060608 已提交
139

fxy060608's avatar
fxy060608 已提交
140
  parseIf(el, createGenVar, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
141
  parseBinding(el, genVar)
fxy060608's avatar
fxy060608 已提交
142
  parseDirs(el, genVar, ignoreDirs, includeDirs)
fxy060608's avatar
fxy060608 已提交
143 144 145
  parseWxsProps(el, {
    isAppView: true
  })
fxy060608's avatar
fxy060608 已提交
146 147 148 149 150

  // if (el.attrs) { // TODO 过滤 dataset
  //   el.attrs = el.attrs.filter(attr => attr.name.indexOf('data-') !== 0)
  // }

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

  parseWxsEvents(el, {
    filterModules: state.filterModules,
    isAppView: true
  })
fxy060608's avatar
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 171
      transformNode,
      filterModules: options.filterModules
fxy060608's avatar
fxy060608 已提交
172
    })
fxy060608's avatar
fxy060608 已提交
173
  }
fxy060608's avatar
init v3  
fxy060608 已提交
174 175
}

fxy060608's avatar
fxy060608 已提交
176
function handleViewEvents (events) {
fxy060608's avatar
fxy060608 已提交
177
  Object.keys(events).forEach(name => {
fxy060608's avatar
fxy060608 已提交
178 179 180 181 182 183
    const eventOpts = events[name]
    // wxs
    if (eventOpts.value && eventOpts.value.indexOf('$handleWxsEvent') !== -1) {
      return
    }

fxy060608's avatar
init v3  
fxy060608 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
    const modifiers = Object.create(null)

    let type = name
    const isPassive = type.charAt(0) === '&'
    type = isPassive ? type.slice(1) : type

    const isOnce = type.charAt(0) === '~'
    type = isOnce ? type.slice(1) : type

    const isCapture = type.charAt(0) === '!'
    type = isCapture ? type.slice(1) : type

    isPassive && (modifiers.passive = true)
    isOnce && (modifiers.once = true)
    isCapture && (modifiers.capture = true)

    if (Array.isArray(eventOpts)) {
      eventOpts.forEach(eventOpt => {
        eventOpt.modifiers && Object.assign(modifiers, eventOpt.modifiers)
      })
    } else {
      eventOpts.modifiers && Object.assign(modifiers, eventOpts.modifiers)
    }
    if (Object.keys(modifiers).length) {
      events[name] = {
        value: `$handleViewEvent($event,${JSON.stringify(modifiers)})`
      }
    } else {
      events[name] = {
fxy060608's avatar
fxy060608 已提交
213
        value: '$handleViewEvent($event)'
fxy060608's avatar
init v3  
fxy060608 已提交
214 215 216 217 218
      }
    }
  })
}

fxy060608's avatar
fxy060608 已提交
219
function genVModel (el, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
220
  if (el.model) {
fxy060608's avatar
fxy060608 已提交
221
    el.model.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', el.model.value)
222
    if ((el.tag === 'v-uni-input' || el.tag === 'v-uni-textarea') && !(el.events && el.events.input)) {
223 224
      el.model.callback = `function($$v){$handleVModelEvent(${el.attrsMap[ID]},$$v)}`
    } else {
fxy060608's avatar
fxy060608 已提交
225
      el.model.callback = 'function(){}'
226
    }
fxy060608's avatar
fxy060608 已提交
227 228 229
  }
}

fxy060608's avatar
init v3  
fxy060608 已提交
230
function genData (el) {
fxy060608's avatar
fxy060608 已提交
231 232
  delete el.$parentIterator3

fxy060608's avatar
fxy060608 已提交
233
  genVModel(el)
fxy060608's avatar
init v3  
fxy060608 已提交
234 235

  // 放在 postTransformNode 中处理的时机太靠前,v-model 等指令会新增 event
fxy060608's avatar
fxy060608 已提交
236 237
  el.events && handleViewEvents(el.events)
  el.nativeEvents && handleViewEvents(el.nativeEvents)
fxy060608's avatar
init v3  
fxy060608 已提交
238 239 240 241
  return ''
}

module.exports = {
fxy060608's avatar
fxy060608 已提交
242 243 244 245
  preTransformNode: function (el, options) {
    parseTag(el)
    return basePreTransformNode(el, options)
  },
fxy060608's avatar
init v3  
fxy060608 已提交
246 247
  postTransformNode,
  genData
fxy060608's avatar
fxy060608 已提交
248
}