view.js 5.9 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 118 119 120
    return parseText(el, parent, {
      index: 0,
      view: true,
      // <uni-popup>{{content}}</uni-popup>
fxy060608's avatar
fxy060608 已提交
121
      genVar: createGenVar(pid, isScopedSlot)
fxy060608's avatar
fxy060608 已提交
122
    })
fxy060608's avatar
fxy060608 已提交
123 124
  }

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

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

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

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

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

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

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

fxy060608's avatar
fxy060608 已提交
156
function postTransformNode (el, options) {
fxy060608's avatar
fxy060608 已提交
157
  if (!el.parent) { // 从根节点开始递归处理
fxy060608's avatar
fxy060608 已提交
158 159
    traverseNode(el, false, {
      forIteratorId: 0,
fxy060608's avatar
fxy060608 已提交
160 161
      transformNode,
      filterModules: options.filterModules
fxy060608's avatar
fxy060608 已提交
162
    })
fxy060608's avatar
fxy060608 已提交
163
  }
fxy060608's avatar
init v3  
fxy060608 已提交
164 165
}

fxy060608's avatar
fxy060608 已提交
166
function handleViewEvents (events) {
fxy060608's avatar
fxy060608 已提交
167
  Object.keys(events).forEach(name => {
fxy060608's avatar
fxy060608 已提交
168 169 170 171 172 173
    const eventOpts = events[name]
    // wxs
    if (eventOpts.value && eventOpts.value.indexOf('$handleWxsEvent') !== -1) {
      return
    }

fxy060608's avatar
init v3  
fxy060608 已提交
174 175 176 177 178 179 180 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
    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 已提交
209
function genVModel (el, isScopedSlot) {
fxy060608's avatar
fxy060608 已提交
210
  if (el.model) {
fxy060608's avatar
fxy060608 已提交
211
    el.model.value = createGenVar(el.attrsMap[ID], isScopedSlot)('v-model', el.model.value)
fxy060608's avatar
fxy060608 已提交
212 213 214 215 216 217 218 219
    if (el.tag === 'v-uni-input' || el.tag === 'v-uni-textarea') {
      el.model.callback = `function($$v){$handleVModelEvent(${el.attrsMap[ID]},$$v)}`
    } else {
      el.model.callback = `function(){}`
    }
  }
}

fxy060608's avatar
init v3  
fxy060608 已提交
220
function genData (el) {
fxy060608's avatar
fxy060608 已提交
221 222
  delete el.$parentIterator3

fxy060608's avatar
fxy060608 已提交
223
  genVModel(el)
fxy060608's avatar
init v3  
fxy060608 已提交
224 225

  // 放在 postTransformNode 中处理的时机太靠前,v-model 等指令会新增 event
fxy060608's avatar
fxy060608 已提交
226 227
  el.events && handleViewEvents(el.events)
  el.nativeEvents && handleViewEvents(el.nativeEvents)
fxy060608's avatar
init v3  
fxy060608 已提交
228 229 230 231
  return ''
}

module.exports = {
fxy060608's avatar
fxy060608 已提交
232 233 234 235
  preTransformNode: function (el, options) {
    parseTag(el)
    return basePreTransformNode(el, options)
  },
fxy060608's avatar
init v3  
fxy060608 已提交
236 237 238
  postTransformNode,
  genData
}