About this post
on the web page, the progress bar tends to be global component.
And, it is preferred to be opened from TypeScript (not from Vue template using v-if ) because the bar should be opened only while the process.
In this post, the way of implementation about progress bar opened from TypeScript is introduced.
Target readers
- the developers who want to implement progressbarby Vue.js or Nuxt.js
- the developers who have basics about store and Vuetify.js (some basic parts of store and Vuetify will be omitted.)
Versions
| content | version | 
|---|---|
| nuxt | 2.15.8 | 
| nuxt-typed-vuex | 0.3.0 | 
| vue | 2.6.14 | 
| vuetify | 2.6.1 | 
the directory structure
sampleProject
├componens
| └progressbar.vue
├pages
| └index.vue
├store
| ├index.ts
| └progressbar.ts
└types
  └index.d.ts
Steps to open the progress bar from TypeScript
- the heavy process is executed.
- the store of progressbaris called.
- while the heavy process is executed, progress bar component is shown thanks to the store of of progressbar.
- after the heavy process is done, progress bar component is not shown anymore.
Create a store to control progress bar
Create store/progressbar.ts.
import { mutationTree, actionTree } from 'typed-vuex';
// isShown is to control whether progress bar is shown or not
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) {
      // only while action is executed, the progress bar is opened
      commit('change', true);
      try {
        await action();
      } finally {
        // even if the argument action throws an error, the progress bar should be closed
        commit('change', false);
      }
    },
  },
);
Register the store by creating store/index.ts.
import {
  getAccessorType,
  getterTree,
  mutationTree,
  actionTree,
} from 'typed-vuex';
// if there is other stores, import here
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: {
    // if there is other stores, add here
    progressbar,
  },
});
Extend the types for vue so that the store can be accessed from the file of vue extension.
create types/index.d.ts
import { accessorType } from '~~/store';
declare module 'vue/types/vue' {
  interface Vue {
    $accessor: typeof accessorType;
  }
}
Create a progress bar component
By the implementation of this.$store.subscribe, catch the change notification of store progressbar and change the visibility according to isShown store value.
<template>
  <!-- set z-index so that this progress bar can be shown above the modal dialog -->
  <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>
Open progress bar from TypeScript
Create pages/index.vue .
Only in the scope of await this.$accessor.progressbar.open(async () => {}); , the progress bar is shown.
<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 () => {
        // in this scope, the progress bar is shown
        await this.$axios.get('https://example.com');
      });
      // out of the scope of progress bar, the progress bar is not shown
    },
  },
});
</script>
 
 
              
 
    
Top comments (0)