报错场景再现
由于原来做的组件代码行太多并且有个抽屉组件被复制粘贴3次,按照我的习惯,同段代码被引用3次以上就要做组件抽离方便后续维护
需求
把抽屉部分抽离,显隐由父组件控制
于是,问题出现当初次打开抽屉,好好的,但让抽屉关闭时,抽屉是关闭了,但弹出警告Set operation on key “showDrawer” failed: target is readonly. 并且再也不能打开
代码
抽屉组件
<template>
<div>
<ElDrawer
v-model="showDrawer"
:size="50%"
title="签批进度"
>
....
</ElDrawer>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
showDrawer: Boolean
})
const { showDrawer } = toRefs(props)
</script>
父组件
<template>
<div>
...
<button @click="openDrawer">签批进度</button>
...
<!-- 签批进度 -->
<drawer-c :show-drawer="drawerr" />
...
</div>
</template>
<script lang="ts" setup>
const drawerr = ref(false)
function openDrawer() {
drawerr.value = true
}
</script>
找寻原因
在点击关闭时,由于双向绑定,vue去更改抽屉组件showDrawer,想将其真变假,但其只读不让改,所以报错并阻止了修改,但抽屉为什么能在showDrawer没变的情况下关闭,这个没去研究
探索解决 办法
看到前辈们也曾遇到同样的问题,一开始共找到两种解决办法
-
办法
-
v-model
改为:model-value
- 若用的是antd,需要调下版本
以上两个办法,对我都没作用,首先,方法一就是从双向绑定变为单向绑定,这是不报错了,但还是不能再次打开了
解决
寻寻觅觅,查阅很多文章了解原理,终于解决,话不多说,上代码
抽屉组件
<template>
<div>
<ElDrawer
v-model="visibleD "
:size="50%"
title="签批进度"
>
....
</ElDrawer>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
showDrawer: Boolean
})
const { showDrawer } = toRefs(props)
const emits = defineEmits(['toggleStatus'])
//先用自己的属性
const visibleD = ref(false)
const toggle = (newVal: boolean) => (visibleD.value = newVal)
//监测showDrawer触发visibleD
watch(
() => showDrawer .value,
(newVal) => {
toggle(newVal)
}
)
//监测visibleD触发showDrawer的变值方法
watch(
() => visibleD.value,
(newVal) => {
console.log('visible=------', newVal)
emits('toggleStatus', newVal)
}
)
</script>
父组件
<template>
<div>
...
<button @click="openDrawer">签批进度</button>
...
<!-- 签批进度 -->
<drawer-c :show-drawer="drawerr" @toggle-status="switchDrawerr" />
...
</div>
</template>
<script lang="ts" setup>
const drawerr = ref(false)
function openDrawer() {
drawerr.value = true
}
function switchDrawerr(show: boolean) {
drawerr.value = show
}
</script>
至此问题解决!