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

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

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

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

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

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

fxy060608's avatar
fxy060608 已提交
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 102
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 已提交
103
function transformNode (el, parent, state, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
104 105 106
  if (el.type === 3) {
    // fixed by xxxxxx 注意:保持平台一致性,trim 一下
    el.text = el.text.trim()
fxy060608's avatar
fxy060608 已提交
107 108
    return
  }
fxy060608's avatar
fxy060608 已提交
109
  parseBlock(el, parent)
fxy060608's avatar
fxy060608 已提交
110 111
  parseComponent(el)
  parseEvent(el)
fxy060608's avatar
fxy060608 已提交
112
  // 更新 id
fxy060608's avatar
fxy060608 已提交
113
  updateForEleId(el, state)
fxy060608's avatar
fxy060608 已提交
114
  updateScopedSlotEleId(el, state)
fxy060608's avatar
init v3  
fxy060608 已提交
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
    return parseText(el, parent, {
122
      childIndex: state.childIndex || 0,
fxy060608's avatar
fxy060608 已提交
123 124 125
      index: 0,
      view: true,
      // <uni-popup>{{content}}</uni-popup>
fxy060608's avatar
fxy060608 已提交
126
      genVar: createGenVar(pid, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
127
    })
fxy060608's avatar
fxy060608 已提交
128 129
  }

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

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

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

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

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

  parseWxsEvents(el, {
    filterModules: state.filterModules,
    isAppView: true
  })
fxy060608's avatar
fxy060608 已提交
160 161
}

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

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

fxy060608's avatar
init v3  
fxy060608 已提交
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
    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 已提交
215
        value: '$handleViewEvent($event)'
fxy060608's avatar
init v3  
fxy060608 已提交
216 217 218 219 220
      }
    }
  })
}

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

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

fxy060608's avatar
fxy060608 已提交
235
  genVModel(el)
fxy060608's avatar
init v3  
fxy060608 已提交
236 237

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

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