Skip to content

Commit

Permalink
fix: 自定义class类名
Browse files Browse the repository at this point in the history
  • Loading branch information
BBBboys committed Dec 14, 2024
1 parent 51aecd8 commit a72cd95
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 28 deletions.
66 changes: 39 additions & 27 deletions src/components/Core.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { Component, ComponentInternalInstance, InjectionKey, Ref } from "vue";
import { defineComponent, inject, nextTick, render, provide } from "vue";
import { ConsumerEventBus, getMaxZIndex, PromiseWithResolvers, type IOnConfig } from "./utils";
import { defineComponent, inject, nextTick, provide, render } from "vue";
import { EVENT_NAME } from "./type";
import { ConsumerEventBus, PromiseWithResolvers, type IOnConfig } from "./utils";

export interface ICommandComponentArrtsProviderConfig {
provideProps?: Record<string, any>;
appendTo?: string | HTMLElement;
customClassName?: string;
}

export type ICommandDialogProviderConfig = ICommandComponentArrtsProviderConfig & {
Expand All @@ -27,7 +28,7 @@ export interface IConsumer {
/** 弹窗销毁,但是不继续推进promise的状态改变 */
destroy: (external?: boolean) => void;
/** 弹窗是否可见响应式变量,虽然已经提供了hide以及show方法不需要通过该属性来控制弹窗的显示与隐藏,但是为了方便一些特殊场景,还是提供了该属性,比如你需要watch这个属性来做一些事情 */
visible: Ref<boolean>,
visible: Ref<boolean>;
/** 隐藏 */
hide: () => void;
/** 显示 */
Expand All @@ -43,11 +44,11 @@ export interface IConsumer {
/** 一般建议赋值为UI库的弹窗实例实例Ref */
componentRef?: Ref<any> | undefined;
/** 弹窗挂载的html元素 */
container: HTMLDivElement
container: HTMLDivElement;
/** 弹窗嵌套堆栈 */
stack: IConsumer[],
stack: IConsumer[];
/** 当前在弹窗嵌套堆栈中的索引 */
stackIndex: number
stackIndex: number;
}

// Consumer inject key
Expand All @@ -58,20 +59,20 @@ export const CommandDialogStackInjectKey: InjectionKey<IConsumer[]> = Symbol("Co
const eventBus = new ConsumerEventBus();

const getProvidesChain = (ins: ComponentInternalInstance): any => ({
...ins.parent ? getProvidesChain(ins.parent) : {},
...(ins as any).provides
...(ins.parent ? getProvidesChain(ins.parent) : {}),
...(ins as any).provides,
});

export function CommandProvider(parentInstance: ComponentInternalInstance | null, uiComponentVnode: Component, config: ICommandDialogProviderConfig): IConsumer {
const appendToElement = (typeof config.appendTo === "string" ? document.querySelector(config.appendTo) : config.appendTo) || document.body;
const container = document.createElement("div");
container.className = "command-commponent-container"
container.className = config.customClassName || "command-commponent-container";

appendToElement.appendChild(container);
const MaxZIndex = getMaxZIndex(container);
// 设置节点层级,尽量让其显示出来
container.style.position = 'relative';
container.style.zIndex = String(Math.max(MaxZIndex + 1, 9999));
// const MaxZIndex = getMaxZIndex(container);
// // 设置节点层级,尽量让其显示出来
// container.style.position = 'relative';
// container.style.zIndex = String(Math.max(MaxZIndex + 1, 9999));

const hide = () => {
config.visible.value = false;
Expand All @@ -84,7 +85,7 @@ export function CommandProvider(parentInstance: ComponentInternalInstance | null
render(null, container);
container.remove();
});
}
};
const destroy = (external = false) => {
if (external) {
// 这里的事件是为了完整的关闭动画展示,如果关闭时没有触发该事件,那么将永远不会执行卸载操作,所以加入延时立即调用,保证最终一定会执行卸载操作
Expand All @@ -106,15 +107,23 @@ export function CommandProvider(parentInstance: ComponentInternalInstance | null
};

const consumer: IConsumer = {
promise, resolve, reject, destroyWithResolve, destroyWithReject, hide, show, destroy, container,
promise,
resolve,
reject,
destroyWithResolve,
destroyWithReject,
hide,
show,
destroy,
container,
visible: config.visible,
on: (name: string | symbol, callback: Function, config: IOnConfig = {}) => eventBus.on(consumer, name, callback, config),
once: (name: string | symbol, callback: Function) => eventBus.once(consumer, name, callback),
emit: (name: string | symbol, ...args: any) => eventBus.emit(consumer, name, ...args),
off: (name: string | symbol, callback: Function) => eventBus.off(consumer, name, callback),
stack: [],
stackIndex: -1,
componentRef: void 0
componentRef: void 0,
};

const CommandDialogProviderComponent = defineComponent({
Expand All @@ -124,11 +133,11 @@ export function CommandProvider(parentInstance: ComponentInternalInstance | null
}
provide(CommandDialogConsumerInjectKey, consumer);

const stack = inject(CommandDialogStackInjectKey, [])
consumer.stackIndex = stack.length
stack.push(consumer)
provide(CommandDialogStackInjectKey, stack)
consumer.stack = stack
const stack = inject(CommandDialogStackInjectKey, []);
consumer.stackIndex = stack.length;
stack.push(consumer);
provide(CommandDialogStackInjectKey, stack);
consumer.stack = stack;

return () => uiComponentVnode;
},
Expand All @@ -140,24 +149,27 @@ export function CommandProvider(parentInstance: ComponentInternalInstance | null
vnode.appContext!.provides = {
...vnode.appContext!.provides,
...getProvidesChain(parentInstance!),
}
};

render(vnode, container);
return consumer;
}

export const getConsumer = (warn: boolean = true): IConsumer => {
const showWarningMessage = () =>
warn && console.warn(`别调用了欧尼酱~,这会儿没啥实际用途;没有根据CommandDialogInjectKey接收到注入数据.原因可能有两个:
warn &&
console.warn(`别调用了欧尼酱~,这会儿没啥实际用途;没有根据CommandDialogInjectKey接收到注入数据.原因可能有两个:
1.你可能对getConsumer进行了异步调用或条件调用,请在setup中直接调用.
2.你没有在命令弹窗内展示该组件,这个时候你一般可以忽略该警告消息.`);

return inject<IConsumer>(
CommandDialogConsumerInjectKey,
() => new Proxy({} as IConsumer, {
get: () => showWarningMessage,
apply: showWarningMessage,
}), true
() =>
new Proxy({} as IConsumer, {
get: () => showWarningMessage,
apply: showWarningMessage,
}),
true
)!;
};

Expand Down
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createApp } from "vue";
import { router } from "./router";
import App from "./App.vue";
import 'virtual:uno.css'
// import 'virtual:uno.css'

// 导入vant-popup弹窗样式
import("vant/es/popup/style");
Expand Down

0 comments on commit a72cd95

Please sign in to comment.