IT이야기

Vue + Vuetify에서 스낵바를 글로벌 구성 요소로 사용

cyworld 2022. 5. 27. 21:21
반응형

Vue + Vuetify에서 스낵바를 글로벌 구성 요소로 사용

스낵바 컴포넌트를 작성하려고 합니다.vue를 사용하여 BaseTemplate에 구현할 수 있습니다.다른 라우터 뷰 컴포넌트를 참조하는 메인메뉴가 있는 경우

이것은 Base Component가 됩니다.

<template>
    <v-app id="inspire">
        <v-navigation-drawer
            v-model="drawer"
            app
            clipped
        >
            <v-list dense>
                <v-list-item
                    v-for="item in items"
                    :key="item.title"
                    :to="item.to"
                    :active-class="`primary white--text`"
                    link
                >
                    <v-list-item-icon>
                        <v-icon>{{ item.icon }}</v-icon>
                    </v-list-item-icon>

                    <v-list-item-content>
                        <v-list-item-title>{{ item.title }}</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
            </v-list>
        </v-navigation-drawer>

        <v-app-bar
            app
            clipped-left
            color="blue"
            dark
        >
            <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
            <v-toolbar-title>Title</v-toolbar-title>

        </v-app-bar>

        <v-main>
            <v-container fluid style="padding:30px">
                <transition name="component-fade" mode="out-in">
                <router-view></router-view>
                </transition>
            </v-container>
        </v-main>


        <template>
            <v-snackbar
                v-model="snackbar"
                :timeout="timeoutSnackBar"
            >
                {{ textSnackBar }}
            </v-snackbar>
        </template>


    </v-app>
</template>
<script>
export default {
    data: () => ({
        snackbar: false,
        timeoutSnackBar: -1,
        textSnackBar: '',
        methods:{
         SnackNotification(time,text){
this.snackbar = true
this.timeoutSnackBar: time
this.textSnackBar: text
}

          }
        drawer: null,
        items: [
            {
                title: "Home",
                icon: "mdi-view-dashboard",
                to: "/"
            },

            {
                title: "Users",
                icon: "mdi-account",
                to: "/users"
            },

           
        ]
    }),
}
</script>

de User Component에서 사용하려고 합니다.표시하다


<template>
  <v-card
    class="mx-auto"
    max-width="344"
    outlined
  >
    <v-list-item three-line>
      <v-list-item-content>
        <div class="overline mb-4">
          OVERLINE
        </div>
        <v-list-item-title class="headline mb-1">
          Headline 5
        </v-list-item-title>
        <v-list-item-subtitle>Greyhound divisely hello coldly fonwderfully</v-list-item-subtitle>
      </v-list-item-content>

      <v-list-item-avatar
        tile
        size="80"
        color="grey"
      ></v-list-item-avatar>
    </v-list-item>

    <v-card-actions>
      <v-btn
        outlined
        rounded
        text
      >
        Button
      </v-btn>
    </v-card-actions>
  </v-card>
</template>
<script>
  export default {
created() {
        this.users();
    },
    methods: {
        users: function() {
            axios
                .get('/api/users')
                .then(response =>   {
                    this.users = response.data.data
                })
                .catch(error => {
                    this.errored = true
                })
                .finally(() => {
                    if (this.firstLoad) this.firstLoad = false
                    this.loading = false;
                    this.SnackNotification(2000,'Hi, im a notification')
                })
        },
}
</script>

.js는 이거야.

import App from './components/BaseTemplate.vue'

const app = new Vue({
    el: '#app',
    render: h => h(App),
    vuetify: new Vuetify(),
    router
})



이런 식으로 할 생각은 있었지만, 이 글로벌 실장을 하는 것은 잘못되었다고 생각합니다.몇 가지 옵션을 찾았지만 NuxtJs를 사용하고 있었습니다.그것은 제가 생각하고 있던 것과는 달랐습니다.어떻게 할 수 있는지 어떤 추천도 해 주실 수 있을까요?감사합니다.

vue.app의 스낵바를 vuex와 함께 글로벌 스낵바로 추가할 수 있습니다.예제:

App.vue

<template>
  <v-app>
    ...
    <v-main>
      <router-view />
    </v-main>
    ...
    <v-snackbar v-model="snackbar.active" :timeout="-1" :color="snackbar.color">
      {{ snackbar.message}}
      <template v-slot:action="{ attrs }">
        <v-btn text v-bind="attrs" @click="snackbar.active = false">
          Close
        </v-btn>
      </template>
    </v-snackbar>
  </v-app>
</template>

<script>
import { mapState } from "vuex";

export default {
  name: "App",
  computed: {
    ...mapState(["snackbar"])
  }
};
</script>

Index.js(스토어)

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    snackbar: { active: false, color: "", message: "" }
  },
  mutations: {
    SET_SNACKBAR(state, snackbar) {
      state.snackbar = snackbar;
    }
  },
  actions: {
    snackBar({ commit }, message) {
        commit("SET_SNACKBAR", {
          active: true,
          color: "success", // You can create another actions for diferent color.
          message: message
        });
      }
  }
});

모든 라우터 뷰에서 다음과 같이 스낵바를 활성화할 수 있습니다.

예.표시하다

<template>
  ...
    <v-btn @click="showSnackBar()">
      Show SnackBar!
    </v-btn>
  ...
</template>

<script>
import { mapActions} from "vuex";

export default {
  methods: {
    ..mapActions(["snackBar"]),

    showSnackBar() {
      this.snackBar("Hi, I'm snackbar");
    }
  }
};
</script>

비슷한 문제에 대해서는 이쪽에서 답변을 봐주세요.그 경우, 그들은 글로벌한 '확인 대화'를 원했지만, 당신의 경우는 '글로벌 스낵바'입니다.

제가 그 답변에 올린 코드는 최소한의 수정으로 대화 상자 대신 스낵바에 사용할 수 있습니다.사실, 제 프로젝트에서는 보통 두 가지를 모두 추가합니다. 왜냐하면 그것들은 매우 유용하기 때문입니다.

언급URL : https://stackoverflow.com/questions/64219196/use-snackbar-as-a-global-component-in-vue-vuetify

반응형