一、什么是 v-model
?
在 Vue 中,v-model
是一个语法糖,主要用于实现表单输入元素和组件之间的双向数据绑定。
通俗地说:
- 当你在
<input>
或自定义组件上使用v-model="something"
, - 它等价于同时做了两件事:
- 绑定
value
属性(:value="something"
) - 监听
input
事件并更新数据(@input="something = $event.target.value"
)
- 绑定
二、使用v-model
准备工作 可见之前的笔记
父组件Parent.vue
<template>
<div class="props-text">
<h1>v-model</h1>
<h1>我是父组件</h1>
<!--
v-model指令:收集表单数据,数据双向绑定
v-model也可以实现组件之间的通信,实现父子组件数据同步的业务
总计之前学到的
父组件给子组件数据:props
子组件给父组件数据:$emit
-->
<input type="number" v-model="msg" >
<hr>
<div>{{msg}}</div>
</hr>
</input>
<hr>
<Child1 :msg="msg" @update:msg="handleUpdate"></Child1>
<hr>
<h3>钱数:{{ money }}</h3>
<!-- <Child2 :modelValue="money" @update:modelValue="updatemodelValue"></Child2> -->
<!--
:modelValue="money" @update:modelValue="updatemodelValue" == v-model="money"
:modelValue 不可自定义
v-model组件身上使用
第一 相当有给子组件传递props[modelValue]= 1000
第二 相当于给子组件绑定了一个自定义事件 update:modelValue
-->
<Child2 v-model="money"></Child2>
<hr>
<h3>pageNo:{{ pageNo }}</h3>
<h3>pageSize:{{ pageSize }}</h3>
<Child3 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child3>
</div>
</template>
<script setup>
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
import Child3 from './Child3.vue'
import { h, ref } from 'vue'
let msg = ref(0)
let money = ref(10000)
const handleUpdate = (value) => {
//接收子组件1传递的数据
console.log(value)
msg.value = msg.value+value;
}
const updatemodelValue = (value) => {
//接收子组件2传递的数据
money.value = value;
}
let pageNo = ref(1)
let pageSize = ref(10)
</script>
<style scoped>
.props-text {
width: 400px;
height: 400px;
background-color: burlywood;
}
</style>
子组件1Child1.vue
<template>
<div class="son1">
<h1>我是子组件1</h1>
<h3>{{ msg }}</h3>
<input type="number" v-model="zi">
<button @click="handle">点击将文本框内容传递给父组件</button>
</div>
</template>
<script setup>
defineProps(["msg"])
let $emit = defineEmits(["update:msg"])
import { ref } from "vue";
let zi = ref(0)
const handle = () => {
console.log(zi.value)
$emit("update:msg", zi.value)
}
</script>
<style>
.son1 {
width: 200px;
height: 200px;
background-color: rgb(132, 27, 202);
}
</style>
子组件2Child2.vue
<template>
<div class="son2">
<h1>我是子组件2</h1>
<h3>{{ modelValue }}</h3>
<button @click="handle">点击将文本框内容传递给父组件</button>
</div>
</template>
<script setup>
let props= defineProps(["modelValue"])
let $emit = defineEmits(["update:modelValue"])
import { ref } from "vue";
const handle = () => {
$emit("update:modelValue", props.modelValue+1000)
}
</script>
<style>
.son2{
width: 200px;
height: 200px;
background-color: rgb(27, 123, 202);
}
</style>
子组件3Child3.vue
<template>
<div class="son2">
<h1>我是子组件3</h1>
<button @click="handle1">pageNo:{{ pageNo }}</button>
<button @click="handle2">pageSize:{{ pageSize }}</button>
<button @click="$emit('update:pageSize', props.pageSize + 20)">pageSize:{{ pageSize }}</button>
</div>
</template>
<script setup>
let props = defineProps(["pageNo", "pageSize"])
let $emit = defineEmits(["update:pageNo", "update:pageSize"])
import { ref } from "vue";
const handle1 = () => {
$emit("update:pageNo", props.pageNo + 1)
}
const handle2 = () => {
$emit("update:pageSize", props.pageSize + 10)
}
</script>
<style>
.son2 {
width: 200px;
height: 200px;
background-color: rgb(27, 202, 80);
}
</style>
三、总结
场景 | 使用方式 |
---|---|
原生 input | v-model="xxx" |
Vue 2 自定义组件 | 接收 value ,触发 input |
Vue 3 自定义组件 | 接收 modelValue ,触发 update:modelValue |
多个双向绑定 | v-model:title="xxx" + v-model:content="yyy" |