面试官:知道v-model吗?
你:知道,语法糖封装 <input v-bind:value="message" v-on:input="message= $event.target.value"/>
要打面试官得这样:
总结:源码model函数判断Ast对象的tag来区分绑定类型--然后触发不同的绑定方法来处理
input/textarea会走genDefaultModel函数绑定
//input/textarea类型走input函数绑定,但如果加了lazy点缀符,会变成绑定change
const event = lazy
? 'change'
: type === 'range'
? RANGE_TOKEN
: 'input'
addHandler(el, event, code, null, true)
radio/select/checkbox都是绑定change处理
function genRadioModel (
el: ASTElement,
value: string,
modifiers: ?ASTModifiers
) {
const number = modifiers && modifiers.number
let valueBinding = getBindingAttr(el, 'value') || 'null'
valueBinding = number ? `_n(${valueBinding})` : valueBinding
addProp(el, 'checked', `_q(${value},${valueBinding})`)
addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true)
}
genAssignmentCode函数--用于生成 v 模型值赋值代码的跨平台 codegen 帮助程序
export function genAssignmentCode (
value: string,
assignment: string
): string {
const res = parseModel(value)
if (res.key === null) {
return `${value}=${assignment}`
} else {
return `$set(${res.exp}, ${res.key}, ${assignment})`
}
}