이번게시글에서는 vuex-pathify를 사용하여 dialog 창 만드는 방법을 정리합니다.
소스코드는 https://github.com/jaeho310/vue-study (vuex-dialog 브랜치)에서 확인 가능합니다.
이전 게시글에서 내용이 추가된 예제입니다.
결과화면
1. CustomDialog.vue 파일 생성
<template>
<v-card>
<v-card-title class="text-h5" v-if="question">
confirm
</v-card-title>
<v-card-title class="text-h5" v-if="!question">
alert
</v-card-title>
<v-card-text v-text="text"></v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
v-if="!question"
color="green darken-1"
text
@click="$emit('submit')"
>
ok
</v-btn>
<v-btn
v-if="question"
color="green darken-1"
text
@click="$emit('submit')"
>
yes
</v-btn>
<v-btn
v-if="question"
color="green darken-1"
text
@click="$emit('hide')"
>
no
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
name: 'CustomDialog',
props: ["text", "question"],
}
</script>
<style>
</style>
입맛에 맞게 꾸며줍니다.
저는 yes or no, confirm으로 팝업창을 구성하였습니다.
2. utils/dialog.js 파일 생성
import store from '../store'
let __dialog = {
dialogInfo: {
text: "Dialog 메시지를 입력하세요",
question: false,
hideDialog: null,
submitDialog: null,
},
showDialog: false,
dialogCallback: function(){alert("dialog 콜백을 확인해주세요")},
makeDialog: function(payload) {
// alert창인지, yes or no question 인지
if (payload.question != null) {
this.dialogInfo.question = payload.question
} else if (payload.question == null) {
this.dialogInfo.question = false
}
// message 확인
if (payload.text) {
this.dialogInfo.text = payload.text
} else {
this.dialogInfo.text = "Dialog 메시지를 입력하세요"
}
// callback이 있는경우
if (payload.callback != null) {
this.dialogCallback = payload.callback
} else {
this.dialogCallback = null
}
// no를 누른경우
this.dialogInfo.hideDialog = () => {
this.showDialog = false
}
// yes를 누른경우 doalog창을 닫고 callback을 실행
this.dialogInfo.submitDialog = () => {
this.showDialog = false
if (this.dialogCallback) {
this.dialogCallback()
}
}
if (payload.delay != null) {
setTimeout(()=>{this.showDialog=true}, payload.delay)
} else {
this.showDialog = true
}
store.set('dialog/dialogManager', __dialog)
}
}
export default __dialog
dialog를 위한 js 파일을 하나 만들어줍니다.
payload에는 text, question, callback, delay를 보낼 수 있게 해놨습니다.
해당 파일을 import를 한후 makeDialog메서드를 사용하게되면 vuex에 state인 showDialog가 ture로 변경하고
dialog창이 등장합니다.
3. store/modules/dialog.js 파일 생성
// Pathify
import { make } from 'vuex-pathify'
const state = {
dialogManager: {
dialogInfo: {
text: "Dialog 메시지를 입력하세요",
question: false,
hideDialog: null,
submitDialog: null,
},
showDialog: false,
dialogCallback: ()=>{alert("dialog 콜백을 확인해주세요")}
}
}
const mutations = make.mutations(state)
const actions = {}
const getters = {}
export default {
namespaced: true,
state,
mutations,
actions,
getters,
}
mutation은 vuex-pathify의 make.mutations로 대체해버립니다.
4. store/modules/index.js 파일 생성
export { default as app } from './app'
export { default as dialog } from './dialog'
모듈별로 나눠 pathify를 연동하여 사용합니다.
5. layout/View.vue 파일 수정
<template>
<v-main>
<router-view />
<v-dialog
max-width="400"
v-model="dialogManager.showDialog"
>
<CustomDialog
:text="dialogManager.dialogInfo.text"
:question="dialogManager.dialogInfo.question"
@hide="dialogManager.dialogInfo.hideDialog"
@submit="dialogManager.dialogInfo.submitDialog"
/>
</v-dialog>
</v-main>
</template>
<script>
import CustomDialog from '@/components/CustomDialog'
import { sync } from 'vuex-pathify'
export default {
components: {
CustomDialog
},
computed: {
...sync('dialog',[
'dialogManager'
])
},
}
</script>
<style>
</style>
dialog창을 사용하는곳마다 다 CustomDialog를 import 하고 props와 emit을 세팅할 수는 없습니다.
적당히 부모가 되는 컴포넌트에 CustomDialog를 넣어줍니다.
vuex와 pathify로 연결된 showDialog가 true가 되는순간 팝업창이 뜹니다.
이제 사용할 준비는 끝났습니다.
사용법입니다.
6. /views/Test.vue
<template>
<v-card
class="mx-auto mt-15"
width="400"
>
<v-card-title>
<span class="text-h5">메뉴 추가</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-text-field
v-model="inputValue"
label="추가할 메뉴명을 입력해주세요"
></v-text-field>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="save"
>
저장
</v-btn>
<v-btn
color="blue darken-1"
text
@click="toHome"
>
홈으로
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
import dialog from '../utils/dialog.js'
import { sync } from 'vuex-pathify'
export default {
name: "Test",
data() {
return {
inputValue: '',
}
},
methods: {
save() {
if (!this.inputValue) {
dialog.makeDialog({text: "메뉴명을 입력해주세요"})
return
}
this.items.push({
title: this.inputValue,
to : '/',
icon: 'mdi-account'
})
dialog.makeDialog({text: "메뉴가 추가되었습니다."})
this.inputValue = ''
},
toHome() {
dialog.makeDialog({text: "홈으로 이동하시겠습니까?", question: true, callback: this.routerHome})
},
routerHome() {
this.$router.push("/")
dialog.makeDialog({text: "홈으로 이동되었습니다.", delay: 100})
}
},
computed: {
items: sync('app/items'),
}
}
</script>
util에 만들어놨던 dialog.js를 import해서 사용합니다.
vuex를 사용하여 상위컴포넌트에서 dialog창을 띄워놨으므로
router.push를 사용하더라도 팝업창을 계속 사용 가능합니다.
'vue' 카테고리의 다른 글
[vue] 스프링(spring)에서 vue router 사용법 (1) | 2021.11.02 |
---|---|
[vue] vue와 spring 연동하는법(vue 배포방법) (0) | 2021.11.02 |
[vue] vuex pathify를 사용한 메뉴바 구성하기(vuex pathify 사용법) (0) | 2021.10.27 |
[vue] vue 프로젝트에 jest 연동, 사용하기 (0) | 2021.10.26 |
[vue] vue tutorial 뷰 튜토리얼 -6- (vuetify 테이블 input박스) (0) | 2021.09.21 |
댓글