| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- /* @flow */
- /**
- * Expand input[v-model] with dyanmic 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 {
- 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'] && (map['v-bind:type'] || map[':type'])) {
- const typeBinding: any = getBindingAttr(el, 'type')
- const ifCondition = getAndRemoveAttr(el, 'v-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 = `type==='checkbox'` + (ifCondition ? `&&(${ifCondition})` : ``)
- 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: `type==='radio'` + (ifCondition ? `&&(${ifCondition})` : ``),
- 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
- })
- return branch0
- }
- }
- }
- function cloneASTElement (el) {
- return createASTElement(el.tag, el.attrsList.slice(), el.parent)
- }
- function addRawAttr (el, name, value) {
- el.attrsMap[name] = value
- el.attrsList.push({ name, value })
- }
- export default {
- preTransformNode
- }
|