随手写系列-别再傻傻只回答v-model只是input语法糖封装了

92 阅读1分钟

面试官:知道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})`
  }
}