1、Vue中v-model的实现原理
组件 v-model
可以看成是 value+input 方法 的语法糖
<el-checkbox :value="" @input=""></el-checkbox> <el-checkbox v-model="check"></el-checkbox>
原理: 组件的 v-model 将默认转化成 value+input
const VueTemplateCompiler = require('vue-template-compiler');
const ele = VueTemplateCompiler.compile('<el-checkbox v-model="check"></el-checkbox>');
//编译结果
with(this) {
return _c('el-checkbox', {
model: {
value: (check),
callback: function ($$v) {
check = $$v
},
expression: "check"
}
})
}
core/vdom/create-component.js line:155
function transformModel (options, data: any) {
const prop = (options.model && options.model.prop) || 'value'
const event = (options.model && options.model.event) || 'input' ;
(data.attrs || (data.attrs = {}))[prop] = data.model.value;//data.attrs.value="xxx"
const on = data.on || (data.on = {})
const existing = on[event]
const callback = data.model.callback
if (isDef(existing)) {
if (
Array.isArray(existing)
? existing.indexOf(callback) === -1
: existing !== callback ) {
on[event] = [callback].concat(existing)
}
} else {
on[event] = callback
}
}
普通的标签上的 v-model ,会根据标签的不同生成不同的事件和属性
const VueTemplateCompiler = require('vue-template-compiler');
const ele = VueTemplateCompiler.compile('<input v-model="value"/>');
with(this) {
return _c('input', {
directives: [{
name: "model",
rawName: "v-model",
value: (value),
expression: "value"
}],
domProps: {
"value": (value) },
on: {
"input": function ($event) {
if ($event.target.composing) return;
value = $event.target.value
}
}
})
}
编译时:不同的标签解析出的内容不一样
platforms/web/compiler/directives/model.js
if (el.component) {
genComponentModel(el, value, modifiers) // component v-model doesn't need extra runtime
return false
} else if (tag === 'select') {
genSelect(el, value, modifiers)
} else if (
tag === 'input' && type === 'checkbox') {
genCheckboxModel(el, value, modifiers)
} else if (tag === 'input' && type === 'radio') {
genRadioModel(el, value, modifiers)
} else if (tag === 'input' || tag === 'textarea') {
genDefaultModel(el, value, modifiers)
} else if (!config.isReservedTag(tag)) {
genComponentModel(el, value, modifiers) // component v-model doesn't need extra runtime
return false
}
2、如何自定义v-model
自定义v-model 的含义
Vue.component('el-checkbox',{
template:`<input type="checkbox" :checked="check" @change="$emit('change',$event.target.checked)">`,
model:{
prop:'check', // 更改默认的value的名字
event:'change' // 更改默认的方法名
},props: {
check: Boolean
}
})