Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/vant/src/popup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import _Popup from './Popup';
export const Popup = withInstall(_Popup);
export default Popup;
export { popupProps } from './Popup';
export {
useGlobalZIndex,
setGlobalZIndex,
} from '../composables/use-global-z-index';
Comment on lines +7 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While exporting useGlobalZIndex can be useful for integrating custom components with Vant's layering system, exporting setGlobalZIndex is concerning. It allows modification of a global variable from anywhere in an application, which can lead to race conditions and unpredictable behavior, especially in large-scale projects. For instance, different parts of an application could overwrite the global z-index, leading to hard-to-debug layering issues with popups.

A more robust approach for managing the base z-index would be to handle it through a centralized configuration, for example, when installing the Vant plugin:

app.use(Vant, { globalZIndex: 3000 });

This ensures that the configuration is set once and avoids accidental modifications at runtime. If dynamic changes are necessary, a solution based on Vue's provide/inject API would be safer and more aligned with Vue's reactivity principles.

Please consider an alternative design that avoids exporting a setter for a global mutable state.

export type { PopupProps } from './Popup';
export type {
PopupPosition,
Expand Down
28 changes: 27 additions & 1 deletion packages/vant/src/popup/test/index.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { nextTick } from 'vue';
import { mount, triggerDrag } from '../../../test';
import { Popup } from '..';
import { Popup, useGlobalZIndex, setGlobalZIndex } from '..';

let wrapper;
afterEach(() => {
Expand Down Expand Up @@ -303,3 +303,29 @@ test('should destroy content when using destroyOnClose prop', async () => {
await wrapper.setProps({ show: false });
expect(wrapper.find('.foo').exists()).toBeFalsy();
});

test('useGlobalZIndex should return auto-incrementing z-index', () => {
setGlobalZIndex(2000);
const first = useGlobalZIndex();
const second = useGlobalZIndex();
const third = useGlobalZIndex();
expect(first).toBe(2001);
expect(second).toBe(2002);
expect(third).toBe(2003);
});

test('setGlobalZIndex should reset the global z-index', () => {
setGlobalZIndex(100);
expect(useGlobalZIndex()).toBe(101);
expect(useGlobalZIndex()).toBe(102);

setGlobalZIndex(500);
expect(useGlobalZIndex()).toBe(501);
expect(useGlobalZIndex()).toBe(502);
});

test('setGlobalZIndex should allow custom initial value', () => {
setGlobalZIndex(0);
expect(useGlobalZIndex()).toBe(1);
expect(useGlobalZIndex()).toBe(2);
});
Loading