Pre Merge pull request !26 from 玲娜贝er/dev
This commit is contained in:
commit
345721e7c8
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/web-antd",
|
"name": "@vben/web-antd",
|
||||||
"version": "1.3.0",
|
"version": "1.3.1",
|
||||||
"homepage": "https://vben.pro",
|
"homepage": "https://vben.pro",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -2,6 +2,11 @@ import type { RouteRecordStringComponent } from '@vben/types';
|
|||||||
|
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
|
const {
|
||||||
|
version,
|
||||||
|
// vite inject-metadata 插件注入的全局变量
|
||||||
|
} = __VBEN_ADMIN_METADATA__ || {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该文件放非后台返回的路由 比如个人中心 等需要跳转显示的页面
|
* 该文件放非后台返回的路由 比如个人中心 等需要跳转显示的页面
|
||||||
*/
|
*/
|
||||||
@ -134,8 +139,8 @@ export const localMenuList: RouteRecordStringComponent[] = [
|
|||||||
icon: 'lucide:book-open-text',
|
icon: 'lucide:book-open-text',
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
title: '更新记录',
|
title: '更新记录',
|
||||||
badge: '1.3.0',
|
badge: `当前: ${version}`,
|
||||||
badgeVariants: '#CC0033',
|
badgeVariants: 'bg-primary',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -77,7 +77,7 @@ const [BasicDrawer, drawerApi] = useVbenDrawer({
|
|||||||
|
|
||||||
const { dictCode, dictType } = drawerApi.getData() as DrawerProps;
|
const { dictCode, dictType } = drawerApi.getData() as DrawerProps;
|
||||||
isUpdate.value = !!dictCode;
|
isUpdate.value = !!dictCode;
|
||||||
formApi.setFieldValue('dictType', dictType);
|
await formApi.setFieldValue('dictType', dictType);
|
||||||
|
|
||||||
if (dictCode && isUpdate.value) {
|
if (dictCode && isUpdate.value) {
|
||||||
const record = await dictDetailInfo(dictCode);
|
const record = await dictDetailInfo(dictCode);
|
||||||
|
@ -8,6 +8,7 @@ import { addFullName, cloneDeep } from '@vben/utils';
|
|||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { postAdd, postInfo, postUpdate } from '#/api/system/post';
|
import { postAdd, postInfo, postUpdate } from '#/api/system/post';
|
||||||
import { getDeptTree } from '#/api/system/user';
|
import { getDeptTree } from '#/api/system/user';
|
||||||
|
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
|
||||||
|
|
||||||
import { drawerSchema } from './data';
|
import { drawerSchema } from './data';
|
||||||
|
|
||||||
@ -50,8 +51,16 @@ async function setupDeptSelect() {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
|
||||||
|
{
|
||||||
|
initializedGetter: defaultFormValueGetter(formApi),
|
||||||
|
currentGetter: defaultFormValueGetter(formApi),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const [BasicDrawer, drawerApi] = useVbenDrawer({
|
const [BasicDrawer, drawerApi] = useVbenDrawer({
|
||||||
onCancel: handleCancel,
|
onBeforeClose,
|
||||||
|
onClosed: handleClosed,
|
||||||
onConfirm: handleConfirm,
|
onConfirm: handleConfirm,
|
||||||
async onOpenChange(isOpen) {
|
async onOpenChange(isOpen) {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
@ -67,31 +76,33 @@ const [BasicDrawer, drawerApi] = useVbenDrawer({
|
|||||||
const record = await postInfo(id);
|
const record = await postInfo(id);
|
||||||
await formApi.setValues(record);
|
await formApi.setValues(record);
|
||||||
}
|
}
|
||||||
|
await markInitialized();
|
||||||
drawerApi.drawerLoading(false);
|
drawerApi.drawerLoading(false);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleConfirm() {
|
async function handleConfirm() {
|
||||||
try {
|
try {
|
||||||
drawerApi.drawerLoading(true);
|
drawerApi.lock(true);
|
||||||
const { valid } = await formApi.validate();
|
const { valid } = await formApi.validate();
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data = cloneDeep(await formApi.getValues());
|
const data = cloneDeep(await formApi.getValues());
|
||||||
await (isUpdate.value ? postUpdate(data) : postAdd(data));
|
await (isUpdate.value ? postUpdate(data) : postAdd(data));
|
||||||
|
resetInitialized();
|
||||||
emit('reload');
|
emit('reload');
|
||||||
await handleCancel();
|
drawerApi.close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
drawerApi.drawerLoading(false);
|
drawerApi.lock(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleCancel() {
|
async function handleClosed() {
|
||||||
drawerApi.close();
|
|
||||||
await formApi.resetForm();
|
await formApi.resetForm();
|
||||||
|
resetInitialized();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -94,7 +94,8 @@ export const columns: VxeGridProps['columns'] = [
|
|||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
slots: { default: 'action' },
|
slots: { default: 'action' },
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 180,
|
resizable: false,
|
||||||
|
width: 'auto',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -226,7 +226,11 @@ function handleAssignRole(record: Role) {
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</template>
|
</template>
|
||||||
<a-button size="small" type="link">
|
<a-button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
v-access:code="'system:role:edit'"
|
||||||
|
>
|
||||||
{{ $t('pages.common.more') }}
|
{{ $t('pages.common.more') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
@ -52,7 +52,7 @@ const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
|
|||||||
const [BasicModal, modalApi] = useVbenModal({
|
const [BasicModal, modalApi] = useVbenModal({
|
||||||
fullscreenButton: false,
|
fullscreenButton: false,
|
||||||
onBeforeClose,
|
onBeforeClose,
|
||||||
onCancel: handleClosed,
|
onClosed: handleClosed,
|
||||||
onConfirm: handleConfirm,
|
onConfirm: handleConfirm,
|
||||||
onOpenChange: async (isOpen) => {
|
onOpenChange: async (isOpen) => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
|
@ -87,7 +87,7 @@ export const columns: VxeGridProps['columns'] = [
|
|||||||
slots: { default: 'action' },
|
slots: { default: 'action' },
|
||||||
title: '操作',
|
title: '操作',
|
||||||
resizable: false,
|
resizable: false,
|
||||||
width: 180,
|
width: 'auto',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
|
|||||||
|
|
||||||
const [BasicDrawer, modalApi] = useVbenModal({
|
const [BasicDrawer, modalApi] = useVbenModal({
|
||||||
onBeforeClose,
|
onBeforeClose,
|
||||||
onCancel: handleClosed,
|
onClosed: handleClosed,
|
||||||
onConfirm: handleConfirm,
|
onConfirm: handleConfirm,
|
||||||
async onOpenChange(isOpen) {
|
async onOpenChange(isOpen) {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
|
@ -2,14 +2,16 @@ import type { DeepPartial } from '@vben-core/typings';
|
|||||||
|
|
||||||
import type { InitialOptions, Preferences } from './types';
|
import type { InitialOptions, Preferences } from './types';
|
||||||
|
|
||||||
|
import { markRaw, reactive, readonly, watch } from 'vue';
|
||||||
|
|
||||||
import { StorageManager } from '@vben-core/shared/cache';
|
import { StorageManager } from '@vben-core/shared/cache';
|
||||||
import { isMacOs, merge } from '@vben-core/shared/utils';
|
import { isMacOs, merge } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
breakpointsTailwind,
|
breakpointsTailwind,
|
||||||
useBreakpoints,
|
useBreakpoints,
|
||||||
useDebounceFn,
|
useDebounceFn,
|
||||||
} from '@vueuse/core';
|
} from '@vueuse/core';
|
||||||
import { markRaw, reactive, readonly, watch } from 'vue';
|
|
||||||
|
|
||||||
import { defaultPreferences } from './config';
|
import { defaultPreferences } from './config';
|
||||||
import { updateCSSVariables } from './update-css-variables';
|
import { updateCSSVariables } from './update-css-variables';
|
||||||
@ -37,106 +39,6 @@ class PreferenceManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存偏好设置
|
|
||||||
* @param {Preferences} preference - 需要保存的偏好设置
|
|
||||||
*/
|
|
||||||
private _savePreferences(preference: Preferences) {
|
|
||||||
this.cache?.setItem(STORAGE_KEY, preference);
|
|
||||||
this.cache?.setItem(STORAGE_KEY_LOCALE, preference.app.locale);
|
|
||||||
this.cache?.setItem(STORAGE_KEY_THEME, preference.theme.mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理更新的键值
|
|
||||||
* 根据更新的键值执行相应的操作。
|
|
||||||
* @param {DeepPartial<Preferences>} updates - 部分更新的偏好设置
|
|
||||||
*/
|
|
||||||
private handleUpdates(updates: DeepPartial<Preferences>) {
|
|
||||||
const themeUpdates = updates.theme || {};
|
|
||||||
const appUpdates = updates.app || {};
|
|
||||||
if (themeUpdates && Object.keys(themeUpdates).length > 0) {
|
|
||||||
updateCSSVariables(this.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
Reflect.has(appUpdates, 'colorGrayMode') ||
|
|
||||||
Reflect.has(appUpdates, 'colorWeakMode')
|
|
||||||
) {
|
|
||||||
this.updateColorMode(this.state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private initPlatform() {
|
|
||||||
const dom = document.documentElement;
|
|
||||||
dom.dataset.platform = isMacOs() ? 'macOs' : 'window';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从缓存中加载偏好设置。如果缓存中没有找到对应的偏好设置,则返回默认偏好设置。
|
|
||||||
*/
|
|
||||||
private loadCachedPreferences() {
|
|
||||||
return this.cache?.getItem<Preferences>(STORAGE_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载偏好设置
|
|
||||||
* @returns {Preferences} 加载的偏好设置
|
|
||||||
*/
|
|
||||||
private loadPreferences(): Preferences {
|
|
||||||
return this.loadCachedPreferences() || { ...defaultPreferences };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 监听状态和系统偏好设置的变化。
|
|
||||||
*/
|
|
||||||
private setupWatcher() {
|
|
||||||
if (this.isInitialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听断点,判断是否移动端
|
|
||||||
const breakpoints = useBreakpoints(breakpointsTailwind);
|
|
||||||
const isMobile = breakpoints.smaller('md');
|
|
||||||
watch(
|
|
||||||
() => isMobile.value,
|
|
||||||
(val) => {
|
|
||||||
this.updatePreferences({
|
|
||||||
app: { isMobile: val },
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{ immediate: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
// 监听系统主题偏好设置变化
|
|
||||||
window
|
|
||||||
.matchMedia('(prefers-color-scheme: dark)')
|
|
||||||
.addEventListener('change', ({ matches: isDark }) => {
|
|
||||||
this.updatePreferences({
|
|
||||||
theme: { mode: isDark ? 'dark' : 'light' },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新页面颜色模式(灰色、色弱)
|
|
||||||
* @param preference
|
|
||||||
*/
|
|
||||||
private updateColorMode(preference: Preferences) {
|
|
||||||
if (preference.app) {
|
|
||||||
const { colorGrayMode, colorWeakMode } = preference.app;
|
|
||||||
const dom = document.documentElement;
|
|
||||||
const COLOR_WEAK = 'invert-mode';
|
|
||||||
const COLOR_GRAY = 'grayscale-mode';
|
|
||||||
colorWeakMode
|
|
||||||
? dom.classList.add(COLOR_WEAK)
|
|
||||||
: dom.classList.remove(COLOR_WEAK);
|
|
||||||
colorGrayMode
|
|
||||||
? dom.classList.add(COLOR_GRAY)
|
|
||||||
: dom.classList.remove(COLOR_GRAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clearCache() {
|
clearCache() {
|
||||||
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
|
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
|
||||||
this.cache?.removeItem(key);
|
this.cache?.removeItem(key);
|
||||||
@ -220,6 +122,113 @@ class PreferenceManager {
|
|||||||
this.handleUpdates(updates);
|
this.handleUpdates(updates);
|
||||||
this.savePreferences(this.state);
|
this.savePreferences(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存偏好设置
|
||||||
|
* @param {Preferences} preference - 需要保存的偏好设置
|
||||||
|
*/
|
||||||
|
private _savePreferences(preference: Preferences) {
|
||||||
|
this.cache?.setItem(STORAGE_KEY, preference);
|
||||||
|
this.cache?.setItem(STORAGE_KEY_LOCALE, preference.app.locale);
|
||||||
|
this.cache?.setItem(STORAGE_KEY_THEME, preference.theme.mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理更新的键值
|
||||||
|
* 根据更新的键值执行相应的操作。
|
||||||
|
* @param {DeepPartial<Preferences>} updates - 部分更新的偏好设置
|
||||||
|
*/
|
||||||
|
private handleUpdates(updates: DeepPartial<Preferences>) {
|
||||||
|
const themeUpdates = updates.theme || {};
|
||||||
|
const appUpdates = updates.app || {};
|
||||||
|
if (themeUpdates && Object.keys(themeUpdates).length > 0) {
|
||||||
|
updateCSSVariables(this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
Reflect.has(appUpdates, 'colorGrayMode') ||
|
||||||
|
Reflect.has(appUpdates, 'colorWeakMode')
|
||||||
|
) {
|
||||||
|
this.updateColorMode(this.state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private initPlatform() {
|
||||||
|
const dom = document.documentElement;
|
||||||
|
dom.dataset.platform = isMacOs() ? 'macOs' : 'window';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从缓存中加载偏好设置。如果缓存中没有找到对应的偏好设置,则返回默认偏好设置。
|
||||||
|
*/
|
||||||
|
private loadCachedPreferences() {
|
||||||
|
return this.cache?.getItem<Preferences>(STORAGE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载偏好设置
|
||||||
|
* @returns {Preferences} 加载的偏好设置
|
||||||
|
*/
|
||||||
|
private loadPreferences(): Preferences {
|
||||||
|
return this.loadCachedPreferences() || { ...defaultPreferences };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听状态和系统偏好设置的变化。
|
||||||
|
*/
|
||||||
|
private setupWatcher() {
|
||||||
|
if (this.isInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听断点,判断是否移动端
|
||||||
|
const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||||
|
const isMobile = breakpoints.smaller('md');
|
||||||
|
watch(
|
||||||
|
() => isMobile.value,
|
||||||
|
(val) => {
|
||||||
|
this.updatePreferences({
|
||||||
|
app: { isMobile: val },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听系统主题偏好设置变化
|
||||||
|
window
|
||||||
|
.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
.addEventListener('change', ({ matches: isDark }) => {
|
||||||
|
// 如果偏好设置中主题模式为auto,则跟随系统更新
|
||||||
|
if (this.state.theme.mode === 'auto') {
|
||||||
|
this.updatePreferences({
|
||||||
|
theme: { mode: isDark ? 'dark' : 'light' },
|
||||||
|
});
|
||||||
|
// 恢复为auto模式
|
||||||
|
this.updatePreferences({
|
||||||
|
theme: { mode: 'auto' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新页面颜色模式(灰色、色弱)
|
||||||
|
* @param preference
|
||||||
|
*/
|
||||||
|
private updateColorMode(preference: Preferences) {
|
||||||
|
if (preference.app) {
|
||||||
|
const { colorGrayMode, colorWeakMode } = preference.app;
|
||||||
|
const dom = document.documentElement;
|
||||||
|
const COLOR_WEAK = 'invert-mode';
|
||||||
|
const COLOR_GRAY = 'grayscale-mode';
|
||||||
|
colorWeakMode
|
||||||
|
? dom.classList.add(COLOR_WEAK)
|
||||||
|
: dom.classList.remove(COLOR_WEAK);
|
||||||
|
colorGrayMode
|
||||||
|
? dom.classList.add(COLOR_GRAY)
|
||||||
|
: dom.classList.remove(COLOR_GRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const preferencesManager = new PreferenceManager();
|
const preferencesManager = new PreferenceManager();
|
||||||
|
@ -138,7 +138,7 @@ async function handleOpenChange(val: boolean) {
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<component :is="getIconRender" class="mr-2" />
|
<component :is="getIconRender" class="mr-2" />
|
||||||
<span class="flex-auto">{{ $t(title) }}</span>
|
<span class="flex-auto">{{ $t(title) }}</span>
|
||||||
<AlertDialogCancel v-if="showCancel">
|
<AlertDialogCancel v-if="showCancel" as-child>
|
||||||
<VbenButton
|
<VbenButton
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
@ -158,16 +158,17 @@ async function handleOpenChange(val: boolean) {
|
|||||||
<VbenLoading v-if="loading && contentMasking" :spinning="loading" />
|
<VbenLoading v-if="loading && contentMasking" :spinning="loading" />
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
<div class="flex justify-end gap-x-2" :class="`justify-${buttonAlign}`">
|
<div class="flex justify-end gap-x-2" :class="`justify-${buttonAlign}`">
|
||||||
<AlertDialogCancel v-if="showCancel" :disabled="loading">
|
<AlertDialogCancel v-if="showCancel" as-child>
|
||||||
<component
|
<component
|
||||||
:is="components.DefaultButton || VbenButton"
|
:is="components.DefaultButton || VbenButton"
|
||||||
|
:disabled="loading"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="handleCancel"
|
@click="handleCancel"
|
||||||
>
|
>
|
||||||
{{ cancelText || $t('cancel') }}
|
{{ cancelText || $t('cancel') }}
|
||||||
</component>
|
</component>
|
||||||
</AlertDialogCancel>
|
</AlertDialogCancel>
|
||||||
<AlertDialogAction>
|
<AlertDialogAction as-child>
|
||||||
<component
|
<component
|
||||||
:is="components.PrimaryButton || VbenButton"
|
:is="components.PrimaryButton || VbenButton"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
@ -17,12 +17,15 @@ export * from '@vben-core/popup-ui';
|
|||||||
|
|
||||||
// 给文档用
|
// 给文档用
|
||||||
export {
|
export {
|
||||||
|
VbenAvatar,
|
||||||
VbenButton,
|
VbenButton,
|
||||||
VbenButtonGroup,
|
VbenButtonGroup,
|
||||||
VbenCheckButtonGroup,
|
VbenCheckButtonGroup,
|
||||||
VbenCountToAnimator,
|
VbenCountToAnimator,
|
||||||
|
VbenFullScreen,
|
||||||
VbenInputPassword,
|
VbenInputPassword,
|
||||||
VbenLoading,
|
VbenLoading,
|
||||||
|
VbenLogo,
|
||||||
VbenPinInput,
|
VbenPinInput,
|
||||||
VbenSpinner,
|
VbenSpinner,
|
||||||
VbenTree,
|
VbenTree,
|
||||||
|
@ -9,6 +9,8 @@ import { $t } from '@vben/locales';
|
|||||||
import { BUILT_IN_THEME_PRESETS } from '@vben/preferences';
|
import { BUILT_IN_THEME_PRESETS } from '@vben/preferences';
|
||||||
import { convertToHsl, TinyColor } from '@vben/utils';
|
import { convertToHsl, TinyColor } from '@vben/utils';
|
||||||
|
|
||||||
|
import { useThrottleFn } from '@vueuse/core';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'PreferenceBuiltinTheme',
|
name: 'PreferenceBuiltinTheme',
|
||||||
});
|
});
|
||||||
@ -19,6 +21,15 @@ const colorInput = ref();
|
|||||||
const modelValue = defineModel<BuiltinThemeType>({ default: 'default' });
|
const modelValue = defineModel<BuiltinThemeType>({ default: 'default' });
|
||||||
const themeColorPrimary = defineModel<string>('themeColorPrimary');
|
const themeColorPrimary = defineModel<string>('themeColorPrimary');
|
||||||
|
|
||||||
|
const updateThemeColorPrimary = useThrottleFn(
|
||||||
|
(value: string) => {
|
||||||
|
themeColorPrimary.value = value;
|
||||||
|
},
|
||||||
|
300,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
const inputValue = computed(() => {
|
const inputValue = computed(() => {
|
||||||
return new TinyColor(themeColorPrimary.value || '').toHexString();
|
return new TinyColor(themeColorPrimary.value || '').toHexString();
|
||||||
});
|
});
|
||||||
@ -84,7 +95,7 @@ function handleSelect(theme: BuiltinThemePreset) {
|
|||||||
|
|
||||||
function handleInputChange(e: Event) {
|
function handleInputChange(e: Event) {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
themeColorPrimary.value = convertToHsl(target.value);
|
updateThemeColorPrimary(convertToHsl(target.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectColor() {
|
function selectColor() {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import type { SetupVxeTable } from './types';
|
import type { SetupVxeTable } from './types';
|
||||||
|
|
||||||
import { usePreferences } from '@vben/preferences';
|
|
||||||
import { useVbenForm } from '@vben-core/form-ui';
|
|
||||||
import { defineComponent, watch } from 'vue';
|
import { defineComponent, watch } from 'vue';
|
||||||
|
|
||||||
|
import { usePreferences } from '@vben/preferences';
|
||||||
|
|
||||||
|
import { useVbenForm } from '@vben-core/form-ui';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
VxeButton,
|
VxeButton,
|
||||||
VxeCheckbox,
|
VxeCheckbox,
|
||||||
@ -103,7 +106,7 @@ export function setupVbenVxeTable(setupOptions: SetupVxeTable) {
|
|||||||
initVxeTable();
|
initVxeTable();
|
||||||
useTableForm = useVbenForm;
|
useTableForm = useVbenForm;
|
||||||
|
|
||||||
const preference = usePreferences();
|
const { isDark, locale } = usePreferences();
|
||||||
|
|
||||||
const localMap = {
|
const localMap = {
|
||||||
'zh-CN': zhCN,
|
'zh-CN': zhCN,
|
||||||
@ -111,11 +114,11 @@ export function setupVbenVxeTable(setupOptions: SetupVxeTable) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[() => preference.theme.value, () => preference.locale.value],
|
[() => isDark.value, () => locale.value],
|
||||||
([theme, locale]) => {
|
([isDarkValue, localeValue]) => {
|
||||||
VxeUI.setTheme(theme === 'dark' ? 'dark' : 'light');
|
VxeUI.setTheme(isDarkValue ? 'dark' : 'light');
|
||||||
VxeUI.setI18n(locale, localMap[locale]);
|
VxeUI.setI18n(localeValue, localMap[localeValue]);
|
||||||
VxeUI.setLanguage(locale);
|
VxeUI.setLanguage(localeValue);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
@ -261,6 +261,9 @@ async function openPrompt() {
|
|||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
<Card class="w-[300px]" title="轻量提示弹窗">
|
<Card class="w-[300px]" title="轻量提示弹窗">
|
||||||
|
<template #extra>
|
||||||
|
<DocButton path="/components/common-ui/vben-alert" />
|
||||||
|
</template>
|
||||||
<p>通过快捷方法创建动态提示弹窗,适合一些轻量的提示和确认、输入等</p>
|
<p>通过快捷方法创建动态提示弹窗,适合一些轻量的提示和确认、输入等</p>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button type="primary" @click="openAlert">Alert</Button>
|
<Button type="primary" @click="openAlert">Alert</Button>
|
||||||
|
Loading…
Reference in New Issue
Block a user