0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Vue.js, Nuxt.js】storeを使用してTypeScriptの処理中にprogressbarを起動させる(progressbarのグローバル化)

Posted at

この記事について

以下のようなprogressbarをVueのtemplate上での v-if や v-show での表示制御ではなく、TypeScript側から任意のタイミングで表示できるようにする方法をこの記事で紹介します。
image.png
以下の記事で記載した実装と同じ考え方で実装しております。
【Vue.js, Nuxt.js】storeを使用してTypeScript側からsnackbarを起動させる

対象読者

  • Vue.js(やNuxt.js)でprogressbarをTypeScriptの処理中に表示したい方
  • Vue.jsのstoreの実装を行ったことのある方
  • Vuetifyの(簡易的な)実装を行ったことのある方

環境

内容 バージョン
nuxt 2.15.8
nuxt-typed-vuex 0.3.0
vue 2.6.14
vuetify 2.6.1

以下の内容は、Nuxt.jsを使用していることを前提とします。
ディレクトリ構成

sampleProject
├componens
| └progressbar.vue
├pages
| └index.vue
├store
| ├index.ts
| └progressbar.ts
└types
  └index.d.ts

処理の流れ

考え方としては、「progressbar用のstoreを作成して、store呼び出し時にprogressbarコンポーネントを表示する」として、「progressbarコンポーネントをグローバルに扱う」考え方としております。

progressbarを表示したい処理の実行

progressbar用のstoreの呼び出し(progressbar表示中に実行したい処理も一緒に引き渡す)

処理中はprogressbarを表示するようにstoreのstateを更新

処理後はprogressbarを非表示とするようにstoreのstateを更新

こちらの記事の「処理の流れ」と同じような流れとなっております。

progressbar用のstoreの作成

storeはprogressbar用の個別storeを管理する progressbar.ts と 他のstoreも含めて管理する index.ts に分けております。

store/progressbar.ts
import { mutationTree, actionTree } from 'typed-vuex';

// progressbar表示/非表示の制御用のデータのみをstateで管理
export const state = () => ({
  isShown: false as boolean,
});
export type RootState = ReturnType<typeof state>;

export const mutations = mutationTree(state, {
  change(state, isShown: boolean) {
    state.isShown = isShown;
  },
});

export const actions = actionTree(
  { state, mutations },
  {
    async open({ commit }, action: Function) {
      // actionを実行中のみprogressbarをオン、実行後はオフとする
      commit('change', true);
      try {
        await action();
      } finally {
        // 引き渡された処理が失敗した時を想定してfinally内でprogressbarを非表示とする
        commit('change', false);
      }
    },
  },
);
store/index.ts
import {
  getAccessorType,
  getterTree,
  mutationTree,
  actionTree,
} from 'typed-vuex';
// その他のstoreがある場合はここで他のstoreをimportする
import * as progressbar from './progressbar';

export const state = () => ({});
export const getters = getterTree(state, {});
export const mutations = mutationTree(state, {});
export const actions = actionTree({ state, getters, mutations }, {});
export const accessorType = getAccessorType({
  state,
  getters,
  mutations,
  actions,
  modules: {
    // その他のstoreがある場合はmodulesに他のstoreを追加する
    progressbar,
  },
});

VueファイルのTypeScriptからstoreにアクセスできるように、index.d.ts を以下のように編集します。

types/index.d.ts
import { accessorType } from '~~/store';

declare module 'vue/types/vue' {
  interface Vue {
    $accessor: typeof accessorType;
  }
}

declare module '@nuxt/types' {
  interface NuxtAppOptions {
    $accessor: typeof accessorType;
  }
}

progressbarコンポーネントの作成

先ほど作成したprogressbar用のstoreのstate変更を検知するように実装( this.$store.subscribe の部分)します。
progressbarはVuetifyのコンポーネントを使用しております。

componens/progressbar.vue
<template>
  <!-- モーダルダイアログよりも上に表示できるようにz-indexを設定 -->
  <v-overlay z-index="100" :value="isShown">
    <v-progress-circular indeterminate color="primary"></v-progress-circular>
  </v-overlay>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'AppProgressbar',
  data() {
    return {
      isShown: false,
    };
  },
  created() {
    this.$store.subscribe((mutation, state) => {
      if (mutation.type === 'progressbar/change') {
        this.isShown = state.progressbar.isShown;
      }
    });
  },
});
</script>

TypeScriptからprogressbarを表示

progressbarを表示する際は、components/progressbar.vue を直接呼び出すのではなく、先ほど作成したstoreを呼び出してstore経由でprogressbarを表示します。
vueのtemplate内でprogressbarを v-ifv-show で表示制御せずともTypeScriptから表示/非表示とすることができるようになりました。

pages/index.vue
<template>
  <button @click="doHeavyProcess">Execute</button>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  methods: {
    async doHeavyProcess() {
      await this.$accessor.progressbar.open(async () => {
        // この中の処理中にprogressbarが表示され、処理が終了するとprogressbarが非表示となる
        await this.$axios.get('https://example.com');
      });
    },
  },
});
</script>

参考

How to create a global snackbar using Nuxt, Vuetify and Vuex.
【Vue.js, Nuxt.js】storeを使用してTypeScript側からsnackbarを起動させる

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?