我有一个问题需要解决。
a.ts
const open = ref<boolean>(false)
h(RowAction, {
open: open,
onDelete: () => {
Data.remove().then(() => {}).catch(() => {}).finally(() => (open.value = false))
}
})
RowAction.vue
<script lang="ts" setup>
defineProps<{open: boolean}>()
defineEmits<{ (e: 'delete'): void }>()
</script>
<template>
<div>
<button @click="$emit('delete')">
delete
</button>
</div>
<my-alert :open="open">
<alert-tetx>test</alert-text>
<button @click="open = false">close</button>
<button @click="$emit('delete')">delete</button>
</my-alert>
</template>
我希望删除事件在单击时运行,并在承诺解决或拒绝后关闭警报。但是,我不知道为什么我的代码没有运行。
暴露和管理
open
的内部属性 RowAction
可能不是一个完美的设计模式。只需在 delete
事件中提供解决/拒绝对,即可将问题范围缩小到仅事件回调:
RowAction.vue:
<script setup lang="ts" >
import {ref} from 'vue';
const open = ref(false);
const error = ref('');
const $emit = defineEmits<{ (e: 'delete', deffer: () => ReturnType<PromiseConstructor['withResolvers']>) }>()
function onDelete(){
let needsResolving = false;
error.value = '';
$emit('delete', () => {
needsResolving = true;
const {promise, resolve, reject} = Promise.withResolvers();
promise.then(() => open.value = false).catch(e => error.value = e.message);
return {promise, resolve, reject};
});
needsResolving || (open.value = false);
}
</script>
<template>
<div>
<button @click="open = true">
delete
</button>
<dialog :open>
<div> are you sure to delete ? </div>
<div style="font-size: small;color: red;">{{ error }}</div>
<button @click="open = false">close</button>
<button @click="onDelete">delete</button>
</dialog>
</div>
</template>
应用程序.vue
<script setup lang="ts">
import {h} from 'vue';
import RowAction from './RowAction.vue';
class Data{
static remove(){
return new Promise((resolve, reject) => {
Math.random() > .5 ?
setTimeout(resolve, 1000) :
setTimeout(() => reject(new Error('Operation has failed')), 1000);
});
}
}
function render(){
return h(RowAction, {
onDelete: async (defer) => {
const {resolve, reject} = defer();
Data.remove().then(resolve, reject);
}
});
}
</script>
<template>
<label>With promise work</label>
<render/>
<label>Immediate</label>
<row-action/>
</template>