반응형
페이지별 Vue Instance 생성하여 작업해야하는 환경에서 Store를 사용할수도 없고
메인 페이지가 없다보니 공통 화면 처리하는 부분이 애매한 부분이 있었다
그렇다고 각 페이지별로 매번 간단한 공통 component를 선언해서 사용하기는 싫었다
그래서 component를 동적으로 주입 할수있는 방안을 검토하였고 아래와같이 구현하였다
아래소스는 custom 공통 alert 창을 각 페이지에서 메소드 호출로만 가능하게 하기 위한 plugin 이다.
주 소스 구조는 각 vue 페이지에서 alert 창 요청시
ex) this.$.alert('TEST');
해당 common-alert를 동적으로 주입시킨후 해당 alert component를 호출하는
구조이다.
아래와 같은 plugin을 제공해줌으로서 각 페이지 개발자들에게 this.$alert 사용법만을 가이드하면 되게 되었다
추후 confirm 까지 확장 가능할듯하다.
/**
* Created by kic(ddori) on 2019. 12. 17..
*/
const alertPlugin = {
install (Vue, options = {}) {
if (this.installed) {
return;
}
this.installed = true;
const createDivInBody = () => {
const div = document.createElement('div');
//const mainApp = document.getElementById("app");
//mainApp.appendChild(div);
document.body.appendChild(div);
return div
}
/* 동적 component Inject
*/
const componentInject = (component) =>{
const container = createDivInBody();
Vue.prototype.$alertContainer = new Vue({
parent: Plugin.rootInstance,
render: h => h(component)
}).$mount(container)
}
/* alert component 객체를 얻는다.
*/
const getAlertComponent = (root)=> {
if (Vue.prototype.$alertContainer == null){
componentInject('common-alert');
}
return root._dynamicContainer;
}
/* 공통 alert 메소드
*/
Vue.prototype.$alert = (msg,width,height) =>{
const root = Plugin.rootInstance;
const alertComponent = getAlertComponent(root);
if (!alertComponent) return;
return alertComponent.alert(false,"알 림",msg,width,height);
}
Vue.prototype.$confirm = (msg,width,height) =>{
const root = Plugin.rootInstance;
const alertComponent = getAlertComponent(root);
if (!alertComponent) return;
return alertComponent.alert(true,"알 림" , msg,width,height);
}
Vue.mixin({
beforeMount () {
if (Plugin.rootInstance === undefined) {
Plugin.rootInstance = this.$root;
}
}
})
Vue.prototype.$alertContainer = null;
}
}
(Vue=> {
Vue.component('commonAlert', {
template: `<modal ref="commonAlert" v-show="isPop" @click="onClose" :title="title" :isTitleBar=false :bodyStyle="bodyStyle" @close="onClose" >
<p class="bold pt-30 pb-20 ta-c">{{title}}</p>
<div class="container100 ta-c fs-13">
{{msg}}
</div>
<div class="container100 pt-40 pb-30 ta-c cf">
<button v-show="isConfirm" class="admin-bt wd-90 mr-05" @click="onClickCancel">취소</button>
<button class="admin-bd-bt wd-80" @click="onClickOk">확인</button>
</div>
</modal>`,
data() {
return {
isPop:false,
isConfirm:false,
msg: '',
title:'',
bodyStyle:{},
resolve: null,
reject: null,
}
},
created(){
this.$root._dynamicContainer = this;
//Vue.prototype.$alertContainer = this;
},
computed: {
},
methods: {
onClose(){
},
onClickCancel(){
this.isPop = false;
this.reject(false);
},
onClickOk(){
this.resolve(true);
this.isPop = false;
},
alert(isConfirm,title,msg,width,height){
let bodyStyle = {};
if (width !== undefined){
bodyStyle.width = width+'px';
}else{
bodyStyle.width = '350px';
}
if (height !== undefined){
bodyStyle.height = height+'px';
}
this.isConfirm = isConfirm;
this.title = title;
this.bodyStyle = bodyStyle;
this.isPop = true;
this.msg = msg;
return new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}
},
watch: {
isPop(value){
if (value){
}
}
}
});
})(Vue);
반응형
'FrontEnd > vue.js' 카테고리의 다른 글
Vue Transition (0) | 2020.01.19 |
---|---|
composition api Test Code (0) | 2019.12.29 |
Recusive Navigation Component 개발기 (0) | 2019.10.17 |
개발 환경에 따라 다른 환경 변수 값 적용하기 (0) | 2019.10.10 |
lesscss 적용 처리 (0) | 2019.09.26 |