你或许会说 没什么区别,就是 @input :value 的 语法糖,最多就是 处理的逻辑多了一点
但是 看一下截图中 箭头 所指的地方
// 看一下指令插入的地方
inserted (el, binding, vnode, oldVnode) {
if (vnode.tag === 'select') {
// #6903
if (oldVnode.elm && !oldVnode.elm._vOptions) {
mergeVNodeHook(vnode, 'postpatch', () => {
directive.componentUpdated(el, binding, vnode)
})
} else {
setSelected(el, binding, vnode.context)
}
el._vOptions = [].map.call(el.options, getValue)
} else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
el._vModifiers = binding.modifiers
if (!binding.modifiers.lazy) {
el.addEventListener('compositionstart', onCompositionStart)
el.addEventListener('compositionend', onCompositionEnd)
// Safari < 10.2 & UIWebView doesn't fire compositionend when
// switching focus before confirming composition choice
// this also fixes the issue where some browsers e.g. iOS Chrome
// fires "change" instead of "input" on autocomplete.
el.addEventListener('change', onCompositionEnd)
/* istanbul ignore if */
if (isIE9) {
el.vmodel = true
}
}
}
没错,你会发现 这里 绑定了 两个不认识的 属性
compositionstart compositionend
// 在 执行 这个的时候先将 composing 置为 true
// 表示 要开始 中文输入法了
function onCompositionStart (e) {
e.target.composing = true
}
// 输入法结束之后,执行这个
// 表示 中文输入法结束了
// 顺便 自己 派发一个 input 事件,这里就是语法糖里 @input 接受的 的事件了
function onCompositionEnd (e) {
// prevent triggering an input event for no reason
if (!e.target.composing) return
e.target.composing = false
trigger(e.target, 'input')
}
// 对 el 节点进行 input 事件派发
function trigger (el, type) {
const e = document.createEvent('HTMLEvents')
e.initEvent(type, true, true)
el.dispatchEvent(e)
}