| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import { addHandler, addProp, getBindingAttr } from '../../../../compiler/helpers'
- export default function model (el, dir) {
- const value = dir.value
- const modifiers = dir.modifiers
- if (el.tag === 'select') {
- if (el.attrsMap.multiple != null) {
- genMultiSelect(el, value)
- } else {
- genSelect(el, value)
- }
- } else {
- switch (el.attrsMap.type) {
- case 'checkbox':
- genCheckboxModel(el, value)
- break
- case 'radio':
- genRadioModel(el, value)
- break
- default:
- return genDefaultModel(el, value, modifiers)
- }
- }
- }
- function genCheckboxModel (el, value) {
- const valueBinding = getBindingAttr(el, 'value')
- addProp(el, 'checked',
- `Array.isArray(${value})` +
- `?(${value}).indexOf(${valueBinding})>-1` +
- `:!!(${value})`
- )
- addHandler(el, 'change',
- `var $$a=${value},` +
- '$$el=$event.target,' +
- '$$c=$$el.checked;' +
- 'if(Array.isArray($$a)){' +
- `var $$v=${valueBinding},` +
- '$$i=$$a.indexOf($$v);' +
- 'if($$c){$$i<0&&$$a.push($$v)}' +
- 'else{$$i>-1&&$$a.splice($$i,1)}' +
- `}else{${value}=$$c}`
- )
- }
- function genRadioModel (el, value) {
- const valueBinding = getBindingAttr(el, 'value')
- addProp(el, 'checked', `(${value}==${valueBinding})`)
- addHandler(el, 'change', `${value}=${valueBinding}`)
- }
- function genDefaultModel (el, value, modifiers) {
- const type = el.attrsMap.type
- const { lazy, number, trim } = modifiers || {}
- const event = lazy ? 'change' : 'input'
- const needCompositionGuard = !lazy && type !== 'range'
- const valueExpression = `$event.target.value${trim ? '.trim()' : ''}`
- let code = number || type === 'number'
- ? `${value}=Number(${valueExpression})`
- : `${value}=${valueExpression}`
- if (needCompositionGuard) {
- code = `if($event.target.composing)return;${code}`
- }
- addProp(el, 'value', `(${value})`)
- addHandler(el, event, code)
- if (needCompositionGuard) {
- // need runtime directive code to help with composition events
- return true
- }
- }
- const getSelectedValueCode =
- 'Array.prototype.filter' +
- '.call($event.target.options,function(o){return o.selected})' +
- '.map(function(o){return "_value" in o ? o._value : o.value})'
- function patchChildOptions (el, fn) {
- for (let i = 0; i < el.children.length; i++) {
- let c = el.children[i]
- if (c.tag === 'option') {
- addProp(c, 'selected', fn(getBindingAttr(c, 'value')))
- }
- }
- }
- function genSelect (el, value) {
- addHandler(el, 'change', `${value}=${getSelectedValueCode}[0]`)
- patchChildOptions(el, valueBinding => `$(${value})===(${valueBinding})`)
- }
- function genMultiSelect (el, value) {
- addHandler(el, 'change', `${value}=${getSelectedValueCode}`)
- patchChildOptions(el, valueBinding => `$(${value}).indexOf(${valueBinding})>-1`)
- }
|