一、原理
v-model不仅可以用在表单上面,还可以用在组件上面完成组件通信
v-model本质上是一个语法糖。例如应用在输入框上,就是value属性
和 input事件
的合写。
语法糖:即一种语法的简写
不同的表单元素, v-model在底层的处理机制是不一样的。比如给checkbox使用v-model底层处理的是 checked属性和change事件。
不过咱们只需要掌握应用在文本框上的原理即可
二、作用
提供数据的双向绑定
- 数据变,视图跟着变
:value
- 视图变,数据跟着变
@input
语法糖:即一种语法的简写
注意:$event 用于在模板中,获取事件的形参
<template>
<div id="app" >
<input v-model="msg" type="text">
// ① 数据变,视图跟着变 :value
// ② 视图变,数据跟着变 @input
<input :value="msg" @input="msg = $event.target.value" type="text">
</div>
</template>
三、表单类组件封装
在工作中会使用到大量的表单内容,通常来说会把它封装成组件,比如说下拉组件,一旦涉及到组件,就会涉及到组件通信,而这些组件通信就可以使用v-model来简化
需求目标
实现子组件和父组件数据的双向绑定 (实现App.vue中的selectId和子组件选中的数据进行双向绑定)
① 父传子:数据 应该是父组件 props 传递 过来的,拆解 v-model 绑定数据
因为只有将数据绑定在父组件上,将来才能拿这个数据进行表单提交
由于v-model是双向绑定,所以它是不能直接和父组件的值绑定,因为子组件是不能直接修改父组件的数据的,所以此时需要进行v-model的拆解,拆解成:value和@change
② 子传父:监听输入,子传父传值给父组件修改
代码实例
App.vue
<template>
<div class="app">
<BaseSelect
:selectId="selectId"
<!-- 父组件直接使用$event获取形参 -->
@changeCity="selectId = $event"
></BaseSelect>
</div>
</template>
<script>
import BaseSelect from './components/BaseSelect.vue'
export default {
data() {
return {
selectId: '102',
}
},
components: {
BaseSelect,
},
}
</script>
<style>
</style>
BaseSelect.vue
<template>
<div>
<select :value="selectId" @change="selectCity">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">武汉</option>
<option value="104">广州</option>
<option value="105">深圳</option>
</select>
</div>
</template>
<script>
export default {
props: {
selectId: String,
},
methods: {
selectCity(e) {
this.$emit('changeCity', e.target.value)
},
},
}
</script>
<style>
</style>
四、v-model简化代码
目标
父组件通过v-model 简化代码,实现子组件和父组件数据 双向绑定
v-model其实就是 :value和@input事件的简写
- 子组件:props通过value接收数据,事件触发 input
- 父组件:v-model直接绑定数据
子组件
<select :value="value" @change="handleChange">...</select>
<script>
props: {
value: String
},
methods: {
handleChange (e) {
// 子传父必须触发固定的input事件
this.$emit('input', e.target.value)
}
}
</script>
父组件
<BaseSelect :value="selectId" @input="selectedId = $event"></BaseSelect>
<BaseSelect v-model="selectId"></BaseSelect>