mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 00:26:20 +08:00
feat: added settingButtonPosition configuration close #275
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
## Wip
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- 新增 `settingButtonPosition`配置项,用于配置`设置`按钮位置
|
||||
|
||||
## 2.0.0 (2021-02-18)
|
||||
|
||||
## (破坏性更新) Breaking changes
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
|
||||
* https://github.com/anncwb/vite-plugin-compression
|
||||
*/
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
// Image resource files used to compress the output of the production environment
|
||||
// https://github.com/anncwb/vite-plugin-imagemin
|
||||
|
||||
import viteImagemin from 'vite-plugin-imagemin';
|
||||
|
||||
|
@@ -4,7 +4,6 @@ import vue from '@vitejs/plugin-vue';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
import legacy from '@vitejs/plugin-legacy';
|
||||
|
||||
import windiCSS from 'vite-plugin-windicss';
|
||||
import PurgeIcons from 'vite-plugin-purge-icons';
|
||||
|
||||
import { ViteEnv } from '../../utils';
|
||||
@@ -16,6 +15,7 @@ import { configStyleImportPlugin } from './styleImport';
|
||||
import { configVisualizerConfig } from './visualizer';
|
||||
import { configThemePlugin } from './theme';
|
||||
import { configImageminPlugin } from './imagemin';
|
||||
import { configWindiCssPlugin } from './windicss';
|
||||
|
||||
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||
const { VITE_USE_IMAGEMIN, VITE_USE_MOCK, VITE_LEGACY, VITE_BUILD_COMPRESS } = viteEnv;
|
||||
@@ -25,7 +25,6 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||
vue(),
|
||||
// have to
|
||||
vueJsx(),
|
||||
...windiCSS(),
|
||||
];
|
||||
|
||||
// @vitejs/plugin-legacy
|
||||
@@ -34,6 +33,9 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
||||
// vite-plugin-html
|
||||
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild));
|
||||
|
||||
// vite-plugin-windicss
|
||||
vitePlugins.push(configWindiCssPlugin());
|
||||
|
||||
// vite-plugin-mock
|
||||
VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild));
|
||||
|
||||
|
12
build/vite/plugin/windicss.ts
Normal file
12
build/vite/plugin/windicss.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import windiCSS from 'vite-plugin-windicss';
|
||||
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
export function configWindiCssPlugin(): Plugin[] {
|
||||
return windiCSS({
|
||||
safelist: 'shadow shadow-xl',
|
||||
preflight: {
|
||||
enableAll: true,
|
||||
},
|
||||
});
|
||||
}
|
@@ -107,7 +107,7 @@
|
||||
"vite-plugin-pwa": "^0.4.7",
|
||||
"vite-plugin-style-import": "^0.7.2",
|
||||
"vite-plugin-theme": "^0.4.3",
|
||||
"vite-plugin-windicss": "0.2.2",
|
||||
"vite-plugin-windicss": "0.3.3",
|
||||
"vue-eslint-parser": "^7.5.0",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
|
@@ -22,6 +22,12 @@ export enum ThemeEnum {
|
||||
LIGHT = 'light',
|
||||
}
|
||||
|
||||
export enum SettingButtonPositionEnum {
|
||||
AUTO = 'auto',
|
||||
HEADER = 'header',
|
||||
FIXED = 'fixed',
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限模式
|
||||
*/
|
||||
|
@@ -160,13 +160,5 @@ export function getTargetElement(
|
||||
if (!target) {
|
||||
return defaultElement;
|
||||
}
|
||||
|
||||
let targetElement: TargetElement | undefined | null;
|
||||
|
||||
if (isFunction(target)) {
|
||||
targetElement = target();
|
||||
} else {
|
||||
targetElement = unref(target);
|
||||
}
|
||||
return targetElement;
|
||||
return isFunction(target) ? target() : unref(target);
|
||||
}
|
||||
|
@@ -16,6 +16,8 @@ const getPageLoading = computed(() => appStore.getPageLoading);
|
||||
|
||||
const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive);
|
||||
|
||||
const getSettingButtonPosition = computed(() => unref(getRootSetting).settingButtonPosition);
|
||||
|
||||
const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage);
|
||||
|
||||
const getPermissionMode = computed(() => unref(getRootSetting).permissionMode);
|
||||
@@ -58,6 +60,7 @@ export function useRootSetting() {
|
||||
return {
|
||||
setRootSetting,
|
||||
|
||||
getSettingButtonPosition,
|
||||
getFullContent,
|
||||
getColorWeak,
|
||||
getGrayMode,
|
||||
|
@@ -57,12 +57,7 @@ export function useFullscreen(
|
||||
|
||||
async function toggleFullscreen(): Promise<void> {
|
||||
if (!unref(target)) return;
|
||||
|
||||
if (isFullscreen()) {
|
||||
return exitFullscreen();
|
||||
} else {
|
||||
return enterFullscreen();
|
||||
}
|
||||
return isFullscreen() ? exitFullscreen() : enterFullscreen();
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -1,26 +1,80 @@
|
||||
<template>
|
||||
<LayoutLockPage />
|
||||
<BackTop v-if="getUseOpenBackTop" :target="getTarget" />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
import { defineComponent, computed, unref } from 'vue';
|
||||
import { BackTop } from 'ant-design-vue';
|
||||
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { SettingButtonPositionEnum } from '/@/enums/appEnum';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LayoutFeatures',
|
||||
components: {
|
||||
BackTop,
|
||||
LayoutLockPage: createAsyncComponent(() => import('/@/views/sys/lock/index.vue')),
|
||||
SettingDrawer: createAsyncComponent(() => import('/@/layouts/default/setting/index.vue')),
|
||||
},
|
||||
setup() {
|
||||
const { getUseOpenBackTop } = useRootSetting();
|
||||
const {
|
||||
getUseOpenBackTop,
|
||||
getShowSettingButton,
|
||||
getSettingButtonPosition,
|
||||
getFullContent,
|
||||
} = useRootSetting();
|
||||
|
||||
const { prefixCls } = useDesign('setting-drawer-fearure');
|
||||
const { getShowHeader } = useHeaderSetting();
|
||||
|
||||
const getIsFixedSettingDrawer = computed(() => {
|
||||
if (!unref(getShowSettingButton)) {
|
||||
return false;
|
||||
}
|
||||
const settingButtonPosition = unref(getSettingButtonPosition);
|
||||
|
||||
if (settingButtonPosition === SettingButtonPositionEnum.AUTO) {
|
||||
return !unref(getShowHeader) || unref(getFullContent);
|
||||
}
|
||||
return settingButtonPosition === SettingButtonPositionEnum.FIXED;
|
||||
});
|
||||
|
||||
return {
|
||||
getTarget: () => document.body,
|
||||
getUseOpenBackTop,
|
||||
getIsFixedSettingDrawer,
|
||||
prefixCls,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LayoutLockPage />
|
||||
<BackTop v-if="getUseOpenBackTop" :target="getTarget" />
|
||||
<SettingDrawer v-if="getIsFixedSettingDrawer" :class="prefixCls" />
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-setting-drawer-fearure';
|
||||
|
||||
.@{prefix-cls} {
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
color: @white;
|
||||
cursor: pointer;
|
||||
background: @primary-color;
|
||||
border-radius: 6px 0 0 6px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -22,7 +22,7 @@
|
||||
icon="ion:lock-closed-outline"
|
||||
/>
|
||||
<MenuItem
|
||||
key="loginOut"
|
||||
key="logout"
|
||||
:text="t('layout.header.dropdownItemLoginOut')"
|
||||
icon="ion:power-outline"
|
||||
/>
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
|
||||
type MenuEvent = 'loginOut' | 'doc' | 'lock';
|
||||
type MenuEvent = 'logout' | 'doc' | 'lock';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'UserDropdown',
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
function handleMenuClick(e: { key: MenuEvent }) {
|
||||
switch (e.key) {
|
||||
case 'loginOut':
|
||||
case 'logout':
|
||||
handleLoginOut();
|
||||
break;
|
||||
case 'doc':
|
||||
|
@@ -50,7 +50,7 @@
|
||||
|
||||
<UserDropDown :theme="getHeaderTheme" />
|
||||
|
||||
<SettingDrawer v-if="getShowSettingButton" :class="`${prefixCls}-action__item`" />
|
||||
<SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" />
|
||||
</div>
|
||||
</Header>
|
||||
</template>
|
||||
@@ -72,6 +72,7 @@
|
||||
import { useLocaleSetting } from '/@/hooks/setting/useLocaleSetting';
|
||||
|
||||
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { SettingButtonPositionEnum } from '/@/enums/appEnum';
|
||||
import { AppLocalePicker } from '/@/components/Application';
|
||||
|
||||
import { UserDropDown, LayoutBreadcrumb, FullScreen, Notify, ErrorAction } from './components';
|
||||
@@ -112,7 +113,11 @@
|
||||
getIsMixSidebar,
|
||||
} = useMenuSetting();
|
||||
const { getShowLocale } = useLocaleSetting();
|
||||
const { getUseErrorHandle, getShowSettingButton } = useRootSetting();
|
||||
const {
|
||||
getUseErrorHandle,
|
||||
getShowSettingButton,
|
||||
getSettingButtonPosition,
|
||||
} = useRootSetting();
|
||||
|
||||
const {
|
||||
getHeaderTheme,
|
||||
@@ -122,6 +127,7 @@
|
||||
getShowContent,
|
||||
getShowBread,
|
||||
getShowHeaderLogo,
|
||||
getShowHeader,
|
||||
} = useHeaderSetting();
|
||||
|
||||
const { getIsMobile } = useAppInject();
|
||||
@@ -138,6 +144,18 @@
|
||||
];
|
||||
});
|
||||
|
||||
const getShowSetting = computed(() => {
|
||||
if (!unref(getShowSettingButton)) {
|
||||
return false;
|
||||
}
|
||||
const settingButtonPosition = unref(getSettingButtonPosition);
|
||||
|
||||
if (settingButtonPosition === SettingButtonPositionEnum.AUTO) {
|
||||
return unref(getShowHeader);
|
||||
}
|
||||
return settingButtonPosition === SettingButtonPositionEnum.HEADER;
|
||||
});
|
||||
|
||||
const getLogoWidth = computed(() => {
|
||||
if (!unref(getIsMixMode) || unref(getIsMobile)) {
|
||||
return {};
|
||||
@@ -175,6 +193,7 @@
|
||||
getLogoWidth,
|
||||
getIsMixSidebar,
|
||||
getShowSettingButton,
|
||||
getShowSetting,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div @click="openDrawer" :class="prefixCls">
|
||||
<div @click="openDrawer">
|
||||
<Icon icon="ion:settings-outline" />
|
||||
<SettingDrawer @register="register" />
|
||||
</div>
|
||||
@@ -10,7 +10,6 @@
|
||||
import Icon from '/@/components/Icon';
|
||||
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SettingButton',
|
||||
@@ -18,9 +17,7 @@
|
||||
setup() {
|
||||
const [register, { openDrawer }] = useDrawer();
|
||||
|
||||
const { prefixCls } = useDesign('setting-button');
|
||||
return {
|
||||
prefixCls,
|
||||
register,
|
||||
openDrawer,
|
||||
};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
loginOutTip: 'Reminder',
|
||||
loginOutMessage: 'Confirm to exit the system?',
|
||||
logoutTip: 'Reminder',
|
||||
logoutMessage: 'Confirm to exit the system?',
|
||||
menuLoading: 'Menu loading...',
|
||||
};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
loginOutTip: '温馨提醒',
|
||||
loginOutMessage: '是否确认退出系统?',
|
||||
logoutTip: '温馨提醒',
|
||||
logoutMessage: '是否确认退出系统?',
|
||||
menuLoading: '菜单加载中...',
|
||||
};
|
||||
|
@@ -2,7 +2,13 @@ import type { ProjectConfig } from '/@/types/config';
|
||||
|
||||
import { MenuTypeEnum, MenuModeEnum, TriggerEnum, MixSidebarTriggerEnum } from '/@/enums/menuEnum';
|
||||
import { CacheTypeEnum } from '/@/enums/cacheEnum';
|
||||
import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
|
||||
import {
|
||||
ContentEnum,
|
||||
PermissionModeEnum,
|
||||
ThemeEnum,
|
||||
RouterTransitionEnum,
|
||||
SettingButtonPositionEnum,
|
||||
} from '/@/enums/appEnum';
|
||||
import { primaryColor, themeMode } from '../../build/config/themeConfig';
|
||||
|
||||
// ! You need to clear the browser cache after the change
|
||||
@@ -10,6 +16,9 @@ const setting: ProjectConfig = {
|
||||
// Whether to show the configuration button
|
||||
showSettingButton: true,
|
||||
|
||||
// `Settings` button position
|
||||
settingButtonPosition: SettingButtonPositionEnum.AUTO,
|
||||
|
||||
// Permission mode
|
||||
permissionMode: PermissionModeEnum.ROLE,
|
||||
|
||||
|
@@ -98,22 +98,22 @@ class Permission extends VuexModule {
|
||||
if (!roles) return true;
|
||||
return roleList.some((role) => roles.includes(role));
|
||||
});
|
||||
// 如果确定不需要做后台动态权限,请将下面整个判断注释
|
||||
// If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below
|
||||
} else if (permissionMode === PermissionModeEnum.BACK) {
|
||||
createMessage.loading({
|
||||
content: t('sys.app.menuLoading'),
|
||||
duration: 1,
|
||||
});
|
||||
// 这里获取后台路由菜单逻辑自行修改
|
||||
// Here to get the background routing menu logic to modify by yourself
|
||||
const paramId = id || userStore.getUserInfoState.userId;
|
||||
if (!paramId) {
|
||||
throw new Error('paramId is undefined!');
|
||||
}
|
||||
let routeList = (await getMenuListById({ id: paramId })) as AppRouteRecordRaw[];
|
||||
|
||||
// 动态引入组件
|
||||
// Dynamically introduce components
|
||||
routeList = transformObjToRoute(routeList);
|
||||
// 后台路由转菜单结构
|
||||
// Background routing to menu structure
|
||||
const backMenuList = transformRouteToMenu(routeList);
|
||||
|
||||
this.commitBackMenuListState(backMenuList);
|
||||
|
@@ -131,10 +131,10 @@ class User extends VuexModule {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: login out
|
||||
* @description: logout
|
||||
*/
|
||||
@Action
|
||||
async loginOut(goLogin = false) {
|
||||
async logout(goLogin = false) {
|
||||
goLogin && router.push(PageEnum.BASE_LOGIN);
|
||||
}
|
||||
|
||||
@@ -147,10 +147,10 @@ class User extends VuexModule {
|
||||
const { t } = useI18n();
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: t('sys.app.loginOutTip'),
|
||||
content: t('sys.app.loginOutMessage'),
|
||||
title: t('sys.app.logoutTip'),
|
||||
content: t('sys.app.logoutMessage'),
|
||||
onOk: async () => {
|
||||
await this.loginOut(true);
|
||||
await this.logout(true);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
9
src/types/config.d.ts
vendored
9
src/types/config.d.ts
vendored
@@ -1,5 +1,11 @@
|
||||
import { MenuTypeEnum, MenuModeEnum, TriggerEnum, MixSidebarTriggerEnum } from '/@/enums/menuEnum';
|
||||
import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
|
||||
import {
|
||||
ContentEnum,
|
||||
PermissionModeEnum,
|
||||
ThemeEnum,
|
||||
RouterTransitionEnum,
|
||||
SettingButtonPositionEnum,
|
||||
} from '/@/enums/appEnum';
|
||||
import { CacheTypeEnum } from '/@/enums/cacheEnum';
|
||||
import type { LocaleType } from '/@/locales/types';
|
||||
import { ThemeMode } from '../../build/config/lessModifyVars';
|
||||
@@ -88,6 +94,7 @@ export interface ProjectConfig {
|
||||
|
||||
// 是否显示配置按钮
|
||||
showSettingButton: boolean;
|
||||
settingButtonPosition: SettingButtonPositionEnum;
|
||||
// 权限模式
|
||||
permissionMode: PermissionModeEnum;
|
||||
// 网站灰色模式,用于可能悼念的日期开启
|
||||
|
@@ -100,9 +100,9 @@ export function findPath<T = any>(
|
||||
|
||||
export function findPathAll(tree: any, func: Fn, config: Partial<TreeHelperConfig> = {}) {
|
||||
config = getConfig(config);
|
||||
const path = [];
|
||||
const path: any[] = [];
|
||||
const list = [...tree];
|
||||
const result = [];
|
||||
const result: any[] = [];
|
||||
const visitedSet = new Set(),
|
||||
{ children } = config;
|
||||
while (list.length) {
|
||||
@@ -153,14 +153,14 @@ export function forEach<T = any>(
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 提取tree指定结构
|
||||
* @description: Extract tree specified structure
|
||||
*/
|
||||
export function treeMap<T = any>(treeData: T[], opt: { children?: string; conversion: Fn }): T[] {
|
||||
return treeData.map((item) => treeMapEach(item, opt));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 提取tree指定结构
|
||||
* @description: Extract tree specified structure
|
||||
*/
|
||||
export function treeMapEach(
|
||||
data: any,
|
||||
|
@@ -15,7 +15,7 @@ export function checkStatus(status: number, msg: string): void {
|
||||
// Return to the current page after successful login. This step needs to be operated on the login page.
|
||||
case 401:
|
||||
error(t('sys.api.errMsg401'));
|
||||
userStore.loginOut(true);
|
||||
userStore.logout(true);
|
||||
break;
|
||||
case 403:
|
||||
error(t('sys.api.errMsg403'));
|
||||
|
@@ -23,17 +23,11 @@ export function getPopupContainer(node?: HTMLElement): HTMLElement {
|
||||
*/
|
||||
export function setObjToUrlParams(baseUrl: string, obj: any): string {
|
||||
let parameters = '';
|
||||
let url = '';
|
||||
for (const key in obj) {
|
||||
parameters += key + '=' + encodeURIComponent(obj[key]) + '&';
|
||||
}
|
||||
parameters = parameters.replace(/&$/, '');
|
||||
if (/\?$/.test(baseUrl)) {
|
||||
url = baseUrl + parameters;
|
||||
} else {
|
||||
url = baseUrl.replace(/\/?$/, '?') + parameters;
|
||||
}
|
||||
return url;
|
||||
return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters;
|
||||
}
|
||||
|
||||
export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
|
||||
@@ -45,7 +39,7 @@ export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 根据数组中某个对象值去重
|
||||
* @description: Deduplication according to the value of an object in the array
|
||||
*/
|
||||
export function unique<T = any>(arr: T[], key: string): T[] {
|
||||
const map = new Map();
|
||||
@@ -56,7 +50,7 @@ export function unique<T = any>(arr: T[], key: string): T[] {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: es6数组去重复
|
||||
* @description: es6 array to repeat
|
||||
*/
|
||||
export function es6Unique<T>(arr: T[]): T[] {
|
||||
return Array.from(new Set(arr));
|
||||
|
@@ -115,7 +115,7 @@
|
||||
}
|
||||
|
||||
function goLogin() {
|
||||
userStore.loginOut(true);
|
||||
userStore.logout(true);
|
||||
lockStore.resetLockInfo();
|
||||
}
|
||||
|
||||
@@ -287,6 +287,7 @@
|
||||
|
||||
&-img {
|
||||
width: 70px;
|
||||
margin: 0 auto;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
|
@@ -9370,12 +9370,13 @@ vite-plugin-theme@^0.4.3:
|
||||
es-module-lexer "^0.3.26"
|
||||
tinycolor2 "^1.4.2"
|
||||
|
||||
vite-plugin-windicss@0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.2.2.tgz#2abf1533153f5dc214a9e1a06fb58274e5892c19"
|
||||
integrity sha512-P+iyrcuLjLfjiYP+bBisfKbg9bmeQMUBpjsTFJ9kWWX2fyqo968CHmS3euz+MzRcK5ZECccpOxx60ZXzc12VAw==
|
||||
vite-plugin-windicss@0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.3.3.tgz#9ff2fc485dd5cf1717cde6eed462fd9893ea9eab"
|
||||
integrity sha512-2gm0sTexkmvx9PR4NP1UESly8hX2souOruQztu1qghfw4M3tlUUvwneRpJG5HVJCKCctmAgYRcW4e04TE5R1fA==
|
||||
dependencies:
|
||||
fast-glob "^3.2.5"
|
||||
micromatch "^4.0.2"
|
||||
windicss "^2.1.11"
|
||||
|
||||
vite@2.0.1:
|
||||
|
Reference in New Issue
Block a user