一、单向数据流
vue是单向数据流的,所以v-model其实是破坏性的
v-model是一个语法糖:
- 在vue2中v-model是input(根据表单类型决定)事件和value的结合;
- 在vue3中v-model是props和emit的结合
二、使用案例
v-model默认绑定的事件是'update:modelValue',默认绑定的数据是modelValue
效果:
?
父组件:
<template>
<div class="parent">
<div>我是父组件</div>
<el-button @click="changeName">我不同意你改</el-button>
<div>我有{{money}}万元,败家儿子和我一块花</div>
<Child v-model:money="money" v-model="name"></Child>
</div>
</template>
<script setup lang="ts">
import Child from './child.vue';
const name = ref<string>('法外狂徒-张三');
const money = ref<number>(100);
const changeName = ()=>{
name.value = '法外狂徒-张三';
}
</script>
<style scoped lang="less">
.parent {
width: 500px;
padding: 10px;
background-color: aquamarine;
}
</style>
子组件:
<template lang="">
<div class="child">
<div>我是子组件</div>
<div>父亲起的名字:{{modelValue}}</div>
<el-button @click="changName">户籍室改名字</el-button>
<el-button @click="consume">花老爹的钱寻开心</el-button>
</div>
</template>
<script setup lang="ts">
type Props = {
modelValue: string,
money: number
};
const parentData = defineProps<Props>();
let childMoney = parentData.money;
const emit = defineEmits(['update:modelValue','update:money']);
const consume=()=>{
emit('update:money', --childMoney)
}
const changName = () => {
emit('update:modelValue', '尼古拉斯-赵四')
};
</script>
<style scoped lang="less">
.child {
padding: 20px;
background-color: bisque;
}
</style>
三、自定义修饰符
添加到组件?v-model ?的修饰符将通过?modelModifiers ?prop 提供给组件。
改造父组件:
<Child v-model:money.myModifier="money" v-model="name"></Child>
改造子组件
<script setup lang="ts">
type Props = {
modelValue: string,
money: number,
moneyModifiers?: {
myModifier: boolean
}
};
const parentData = defineProps<Props>();
let childMoney = parentData.money;
const emit = defineEmits(['update:modelValue', 'update:money']);
const consume = () => {
console.log(parentData.moneyModifiers);
// 可以通过判断此修饰符是否为true,来做一些相关的操作
if(parentData?.moneyModifiers?.myModifier){
emit('update:money', --childMoney)
}else{
emit('update:money', childMoney-=2)
}
}
</script>
|