一、单向数据流

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>

Logo

前往低代码交流专区

更多推荐