2022-01-08
Vue.js로 개발하면서 나중에 쉽게 쓸 수 있도록
공통으로 만들어놓은 컴포넌트가 몇 개 있었는데,
그걸 이제 여기다가 정리해보려 한다.
Alert & Confirm (Vuex와 같이 쓰는 것)
<!-- Alert.vue -->
<template>
<div id="alert">
<div>
<div>
<div>
<div>
<div>
<div v-html="title.replaceAll('\\n', '<br />')"></div>
</div>
<div>
<input type="button" :value="okButtonText" @click="onOk" />
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from "vue";
import { mapActions } from "vuex";
export default {
name: "Alert",
props: {
title: String,
okButtonText: String,
},
methods: {
...mapActions({
setInvisible: "SET_ALERT_INVISIBLE",
setVisible: "SET_ALERT_VISIBLE"
}),
onOk() {
this.$emit("ok");
this.setInvisible();
}
},
mounted: {
Vue.prototype.$alert = (title, onOk = () => null) => this.setVisible({ show: true, title, okButtonText: "확인", onOk });
}
}
</script>
<style lang="scss">
#alert {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.62);
z-index: 999;
display: inline;
> div {
width: 100%;
height: 100%;
> div {
display: table;
width: 100%;
height: 100%;
> div {
display: table-cell;
vertical-align: middle;
text-align: center;
> div {
display: inline-block;
z-index: 9999;
animation-duration: 0.6s;
/* 스타일 속성 추가 */
> div {
&:first-child {
/* 스타일 속성 추가 */
}
&:last-child {
/* 스타일 속성 추가 */
input[type=button] {
cursor: pointer;
outline: none;
/* 스타일 속성 추가 */
}
}
}
}
}
}
}
}
@media screen and (max-width: 1200px) {
#alert {
position: fixed;
}
}
</style>
<!-- Confirm.vue -->
<template>
<div id="confirm">
<div>
<div>
<div>
<div>
<div>
<div v-html="title.replaceAll('\\n', '<br />')"></div>
</div>
<div>
<input type="button" :value="okButtonText" @click="onOk" />
<input type="button" :value="cancelButtonText" @click="onCancel" />
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from "vue";
import { mapActions } from "vuex";
export default {
name: "Confirm",
props: {
title: String,
okButtonText: String,
cancelButtonText: String
},
methods: {
...mapActions({
setInvisible: "SET_CONFIRM_INVISIBLE",
setVisible: "SET_CONFIRM_VISIBLE"
}),
onOk() {
this.$emit("ok");
this.setInvisible();
},
onCancel() {
this.$emit("cancel");
this.setInvisible();
}
},
mounted: {
Vue.prototype.$confirm = (title, onOk, onCancel = () => null) => this.setVisible({ show: true, title, okButtonText: "확인", cancelButtonText: "취소", onOk, onCancel });
}
}
</script>
<style lang="scss">
#confirm {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.62);
z-index: 999;
display: inline;
> div {
width: 100%;
height: 100%;
> div {
display: table;
width: 100%;
height: 100%;
> div {
display: table-cell;
vertical-align: middle;
text-align: center;
> div {
display: inline-block;
z-index: 9999;
animation-duration: 0.6s;
/* 스타일 속성 추가 */
> div {
&:first-child {
/* 스타일 속성 추가 */
}
&:last-child {
/* 스타일 속성 추가 */
input[type=button] {
cursor: pointer;
outline: none;
/* 스타일 속성 추가 */
}
}
}
}
}
}
}
}
@media screen and (max-width: 1200px) {
#alert {
position: fixed;
}
}
</style>
<!-- Loading.vue -->
<template>
<div id="loading" v-show="$store.state.loading"></div>
</template>
<script>export default { name: "Loading" }</script>
<style>
#loading {
position: fixed;
top: 0;
left: 0;
z-index: 1000;
width: 100%;
height: 100%;
background-color: transparent;
background-image: url('로딩 뱅글뱅글 이미지 또는 GIF');
background-repeat: no-repeat;
background-position: center center;
background-size: /* 로딩 이미지 사이즈 */;
}
</style>
// common.reducer.js
export default {
state: {
alert: Object.freeze({
show: false,
title: "",
okButtonText: "",
onOk: () => null
}),
confirm: Object.freeze({
show: false,
title: "",
okButtonText: "",
cancelButtonText: "",
onOk: () => null,
onCancel: () => null
}),
loading: false
},
mutations: {
SET_ALERT_INVISIBLE: state => state.alert = Object.freeze({
show: false,
title: "",
okButtonText: "",
onOk: () => null
}),
SET_ALERT_VISIBLE: (state, alert) => state.alert = Object.freeze({ ...alert }),
SET_CONFIRM_INVISIBLE: state => state.confirm = Object.freeze({
show: false,
title: "",
okButtonText: "",
cancelButtonText: "",
onOk: () => null,
onCancel: () => null
}),
SET_CONFIRM_VISIBLE: (state, confirm) => state.confirm = Object.freeze({ ...confirm }),
SET_LOADING_INVISIBLE: state => state.loading = false,
SET_LOADING_VISIBLE: state => state.loading = true
},
actions: {
SET_ALERT_INVISIBLE: context => context.commit("SET_ALERT_INVISIBLE"),
SET_ALERT_VISIBLE: (context, alert) => context.commit("SET_ALERT_VISIBLE", alert),
SET_CONFIRM_INVISIBLE: context => context.commit("SET_CONFIRM_INVISIBLE"),
SET_CONFIRM_VISIBLE: (context, confirm) => context.commit("SET_CONFIRM_VISIBLE", confirm),
SET_LOADING_INVISIBLE: context => context.commit("SET_LOADING_INVISIBLE"),
SET_LOADING_VISIBLE: context => context.commit("SET_LOADING_VISIBLE")
}
}
Pagination (Props로만 쓸 수 있는 것)