概要
タイトルの通り。
未解決ですが調べて分かったことをメモ。
2022/07/23追記
なんと@MertSincanさん(PrimeVueの開発者の方)から本記事へコメントを頂き、解決することができそうです!
CodeSandboxに修正後のソースが上がっていますので、実際の動作は下記から確認ください。
- CodeSandbox
使おうとしたもの
PrimeVue - Dynamic Dialog
PrimeVue ver 3.15.0
事象
Dialogの子コンポーネントからダイアログを閉じようとするとエラーが発生。
エラー内容
Uncaught TypeError: dialogRef.close is not a function
at Proxy.closeDialog (index.js?e1de:39:1)
at onClick._cache.<computed>._cache.<computed> (templateLoader.js?e847:21:1)
at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?d2dd:164:1)
at HTMLButtonElement.invoker (runtime-dom.esm-bundler.js?2725:366:1)
ソース例
- ダイアログ呼び元
<template>
<div class="test">
<Button type="button" label="ダイアログ表示" @click="showDialog" />
</div>
<DynamicDialog />
</template>
<script lang="ts">
import { useDialog } from 'primevue/usedialog';
import testDialog from './dialog/testDialog.vue';
export default {
setup() {
const dialog = useDialog();
return {
showDialog() {
dialog.open(testDialog);
},
};
},
};
</script>
- ダイアログ側
<template>
<div class="testDialog">
test
<Button label="閉じる" @click="onClose()" />
</div>
</template>
<script lang="ts">
import { inject } from 'vue';
export default {
setup() {
const dialogRef = inject<any>('dialogRef'); // <any>はコンパイルエラー回避のため
return {
onClose: () => {
if (dialogRef != null) dialogRef.close(); // nullチェックはコンパイルエラー回避のため
},
};
},
};
</script>
調べたこと
2022/07/23追記
以下、Vueをよくわかっていない人が苦戦しているだけの内容なので縮めます...
- ダイアログ側のコンポーネントをOptions Apiで書くと動いた(Composition Apiで書きたいのじゃが..)
- ソース例
<template>
<div class="testDialog">
test
<Button label="閉じる" @click="onClose()" />
</div>
</template>
<script>
export default {
inject: ['dialogRef'],
methods: {
onClose() {
this.dialogRef.close();
},
},
};
</script>
- PrimeVueのDialogコンポーネントはOptions Apiで書かれている
- Githubのソース
- そのため、provide側がOptions Api、inject側がComposition Apiの書き方になっていた
- このパターンの記述は公式ガイドには見当たらない
- できないってこと!?
- このパターンの記述は公式ガイドには見当たらない
- そもそも、PrimeVueのComposition Api例もおかしい(Options Apiとごっちゃになっている気が...)
解決編
2022/07/23追記
ダイアログ側でdialogRef
に.value
をつけるだけでよいとのことです!(己の無知を痛感...)
(まだ私のローカルPCでは試せていませんが、取り急ぎ追記です)
公式ドキュメントも修正して頂きました!
@MertSincan Thanks!
<template>
<div class="testDialog">
test
<Button label="閉じる" @click="onClose()" />
</div>
</template>
<script lang="ts">
import { inject } from 'vue';
export default {
setup() {
const dialogRef = inject<any>('dialogRef');
return {
onClose: () => {
if (dialogRef != null) dialogRef.value.close();
},
};
},
};
</script>
結論
ver 3.15.0でのDynamicDialogの利用はあきらめて、Dialogの表示/非表示で実装する。
(動かす方法はあるのかもしれませんが…)
DynamicDialog使っていきましょう!!!