VueJS/Nuxt

[VueJS] NuxtJS+Vuetify alert 컴포넌트 만들어보기

SongMinu 2021. 7. 13. 20:00
728x90

nuxt와 vuetify를 이용해 프로젝트를 만들면서 alert 창을 띄우다 보니 기본 alert 창이 보기가 너무 싫었다.

vuetify에서 제공하는 컴포넌트를 이용해서 만들어보면 괜찮지 않을까? 하는 생각으로 만들어봤다.

 

기왕 만들 거면 alert 컴포넌트를 만들어서 alert을 띄울 때 pages나 components 디렉터리에서 쉽게 사용할 수 있고, store에서도 쉽게 사용할 수 있게 만들고 싶었다.

그래서 생각한 건 store를 사용해보기로 했다.


store/index.js 소스

export const strict = false;
export const state = () => {
  return {
    alert : false,
    alert_data: {
      type: 'primary', //type은 success, info, warning, error 이렇게 4가지를 쓸 수 있음
      title:'',
      text: ''
    },
  }
}

export const mutations = {
  SET_ALERT(state, payload) {
    state.alert = payload.alert;
    state.alert_data.type = payload.type;
    state.alert_data.title = payload.title;
    state.alert_data.text = payload.text;
  },
}

export const getters = {
  GET_ALERT(state) {
    return state.alert;
  },
  GET_ALERT_DATA(state) {
    return state.alert_data;
  },
}

export const actions = {
  updateAlert({commit}, params) {
    commit('SET_ALERT', params);
  }
}

비동기도 아닌데 굳이 actions를 사용한 이유는 vue파일들 안에서는 상관없는데

store에 있는 다른 js파일에서 commit으로 index.js에 있는 mutation을 할 수가 없다. (actions는 접근할 수 있는 방법이 있던데 내가 못 찾은걸 수도 있음...)

그리고 state안에 있는 alert은 v-alert을 열게 해 주는 거라 따로 빼놨고, alert_data는 v-alert의 디자인과 보여줄 문구를 담아놓은 거라 이 둘을 한 번에 처리하려면 actions에서 처리하는 게 더 편했다...

 

alert.vue 소스

<template>
  <v-overlay
    :value="is_show"
    z-index="100005"
    >
    <v-alert 
      :type="alert_data.type"
      colored-border
      border="right"
      >
      <v-row>
        <v-col cols="12">
          {{ alert_data.title}}
        </v-col>
        <v-col cols="12" v-html="change(alert_data.text)">
        </v-col>
      </v-row>
      <v-row>
       <v-col cols="12" align="end">
          <v-btn
            outlined
            @click="close"
            >
            확인
          </v-btn>
        </v-col>
      </v-row>
    </v-alert>
  </v-overlay>
</template>

<script>
export default {
  //type은 success, info, warning, error 이렇게 4가지를 쓸 수 있음
  computed: {
    is_show() {
      return this.$store.getters['GET_ALERT'];
    },
    alert_data() {
      return this.$store.getters['GET_ALERT_DATA'];
    }
  },
  methods: {
    change(v) {
      return String(v).replace(/(?:\r\n|\r|\n)/g,"</br>");
    },
    close() {
      this.$store.dispatch('updateAlert', {alert: false, type: 'error', text: ''});
    }
  }
}
</script>

<style>

</style>

computed를 이용해 store안에 데이터를 사용한다.

위 index.js에서 state안에 있는 alert 값이 true가 되면 열리고, 닫기 버튼을 누르면 false로 바꿔서 끈다.

그리고 \n과 같은 개행 처리는 따로 해줘야 한다. (methods안에 change 함수, v-html을 사용)

 

v-alert에서 제공하는 type 속성이 4종류가 있는데 success, info, warning, error에 따라 디자인을 바꿔서 출력해준다.

 

그리고 이제 layout 디렉터리 쪽에 default.vue를 열어서 만든 컴포넌트를 넣어준다.

이제 이렇게 넣어두면 어느 화면, 어느 소스 상에서 store/index.js 쪽으로 소스만 날리면 alert 컴포넌트가 열린다.

 

사용 예제와 화면

저 필터 초기화 버튼을 눌렀을 때 소스

alert 컴포넌트를 띄우기 위해 alert: true 값을 주고,

v-alert의 type으로 info, 그리고 타이틀(title)과 내용(text)을 주었다.

결과

이런 식으로 화면에 컴포넌트가 출력된다.

 

type이 error 일 때

vue 파일 안에서는 

this.$store.dispatch('updateAlert', {

          alerttrue

          type'error'

          title'검색조건 저장',

          text'저장할 검색조건이 없습니다.'

        });

이런 식으로 this.$store.dispatch('updateAlert', { ~~~ 를 사용하면 된다.

 

그리고 store안에 다른 js 파일에서 사용하는 방법은 이렇다.

store/saveFilter.js에 작성한 소스

axios로 express 쪽으로 api 요청을 날리고 elasticsearch 결과를 반환하는 부분인데, 

에러가 발생하면 alert 컴포넌트를 실행하도록 했다.

dispatch를 사용하고 마지막에 {root: true}를 넣으면 store/index.js 안의 actions로 접근이 가능하다.

 

이렇게 하면 vue파일이나 js에서 사용할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

반응형