設計思路備忘筆記...
使用場景:各種全局彈窗..例如登錄彈窗,設置彈窗,模態通用的Confirm對話框等等....
吐槽:在C#/C++/JS/SQL間反復橫跳,這個月又輪到的JS....我也真是醉了
流程就是Vue的插件開發方式....
以vueJs得ts版本為例:
*********************************割割割*********************************
例如有組件:
*.vue:
<template>
<div v-if="bShow" class="game-setting-dialog">
<div class="container">
<h2>Hi, Singleton Component</h2>
</div>
</div>
</template>
<script lang="ts" src="./index.ts"></script>
<style scoped lang="stylus">
.game-setting-dialog
position : fixed;
top : 0;
height : 100%;
width : 100%;
z-index : 1;
text-align : center;
background : rgba( 0, 0, 0, 0.7 );
.container
background : red;
width : 50%;
top : 10vh;
min-height : 100px;
</style>
*.TS腳本:
import {Vue,Prop,Component}from 'vue-property-decorator'
import { Store } from 'vuex';
@Component({ name: 'GameSettingDialog' })
export default class GameSettingDialogComponent extends Vue
{
private _bShow:boolean = false;
mounted() {
}
get bDialog():boolean
{
return this._bShow ;
}
set bDialog(val:boolean)
{
this._bShow = false;
}
}
初始化函數 (注入單例訪問函數):
install.ts:
import Vue,{} from 'vue';
import GameSettingDialog from '@/views/Singleton/GameSettingDialog/index.vue';
import GameSettingDialogComponent from '@/views/Singleton/GameSettingDialog/index.ts';
import store from '@/store/index';
import router from '@/router/index';
declare const window:any;
let instance : any| null = null;
//構造一個新的Vue實例句柄.....
/**
* App初始化時調用...
*/
const install = function (vue:typeof Vue, opts = {})
{
//往Vue類里寫入一個`靜態函數’
Vue.prototype.$gameSettingDialog = (opt?:any)=>
{
if (!instance)
{
//如果單例未創建...
let div = document.createElement('div');
instance = new GameSettingDialog({
el : div ,
store : store , // 如果用到vuex需要包含
router : router // 同route
});
document.body.appendChild(instance.$el);
}
return instance as GameSettingDialogComponent;
};
}
export default install;
編寫一個*.d.ts,重新擴展Vue類的接口成員:
import Vue, {VNode} from 'vue'
import GameSettingDialogComponent from '@/views/Singleton/GameSettingDialog/index.ts'
declare module 'vue/types/vue'
{
interface Vue {
/** Displays a global notification message at the upper right corner of the page */
$gameSettingDialog:(opt?:any) => GameSettingDialogComponent
}
}
然后use即可,如:
//#region import 區域 import Vue from 'vue'; import App from './App.vue'; import './registerServiceWorker'; import router from './router'; import store from './store'; import GameSettingDialog from '@/views/Singleton/GameSettingDialog/install'; //#endregion Vue.config.productionTip = false; //注入全局唯一組件到整個Vue App中... Vue.use(GameSettingDialog); new Vue({ router : router , store : store , render : (h) => h(App) }).$mount('#app');
任意Vue組件中,使用this.$xxxx調用,例如:
this.$gameSettingDialog().bDialog = true; this.$gameSettingDialog().$once('custom-event', ()=> { console.log('事件綁定'); this.$gameSettingDialog().bDialog = false; });
*********************************割割割*********************************
為什么要這樣實現?
因為優雅......(戰術后仰)
而且如果是多項目通用的唯一組件,這種方式封裝成插件...基本是開箱即用....
vuex,vue-route 都是這樣子實現全局唯一的...
