1
0

More than 1 year has passed since last update.

Composition APIでPrimeVueのDynamicDialogを使おうとしたらDialogが閉じれず困った件(解決)

Last updated at Posted at 2022-07-18

概要

タイトルの通り。
未解決ですが調べて分かったことをメモ。

2022/07/23追記
なんと@MertSincanさん(PrimeVueの開発者の方)から本記事へコメントを頂き、解決することができそうです!
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とごっちゃになっている気が...)
    image.png

解決編

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使っていきましょう!!!

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0