12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- /* @flow */
- /**
- * Expand input[v-model] with dynamic type bindings into v-if-else chains
- * Turn this:
- * <input v-model="data[type]" :type="type">
- * into this:
- * <input v-if="type === 'checkbox'" type="checkbox" v-model="data[type]">
- * <input v-else-if="type === 'radio'" type="radio" v-model="data[type]">
- * <input v-else :type="type" v-model="data[type]">
- */
- import {
- addRawAttr,
- getBindingAttr,
- getAndRemoveAttr
- } from 'compiler/helpers'
- import {
- processFor,
- processElement,
- addIfCondition,
- createASTElement
- } from 'compiler/parser/index'
- function preTransformNode (el: ASTElement, options: CompilerOptions) {
- if (el.tag === 'input') {
- const map = el.attrsMap
- if (!map['v-model']) {
- return
- }
- let typeBinding
- if (map[':type'] || map['v-bind:type']) {
- typeBinding = getBindingAttr(el, 'type')
- }
- if (!map.type && !typeBinding && map['v-bind']) {
- typeBinding = `(${map['v-bind']}).type`
- }
- if (typeBinding) {
- const ifCondition = getAndRemoveAttr(el, 'v-if', true)
- const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``
- const hasElse = getAndRemoveAttr(el, 'v-else', true) != null
- const elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true)
- // 1. checkbox
- const branch0 = cloneASTElement(el)
- // process for on the main node
- processFor(branch0)
- addRawAttr(branch0, 'type', 'checkbox')
- processElement(branch0, options)
- branch0.processed = true // prevent it from double-processed
- branch0.if = `(${typeBinding})==='checkbox'` + ifConditionExtra
- addIfCondition(branch0, {
- exp: branch0.if,
- block: branch0
- })
- // 2. add radio else-if condition
- const branch1 = cloneASTElement(el)
- getAndRemoveAttr(branch1, 'v-for', true)
- addRawAttr(branch1, 'type', 'radio')
- processElement(branch1, options)
- addIfCondition(branch0, {
- exp: `(${typeBinding})==='radio'` + ifConditionExtra,
- block: branch1
- })
- // 3. other
- const branch2 = cloneASTElement(el)
- getAndRemoveAttr(branch2, 'v-for', true)
- addRawAttr(branch2, ':type', typeBinding)
- processElement(branch2, options)
- addIfCondition(branch0, {
- exp: ifCondition,
- block: branch2
- })
- if (hasElse) {
- branch0.else = true
- } else if (elseIfCondition) {
- branch0.elseif = elseIfCondition
- }
- return branch0
- }
- }
- }
- function cloneASTElement (el) {
- return createASTElement(el.tag, el.attrsList.slice(), el.parent)
- }
- export default {
- preTransformNode
- }
|