diff --git a/src/core/system/ui/container.tsx b/src/core/system/ui/container.tsx
index 41cf988..dafcd89 100644
--- a/src/core/system/ui/container.tsx
+++ b/src/core/system/ui/container.tsx
@@ -1,9 +1,9 @@
-import { computed, defineComponent, VNode } from 'vue';
-import { IUIMountable, UIComponent } from './shared';
+import { defineComponent, VNode } from 'vue';
+import { IUIMountable } from './shared';
 import { SetupComponentOptions } from '@/module';
 
 export interface UIContainerProps {
-    controller: IUIMountable<UIComponent>;
+    controller: IUIMountable;
 }
 
 const containerConfig = {
@@ -13,18 +13,29 @@ const containerConfig = {
 export const UIContainer = defineComponent<UIContainerProps>(props => {
     const data = props.controller;
     const back = data.backIns;
-    const show = computed(() => data.stack.filter(v => !v.hidden));
     return (): VNode[] => {
         const elements: VNode[] = [];
         const b = back.value;
         if (b && data.showBack.value && !b.hidden) {
             elements.push(
-                <b.ui.component {...b.vBind} key={b.key}></b.ui.component>
+                <b.ui.component
+                    {...b.vBind}
+                    controller={data}
+                    instance={b}
+                    key={b.key}
+                    hidden={b.hidden}
+                ></b.ui.component>
             );
         }
         return elements.concat(
-            show.value.map(v => (
-                <v.ui.component {...v.vBind} key={v.key}></v.ui.component>
+            data.stack.map(v => (
+                <v.ui.component
+                    {...v.vBind}
+                    key={v.key}
+                    controller={data}
+                    instance={v}
+                    hidden={v.hidden}
+                ></v.ui.component>
             ))
         );
     };
diff --git a/src/core/system/ui/controller.ts b/src/core/system/ui/controller.ts
index e11f048..517a494 100644
--- a/src/core/system/ui/controller.ts
+++ b/src/core/system/ui/controller.ts
@@ -5,9 +5,9 @@ import {
     IKeepController,
     IUIInstance,
     IUIMountable,
-    UIComponent
+    UIComponent,
+    UIProps
 } from './shared';
-import { Props } from '@/core/render';
 import { UIInstance } from './instance';
 import {
     computed,
@@ -35,13 +35,13 @@ export const enum UIMode {
     Custom
 }
 
-export interface IUICustomConfig<C extends UIComponent> {
+export interface IUICustomConfig {
     /**
      * 打开一个新的 UI
      * @param ins 要打开的 UI 实例
      * @param stack 当前的 UI 栈,还未将 UI 实例加入栈中
      */
-    open(ins: IUIInstance<C>, stack: IUIInstance<C>[]): void;
+    open(ins: IUIInstance, stack: IUIInstance[]): void;
 
     /**
      * 关闭一个 UI
@@ -49,7 +49,7 @@ export interface IUICustomConfig<C extends UIComponent> {
      * @param stack 当前的 UI 栈,还未将 UI 实例移除
      * @param index 这个 UI 实例在 UI 栈中的索引
      */
-    close(ins: IUIInstance<C>, stack: IUIInstance<C>[], index: number): void;
+    close(ins: IUIInstance, stack: IUIInstance[], index: number): void;
 
     /**
      * 隐藏一个 UI
@@ -57,7 +57,7 @@ export interface IUICustomConfig<C extends UIComponent> {
      * @param stack 当前的 UI 栈
      * @param index 这个 UI 实例在 UI 栈中的索引
      */
-    hide(ins: IUIInstance<C>, stack: IUIInstance<C>[], index: number): void;
+    hide(ins: IUIInstance, stack: IUIInstance[], index: number): void;
 
     /**
      * 显示一个 UI
@@ -65,32 +65,32 @@ export interface IUICustomConfig<C extends UIComponent> {
      * @param stack 当前的 UI 栈
      * @param index 这个 UI 实例在 UI 栈中的索引
      */
-    show(ins: IUIInstance<C>, stack: IUIInstance<C>[], index: number): void;
+    show(ins: IUIInstance, stack: IUIInstance[], index: number): void;
 
     /**
      * 更新所有 UI 的显示,一般会在显示模式更改时调用
      * @param stack 当前的 UI 栈
      */
-    update(stack: IUIInstance<C>[]): void;
+    update(stack: IUIInstance[]): void;
 }
 
 interface UIControllerEvent {}
 
-export class UIController<C extends UIComponent = UIComponent>
+export class UIController
     extends EventEmitter<UIControllerEvent>
-    implements IUIMountable<C>
+    implements IUIMountable
 {
     static controllers: Map<string, UIController> = new Map();
 
     /** 当前的 ui 栈 */
-    readonly stack: IUIInstance<C>[] = reactive([]);
+    readonly stack: IUIInstance[] = reactive([]);
     /** UI 显示方式 */
     mode: UIMode = UIMode.LastOnlyStack;
     /** 这个 UI 实例的背景,当这个 UI 处于显示模式时,会显示背景 */
-    background?: IGameUI<C>;
+    background?: IGameUI;
 
     /** 背景 UI 实例 */
-    readonly backIns: ShallowRef<IUIInstance<C> | null> = shallowRef(null);
+    readonly backIns: ShallowRef<IUIInstance | null> = shallowRef(null);
     /** 当前是否显示背景 UI */
     readonly showBack: ComputedRef<boolean> = computed(
         () => this.userShowBack.value && this.sysShowBack.value
@@ -102,7 +102,7 @@ export class UIController<C extends UIComponent = UIComponent>
     }
 
     /** 自定义显示模式下的配置信息 */
-    private config?: IUICustomConfig<C>;
+    private config?: IUICustomConfig;
     /** 是否维持背景 UI */
     private keepBack: boolean = false;
     /** 用户是否显示背景 UI */
@@ -134,7 +134,7 @@ export class UIController<C extends UIComponent = UIComponent>
      * 设置背景 UI
      * @param back 这个 UI 控制器的背景 UI
      */
-    setBackground(back: IGameUI<C>) {
+    setBackground(back: IGameUI) {
         this.background = back;
     }
 
@@ -171,13 +171,12 @@ export class UIController<C extends UIComponent = UIComponent>
         };
     }
 
-    /**
-     * 打开一个 ui
-     * @param ui 要打开的 ui
-     * @param vBind 传递给这个 ui 的响应式数据
-     */
-    open(ui: IGameUI<C>, vBind: Props<C>) {
-        const ins = new UIInstance(ui, vBind);
+    open<T extends UIComponent>(
+        ui: IGameUI<T>,
+        vBind: UIProps<T>,
+        alwaysShow: boolean = false
+    ): IUIInstance<T> {
+        const ins = new UIInstance(ui, vBind, alwaysShow);
         switch (this.mode) {
             case UIMode.LastOnly:
             case UIMode.LastOnlyStack:
@@ -196,11 +195,7 @@ export class UIController<C extends UIComponent = UIComponent>
         return ins;
     }
 
-    /**
-     * 关闭一个 ui
-     * @param ui 要关闭的 ui 实例
-     */
-    close(ui: UIInstance<C>) {
+    close(ui: IUIInstance) {
         const index = this.stack.indexOf(ui);
         if (index === -1) return;
         switch (this.mode) {
@@ -239,7 +234,16 @@ export class UIController<C extends UIComponent = UIComponent>
         this.keepBack = false;
     }
 
-    hide(ins: IUIInstance<C>): void {
+    closeAll(ui?: IGameUI): void {
+        if (!ui) {
+            this.stack.splice(0);
+        } else {
+            const list = this.stack.filter(v => v.ui === ui);
+            list.forEach(v => this.close(v));
+        }
+    }
+
+    hide(ins: IUIInstance): void {
         const index = this.stack.indexOf(ins);
         if (index === -1) return;
         if (this.mode === UIMode.Custom) {
@@ -249,7 +253,7 @@ export class UIController<C extends UIComponent = UIComponent>
         }
     }
 
-    show(ins: IUIInstance<C>): void {
+    show(ins: IUIInstance): void {
         const index = this.stack.indexOf(ins);
         if (index === -1) return;
         if (this.mode === UIMode.Custom) {
@@ -290,7 +294,7 @@ export class UIController<C extends UIComponent = UIComponent>
      * 使用自定义的显示模式
      * @param config 自定义显示模式的配置
      */
-    showCustom(config: IUICustomConfig<C>) {
+    showCustom(config: IUICustomConfig) {
         this.mode = UIMode.Custom;
         this.config = config;
         config.update(this.stack);
@@ -300,10 +304,8 @@ export class UIController<C extends UIComponent = UIComponent>
      * 获取一个元素上的 ui 控制器
      * @param id 要获取的 ui 控制器的唯一标识符
      */
-    static getController<T extends UIComponent>(
-        id: string
-    ): UIController<T> | null {
-        const res = this.controllers.get(id) as UIController<T>;
+    static getController(id: string): UIController | null {
+        const res = this.controllers.get(id);
         return res ?? null;
     }
 }
diff --git a/src/core/system/ui/instance.ts b/src/core/system/ui/instance.ts
index ddd2468..530d517 100644
--- a/src/core/system/ui/instance.ts
+++ b/src/core/system/ui/instance.ts
@@ -1,5 +1,5 @@
 import { Props } from '@/core/render';
-import { IGameUI, IUIInstance, UIComponent } from './shared';
+import { IGameUI, IUIInstance, UIComponent, UIProps } from './shared';
 import EventEmitter from 'eventemitter3';
 import { markRaw, mergeProps } from 'vue';
 
@@ -21,7 +21,8 @@ export class UIInstance<C extends UIComponent>
 
     constructor(
         ui: IGameUI<C>,
-        public vBind: Props<C>
+        public vBind: UIProps<C>,
+        public readonly alwaysShow: boolean = false
     ) {
         super();
         this.ui = markRaw(ui);
@@ -30,13 +31,13 @@ export class UIInstance<C extends UIComponent>
     /**
      * 设置这个 UI 实例的响应式数据的值
      * @param data 要设置的值
-     * @param merge 是将传入的值与原先的值合并(true),还是将当前值覆盖掉原先的值(false)
+     * @param merge 是将传入的值与原先的值合并(true),还是将当前值覆盖掉原先的值(false),默认合并
      */
-    setVBind(data: Props<C>, merge: boolean = true) {
+    setVBind(data: Partial<Props<C>>, merge: boolean = true) {
         if (merge) {
-            this.vBind = mergeProps(this.vBind, data) as Props<C>;
+            this.vBind = mergeProps(this.vBind, data) as UIProps<C>;
         } else {
-            this.vBind = data;
+            this.vBind = data as UIProps<C>;
         }
     }
 
diff --git a/src/core/system/ui/shared.ts b/src/core/system/ui/shared.ts
index d91ec67..639ea24 100644
--- a/src/core/system/ui/shared.ts
+++ b/src/core/system/ui/shared.ts
@@ -3,7 +3,17 @@ import { DefineComponent, DefineSetupFnComponent, Ref, ShallowRef } from 'vue';
 
 export type UIComponent = DefineSetupFnComponent<any> | DefineComponent;
 
-export interface IGameUI<C extends UIComponent> {
+export interface UIComponentProps<T extends UIComponent = UIComponent> {
+    controller: IUIMountable;
+    instance: IUIInstance<T>;
+}
+
+export type UIProps<C extends UIComponent = UIComponent> = Omit<
+    Props<C>,
+    keyof UIComponentProps<C>
+>;
+
+export interface IGameUI<C extends UIComponent = UIComponent> {
     /** 这个 UI 的名称 */
     readonly name: string;
     /** 这个 UI 的组件 */
@@ -22,11 +32,11 @@ export interface IKeepController {
     unload(): void;
 }
 
-export interface IUIMountable<C extends UIComponent> {
+export interface IUIMountable {
     /** 当前的 UI 栈 */
-    readonly stack: IUIInstance<C>[];
+    readonly stack: IUIInstance<UIComponent>[];
     /** 当前的背景 UI */
-    readonly backIns: ShallowRef<IUIInstance<C> | null>;
+    readonly backIns: ShallowRef<IUIInstance<UIComponent> | null>;
     /** 当前是否显示背景 UI */
     readonly showBack: Ref<boolean>;
 
@@ -34,13 +44,46 @@ export interface IUIMountable<C extends UIComponent> {
      * 隐藏一个 UI
      * @param ins 要隐藏的 UI 实例
      */
-    hide(ins: IUIInstance<C>): void;
+    hide(ins: IUIInstance<UIComponent>): void;
 
     /**
      * 显示一个 UI
      * @param ins 要显示的 UI 实例
      */
-    show(ins: IUIInstance<C>): void;
+    show(ins: IUIInstance<UIComponent>): void;
+
+    /**
+     * 隐藏背景 UI
+     */
+    hideBackground(): void;
+
+    /**
+     * 显示背景 UI
+     */
+    showBackground(): void;
+
+    /**
+     * 打开一个 ui
+     * @param ui 要打开的 ui
+     * @param vBind 传递给这个 ui 的响应式数据
+     * @param alwaysShow 这个 ui 是否保持开启,对于需要叠加显示的 ui 非常有用
+     */
+    open<T extends UIComponent>(
+        ui: IGameUI<T>,
+        vBind: UIProps<T>,
+        alwaysShow?: boolean
+    ): IUIInstance<T>;
+
+    /**
+     * 关闭一个 ui
+     * @param ui 要关闭的 ui 实例
+     */
+    close(ui: IUIInstance<UIComponent>): void;
+
+    /**
+     * 关闭所有或指定类型的所有 UI
+     */
+    closeAll(ui?: IGameUI<UIComponent>): void;
 
     /**
      * 维持背景,直到下次所有 UI 都被关闭
@@ -48,15 +91,17 @@ export interface IUIMountable<C extends UIComponent> {
     keep(): IKeepController;
 }
 
-export interface IUIInstance<C extends UIComponent> {
+export interface IUIInstance<C extends UIComponent = UIComponent> {
     /** 这个 ui 实例的唯一 key,用于 vue */
     readonly key: number;
     /** 这个 ui 实例的 ui 信息 */
     readonly ui: IGameUI<C>;
     /** 传递给这个 ui 实例的响应式数据 */
-    readonly vBind: Props<C>;
+    readonly vBind: UIProps<C>;
     /** 当前元素是否被隐藏 */
     readonly hidden: boolean;
+    /** 是否永远保持开启 */
+    readonly alwaysShow: boolean;
 
     /**
      * 隐藏这个 ui