v-model常用在父组件给子组件传值,而子组件的值发生变化时,也想让父组件的这个值同步发生变化时。例如,要控制el-dialog的visible,在父组件调用这个弹窗时,把控制显藏的变量传到子组件,在子组件里要关闭弹窗时是需要emit到父组件把变量置为false的,这个时候就可以用到v-model代替一般的传值,当然用其他的传值方式也可以。
- vue2的v-model默认给子组件传的值是value,事件是input。代码示例
父组件
<template>
<div>
值是{{count}}
<!-- <SonPage v-model:value="count" @input= val => count = val></SonPage> -->
<!-- 上面的写法等同于下面 -->
<SonPage v-model="count"></SonPage>
</div>
</template>
<script>
import SonPage from './SonPage.vue';
export default{
name: 'fatherPage',
components: { SonPage },
data() {
return {
count: 1
}
},
}
</script>
子组件
<template>
<div>
{{number}}----number
<button @click="submit()">点击</button>
</div>
</template>
<script>
export default {
name: 'sonPage',
props: ['value'],
data() {
const {value} = this.$props;
return {
number: value
}
},
methods: {
submit() {
this.number = this.number+1;
this.$emit('input', this.number)
}
}
}
</script>
- v-model传递给子组件的prop默认名称为value,事件默认为input,如果想要修改这两个默认值,可以使用model来重新指定,如上面的例子中,指定v-model传递给子组件的名称为info,事件为change(随便写)
export default {
name: 'sonPage',
model: {
prop: 'info',
event: 'change'
},
props: ['info'],
data() {
const {info} = this.$props;
return {
number: info
}
},
methods: {
submit() {
this.number = this.number+1;
this.$emit('change', this.number)
}
}
}
- .sync (vue2.3之后的版本)
v-model 只能针对一个变量进行数据绑定,而 .sync 修饰符可以实现多个参数的数据双向绑定。
而且使用.sync也可以简化写法
<template>
<div>
值是{{count}}
<!-- <SonPage :info="count" @update:info = val => count = val></SonPage> -->
<!-- 上面等价于下面 -->
<SonPage :info.sync="count"></SonPage>
</div>
</template>
<script>
import SonPage from './SonPage.vue';
export default{
name: 'fatherPage',
components: { SonPage },
data() {
return {
count: 1
}
},
}
</script>
<template>
<div>
{{number}}----number
<button @click="submit()">点击</button>
</div>
</template>
<script>
export default {
name: 'sonPage',
props: ['info'],
data() {
const {info} = this.$props;
return {
number: info
}
},
methods: {
submit() {
// this.number = this.number+1;
this.$emit('update:info', this.number+1)
}
}
}
</script>
- vue3版本,摒弃了.sync的写法
<template>
<div>
{{count}}
{{ name }}
<son v-model:info="count" v-model:name="name"></son>
</div>
</template>
<script setup>
import { ref } from 'vue';
import son from './son.vue';
const count = ref(1);
const name = ref('小明');
</script>
<template>
<div>
{{ val }}--val
{{ name }}--name
<button @click="submit">点击</button>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const props = defineProps({
info: {
type: Number,
require: true
},
name: {
type: String,
require: true
}
});
const val = ref(props.info)
const name = ref(props.name)
const emit = defineEmits(['update:info', 'update:name']);
const submit = () => {
emit('update:info', 2);
emit('update:name', '大名');
}
</script>