vue2 vue3
vue2
<!-- 原生组件 -->
<input v-model="val" />
<input :value="val" @input="val = $event.target.value">
<!-- 自定义组件 -->
<my-component v-model="val" />
<my-component :value="val" @input="val = arguments[0]">
<!-- 非同寻常的表单元素 -->
<input type="checkbox" :checked='val' @change='updateInput' />
<template>
<input type="checkbox" :checked='checked' @change='updateInput' />
</template>
export default {
props: {
checked: Boolean
},
// 针对 非同寻常的表单元素
model: {
prop: 'checked', // 绑定的属性名(变化的属性)
event: 'change' // 触发事件的事件名 (改变值的事件)
},
methods: {
updateInput(e) {
this.$emit('change', e.target.checked)
}
}
}
<BaseCheckbox v-model='checked' />
<div>{{checked}}</div>
checked: false
vue3 compile 以后的结果
vue3 组件上的model被移除
<my-component v-model="foo" />
h(Comp, {
modelValue: foo,
'onUpdate:modelValue':value => (foo = value)
})
自定义组件上使用 v-model
- 需要在props创建 modelValue属性
- 事件名称 onUpdate:modelValue
<!-- ValidateInput -->
<input type="text"
class="form-control"
:value="inputRef.val"
@blur="validateInput"
@input="updateValue"
:class="{'is-invalid': inputRef.error}"
>
props: {
rules: Array as PropType<RulesProp>,
modelValue: String
},
const inputRef = reactive({
val: props.modelValue || '', // 传入的值是 props.modelValue
error: false,
message: ''
})
const updateValue = (e: KeyboardEvent) => {
const targetValue = (e.target as HTMLInputElement).value
inputRef.val = targetValue
context.emit('update:modelValue', targetValue)
}
<!-- APP -->
<validate-input :rules="emailRules" v-model="emailVal" />
vue3支持多个 v-model
vue2
<body>
<!--
v-model 指令
限制:input、select、textarea、组件上
比如当我们的组件中包含有 input、select、textarea 这三种类型的某一种元素时。并且
该元素的 value 需要由外层组件的数据来进行控制。
这时就可以在调用这个组件时使用 v-model 来进行双向数据绑定
一、不用 v-model 来实现上面的需求
二、查考一然后思考换成 v-model
<base-input :value="msg1" @input="msg1 = $event"></base-input>
v-model => :value 和 @input
:value 和 @input => v-model
-->
<div id="app">
<!--
$event
1. 原生事件时它是事件对象
2. 自定义事件时它是触发事件时传递过来的payload参数
-->
<base-input :value="msg1" @input="msg1 = $event"></base-input>
<base-input :value="msg2" @input="msg2 = $event"></base-input>
<base-input v-model="msg1"></base-input>
<base-input v-model="msg2"></base-input>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>
<script>
Vue.component("baseInput", {
props: {
value: {
type: String,
},
},
template: `
<div>
<input type="text" :value="value" @input="handleInput" />
</div>
`,
methods: {
handleInput(event) {
// 得到输入的内容 this.value 不行
// 用原生的方式去获取 e.target.value
// 1. 先获取输入的内容
let value = event.target.value;
console.log(value);
// 2. 通知父组件,将value作为payload传递过去
this.$emit("input", value);
},
},
});
var vm = new Vue({
el: "#app",
data: {
msg1: "hello",
msg2: "world",
},
});
</script>
学习笔记❥(^_-)