I want to handle components asynchronously in Nuxt.js and display alert messages

Viewed 228

What I want to come true

I want to display an alert message considering the result of the data sent to the server. However, since alert messages are managed by another component, it is necessary to call the component asynchronously. The official Vue.js documentation used Vue.component, but what's the right way to do it with Nuxt.js?

Code

I want to use search.vue in success.vue

search.vue

<template>
  <v-app>
    <div
      class="teal lighten-1 background pa-10"
    >
      <!-- <div
        v-if="responseBook === 200"
        > -->
      <alert-success />
      <v-sheet
        width="1100px"
        class="mx-auto pa-5 rounded-xl"
        color="grey lighten-5"
        min-height="500px"
      >
        <!-- 書籍検索、表示 -->
        <BookPostDialog />

        <!-- 選択されたデータの表示 -->
        <BookPostSelected />
      </v-sheet>
    </div>
  </v-app>
</template>

<script>
export default {
  computed: {
    responseBook () {
      return this.$store.state.book.responseBook.status
    }
  }
}
</script>

<style lang="scss" scoped>
  .background {
    background-image: url('~/assets/images/tree.png');
    background-repeat: space repeat;
  }
</style>

Alert/success.vue

<template>
  <v-alert type="success">
    Succeeded
  </v-alert>
</template>
2 Answers

If you want to use that kind of feature, you'll be better suited looking for something like this component: https://buefy.org/documentation/toast
Or anything like this in the jungle of CSS frameworks, pretty sure each of them have one.

Or implement it yourself, for this, you need to rely on portals.
For Vue2, this is how to do achieve it: https://portal-vue.linusb.org/guide/getting-started.html#enabling-disabling-the-portal

<portal to="destination" :disabled="true">
  <p>
    Your content
  </p>
</portal>

If you want to show success.vue component after the connection to server (getting or posting data), you can use v-if as follows:

search.vue

<template>
    <div>
        <p>search compo</p>
        <div v-if="this.$store.state.book.responseBook == 'ok'">
            data was received.
            <success />
        </div>
    </div>
</template>

<script>
export default {
    
    mounted() {
        this.$store.dispatch('getData')
    }

}
</script>

success.vue

<template>
    <div>
        succeess compo
    </div>
</template>

And then in your store/index.js file:

import Vuex from "vuex";

const createStore = () => {
    return new Vuex.Store({

state: {
            book: {
                responseBook: ""
            }
        },
        
mutations: {

            bookMutate(state, data) {
                state.book.responseBook = data;
            }
        },
actions: {       
getData(vuexContext) {
                let vue = this;
                // your request is here
                setTimeout(function() {

                    vue.$axios.$get("https://pokeapi.co/api/v2/pokemon/ditto").then((result) => {
                        console.log(result);
                        vuexContext.commit("bookMutate", "ok");
                    }).catch(err => {
                        console.log(err);
                    })

                }, 10000)

            },
}
        
        });
};

export default createStore;

I intentionally used setTimeout() in my action to see that the success component is loaded after the data was received. in actual situation it is better to use this action:

getData(vuexContext) {
                               this.$axios.$get("https://pokeapi.co/api/v2/pokemon/ditto").then((result) => {
                    console.log(result);
                    vuexContext.commit("bookMutate", "ok");
                }).catch(err => {
                    console.log(err);
                })

 },

I used axios for calling the api but you can use your own method of getting data. but after that you must commit the mutation to change the state.

Related