defineModel的使用:
defineModel选项可以帮我们省去很多麻烦
不仅需要上述操作,还需要进行一定的配置:
在vite.config.js中进行配置
defineModel是一个宏,所以不需要从vue中import导入,直接使用就可以了。这个宏可以用来声明一个双向绑定 prop,通过父组件的 v-model 来使用。
父组件:
<template>
<CommonInput v-model="inputValue" />
</template>
<script setup lang="ts">
import { ref } from "vue";
const inputValue = ref();
</script>
子组件:
<template>
<input v-model="model" />
</template>
<script setup lang="ts">
const model = defineModel();
model.value = "xxx";
</script>
在上面的例子中我们直接将defineModel的返回值使用v-model绑定到input输入框上面,无需定义 modelValue 属性和监听 update:modelValue 事件,代码更加简洁。defineModel的返回值是一个ref,我们可以在子组件中修改model变量的值,并且父组件中的inputValue变量的值也会同步更新,这样就可以实现双向绑定。
同一个变量不要进行多个双向绑定:
使用arco组件的时候,自己封装的组件遇到的一个问题:
<a-tab-pane key="1" :title="`全部${total_1} `">
<comment-table
ref="comTable1"
v-model:delete="deleteDialog1"
v-model:audit="auditDialog1"
v-model:total="total_1"
v-model:search="searchTerm"
itemType="1"
@update:enabled="updateButtonState"
></comment-table>
</a-tab-pane>
<a-tab-pane key="2" :title="`待审${total_2}`">
<comment-table
ref="comTable2"
v-model:delete="deleteDialog2"
v-model:audit="auditDialog2"
v-model:search="searchTerm"
v-model:total="total_2"
itemType="2"
@update:enabled="updateButtonState"
></comment-table>
</a-tab-pane>
<a-tab-pane key="3" :title="`已批准${total_3}`">
<comment-table
ref="comTable3"
v-model:delete="deleteDialog3"
v-model:audit="auditDialog3"
v-model:search="searchTerm"
v-model:total="total_3"
itemType="3"
@update:enabled="updateButtonState"
></comment-table>
</a-tab-pane>
最开始的时候v-model三个自己封装的组件comment-table绑定的都是同一个属性,比如:
v-model:delete="deleteDialog"
v-model:audit="auditDialog"
v-model:search="searchTerm"
复用三个就会出现问题,导致我对第二个子项操作的时候,莫名奇妙itemType就会从2变成3
最后修改成三个区分的变量就没问题了
原因:
v-model
是用于双向绑定的指令,通常用于将父组件的状态与子组件的内部状态进行同步。每个 v-model
都会绑定到一个特定的属性。这意味着在同一时间内,你不能将多个 v-model
指令绑定到同一个变量,因为这会导致数据冲突和不确定的行为。
-
数据冲突:
- 如果多个
v-model
绑定到同一个变量,更新其中一个会导致其他绑定的变量也发生变化,从而产生不一致的状态。
- 如果多个
-
双向绑定的复杂性:
- 双向绑定的设计是为了让数据在父子组件之间保持同步。如果多个组件同时尝试更新同一个数据源,可能会导致难以预料的结果。
-
组件实例化:
- 每个
comment-table
实例可能会有不同的状态和逻辑,试图将它们绑定到同一个变量会使得状态管理变得复杂和混乱。
- 每个