view.js 6.1 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
  parseIs,
fxy060608's avatar
fxy060608 已提交
15 16 17 18 19 20 21 22
  parseIf,
  parseFor,
  parseText,
  parseAttrs,
  parseProps,
  parseBinding
} = require('./parser/base-parser')

fxy060608's avatar
fxy060608 已提交
23 24 25 26
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 已提交
27

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

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

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

fxy060608's avatar
fxy060608 已提交
44
function parseKey (el, isScopedSlot) {
fxy060608's avatar
init v3  
fxy060608 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
  // 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 已提交
61
      isVar(el.key) && (el.key = createGenVar(el.attrsMap[ID], isScopedSlot)('a-key'))
fxy060608's avatar
init v3  
fxy060608 已提交
62 63 64 65
    }
  }
}

fxy060608's avatar
fxy060608 已提交
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
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 已提交
101
function transformNode (el, parent, state, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
102 103 104
  if (el.type === 3) {
    return
  }
fxy060608's avatar
fxy060608 已提交
105
  parseBlock(el, parent)
fxy060608's avatar
fxy060608 已提交
106 107
  parseComponent(el)
  parseEvent(el)
fxy060608's avatar
fxy060608 已提交
108
  // 更新 id
fxy060608's avatar
fxy060608 已提交
109
  updateForEleId(el, state)
fxy060608's avatar
fxy060608 已提交
110
  updateScopedSlotEleId(el, state)
fxy060608's avatar
init v3  
fxy060608 已提交
111

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

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

fxy060608's avatar
fxy060608 已提交
128 129
  parseIs(el, genVar)

fxy060608's avatar
fxy060608 已提交
130
  if (parseFor(el, createGenVar, isScopedSlot)) {
fxy060608's avatar
fxy060608 已提交
131 132 133 134
    if (el.alias[0] === '{') { // <div><li v-for=" { a, b }  in items"></li></div>
      el.alias = '$item'
    }
  }
fxy060608's avatar
fxy060608 已提交
135
  parseKey(el, isScopedSlot)
fxy060608's avatar
init v3  
fxy060608 已提交
136

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

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

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

  parseWxsEvents(el, {
    filterModules: state.filterModules,
    isAppView: true
  })
fxy060608's avatar
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, {
      createGenVar,
fxy060608's avatar
fxy060608 已提交
166
      forIteratorId: 0,
fxy060608's avatar
fxy060608 已提交
167 168
      transformNode,
      filterModules: options.filterModules
fxy060608's avatar
fxy060608 已提交
169
    })
fxy060608's avatar
fxy060608 已提交
170
  }
fxy060608's avatar
init v3  
fxy060608 已提交
171 172
}

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

fxy060608's avatar
init v3  
fxy060608 已提交
181 182 183 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 213 214 215
    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] = {
        value: `$handleViewEvent($event)`
      }
    }
  })
}

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

fxy060608's avatar
init v3  
fxy060608 已提交
227
function genData (el) {
fxy060608's avatar
fxy060608 已提交
228 229
  delete el.$parentIterator3

fxy060608's avatar
fxy060608 已提交
230
  genVModel(el)
fxy060608's avatar
init v3  
fxy060608 已提交
231 232

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

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