Merge branch 'main' of https://gitee.com/dapppp/ruoyi-plus-vben5 into dev
This commit is contained in:
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -62,7 +62,7 @@ body:
|
|||||||
description: Before submitting the issue, please make sure you do the following
|
description: Before submitting the issue, please make sure you do the following
|
||||||
# description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com).
|
# description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com).
|
||||||
options:
|
options:
|
||||||
- label: Read the [docs](https://anncwb.github.io/vue-vben-admin-doc/)
|
- label: Read the [docs](https://doc.vben.pro/)
|
||||||
required: true
|
required: true
|
||||||
- label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
|
- label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -62,7 +62,7 @@ body:
|
|||||||
label: Validations
|
label: Validations
|
||||||
description: Before submitting the issue, please make sure you do the following
|
description: Before submitting the issue, please make sure you do the following
|
||||||
options:
|
options:
|
||||||
- label: Read the [docs](https://anncwb.github.io/vue-vben-admin-doc/)
|
- label: Read the [docs](https://doc.vben.pro/)
|
||||||
required: true
|
required: true
|
||||||
- label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
|
- label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
|
||||||
required: true
|
required: true
|
||||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,3 +1,15 @@
|
|||||||
|
# 1.1.3
|
||||||
|
|
||||||
|
**Bug Fixes**
|
||||||
|
|
||||||
|
- 节点树在编辑 & 空数组(不勾选)情况 勾选节点会造成watch延迟触发 导致会带上父节点id造成id重复
|
||||||
|
- 节点树在节点独立情况下的控制台warning: Invalid prop: type check failed for prop "value". Expected Array, got Object
|
||||||
|
|
||||||
|
**Others**
|
||||||
|
|
||||||
|
- 角色管理 优化Drawer布局
|
||||||
|
- unplugin-vue-components插件(默认未开启) 需要排除Button组件 全局已经默认导入了
|
||||||
|
|
||||||
# 1.1.2
|
# 1.1.2
|
||||||
|
|
||||||
**Features**
|
**Features**
|
||||||
|
@@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
|||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -51,6 +51,7 @@ const withDefaultPlaceholder = <T extends Component>(
|
|||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'AutoComplete'
|
| 'AutoComplete'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
@@ -58,6 +59,7 @@ export type ComponentType =
|
|||||||
| 'DefaultButton'
|
| 'DefaultButton'
|
||||||
| 'Divider'
|
| 'Divider'
|
||||||
| 'FileUpload'
|
| 'FileUpload'
|
||||||
|
| 'IconPicker'
|
||||||
| 'ImageUpload'
|
| 'ImageUpload'
|
||||||
| 'Input'
|
| 'Input'
|
||||||
| 'InputNumber'
|
| 'InputNumber'
|
||||||
@@ -83,7 +85,20 @@ async function initComponentAdapter() {
|
|||||||
// 如果你的组件体积比较大,可以使用异步加载
|
// 如果你的组件体积比较大,可以使用异步加载
|
||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: Select,
|
||||||
|
loadingSlot: 'suffixIcon',
|
||||||
|
visibleEvent: 'onDropdownVisibleChange',
|
||||||
|
modelField: 'value',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
@@ -93,6 +108,7 @@ async function initComponentAdapter() {
|
|||||||
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
||||||
},
|
},
|
||||||
Divider,
|
Divider,
|
||||||
|
IconPicker,
|
||||||
Input: withDefaultPlaceholder(Input, 'input'),
|
Input: withDefaultPlaceholder(Input, 'input'),
|
||||||
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
||||||
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
||||||
|
@@ -8,6 +8,7 @@ import { computed, nextTick, onMounted, type PropType, ref, watch } from 'vue';
|
|||||||
import { findGroupParentIds, treeToList } from '@vben/utils';
|
import { findGroupParentIds, treeToList } from '@vben/utils';
|
||||||
|
|
||||||
import { Checkbox, Tree } from 'ant-design-vue';
|
import { Checkbox, Tree } from 'ant-design-vue';
|
||||||
|
import { uniq } from 'lodash-es';
|
||||||
|
|
||||||
/** 需要禁止透传 */
|
/** 需要禁止透传 */
|
||||||
defineOptions({ inheritAttrs: false });
|
defineOptions({ inheritAttrs: false });
|
||||||
@@ -73,6 +74,8 @@ const checkedRealKeys = ref<(number | string)[]>([]);
|
|||||||
/**
|
/**
|
||||||
* 取第一次的menuTree id 设置到checkedMenuKeys
|
* 取第一次的menuTree id 设置到checkedMenuKeys
|
||||||
* 主要为了解决没有任何修改 直接点击保存的情况
|
* 主要为了解决没有任何修改 直接点击保存的情况
|
||||||
|
*
|
||||||
|
* length为0情况(即新增时候没有勾选节点) 勾选这里会延迟触发 节点会拼接上父节点 导致ID重复
|
||||||
*/
|
*/
|
||||||
const stop = watch([checkedKeys, () => props.treeData], () => {
|
const stop = watch([checkedKeys, () => props.treeData], () => {
|
||||||
if (
|
if (
|
||||||
@@ -86,7 +89,10 @@ const stop = watch([checkedKeys, () => props.treeData], () => {
|
|||||||
checkedKeys.value as any,
|
checkedKeys.value as any,
|
||||||
{ id: props.fieldNames.key },
|
{ id: props.fieldNames.key },
|
||||||
);
|
);
|
||||||
checkedRealKeys.value = [...parentIds, ...checkedKeys.value];
|
/**
|
||||||
|
* uniq 解决上面的id重复问题
|
||||||
|
*/
|
||||||
|
checkedRealKeys.value = uniq([...parentIds, ...checkedKeys.value]);
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
if (!props.checkStrictly && checkedKeys.value.length > 0) {
|
if (!props.checkStrictly && checkedKeys.value.length > 0) {
|
||||||
@@ -98,19 +104,21 @@ const stop = watch([checkedKeys, () => props.treeData], () => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param checkedKeys 已经选中的子节点的ID
|
* @param checkedStateKeys 已经选中的子节点的ID
|
||||||
* @param info info.halfCheckedKeys为父节点的ID
|
* @param info info.halfCheckedKeys为父节点的ID
|
||||||
*/
|
*/
|
||||||
type CheckedState<T = number | string> =
|
type CheckedState<T = number | string> =
|
||||||
| { checked: T[]; halfChecked: T[] }
|
| { checked: T[]; halfChecked: T[] }
|
||||||
| T[];
|
| T[];
|
||||||
function handleChecked(checkedKeys: CheckedState, info: CheckInfo) {
|
function handleChecked(checkedStateKeys: CheckedState, info: CheckInfo) {
|
||||||
// 数组的话为节点关联
|
// 数组的话为节点关联
|
||||||
if (Array.isArray(checkedKeys)) {
|
if (Array.isArray(checkedStateKeys)) {
|
||||||
const halfCheckedKeys: number[] = (info.halfCheckedKeys || []) as number[];
|
const halfCheckedKeys: number[] = (info.halfCheckedKeys || []) as number[];
|
||||||
checkedRealKeys.value = [...halfCheckedKeys, ...checkedKeys];
|
checkedRealKeys.value = [...halfCheckedKeys, ...checkedStateKeys];
|
||||||
} else {
|
} else {
|
||||||
checkedRealKeys.value = [...checkedKeys.checked];
|
checkedRealKeys.value = [...checkedStateKeys.checked];
|
||||||
|
// fix: Invalid prop: type check failed for prop "value". Expected Array, got Object
|
||||||
|
checkedKeys.value = [...checkedStateKeys.checked];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +145,10 @@ function handleCheckStrictlyChange(e: CheckboxChangeEvent) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 暴露方法来获取用于提交的全部节点
|
* 暴露方法来获取用于提交的全部节点
|
||||||
|
* uniq去重(保险方案)
|
||||||
*/
|
*/
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getCheckedKeys: () => checkedRealKeys.value,
|
getCheckedKeys: () => uniq(checkedRealKeys.value),
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
@@ -207,7 +207,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
|||||||
const vbenMenuList = backMenuToVbenMenu(backMenuList);
|
const vbenMenuList = backMenuToVbenMenu(backMenuList);
|
||||||
// 特别注意 这里要深拷贝
|
// 特别注意 这里要深拷贝
|
||||||
const menuList = [...cloneDeep(localMenuList), ...vbenMenuList];
|
const menuList = [...cloneDeep(localMenuList), ...vbenMenuList];
|
||||||
console.log('menuList', menuList);
|
// console.log('menuList', menuList);
|
||||||
return menuList;
|
return menuList;
|
||||||
},
|
},
|
||||||
// 可以指定没有权限跳转403页面
|
// 可以指定没有权限跳转403页面
|
||||||
|
@@ -21,6 +21,9 @@ const title = computed(() => {
|
|||||||
const [BasicForm, formApi] = useVbenForm({
|
const [BasicForm, formApi] = useVbenForm({
|
||||||
commonConfig: {
|
commonConfig: {
|
||||||
formItemClass: 'col-span-2',
|
formItemClass: 'col-span-2',
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
layout: 'vertical',
|
layout: 'vertical',
|
||||||
schema: drawerSchema(),
|
schema: drawerSchema(),
|
||||||
|
@@ -134,7 +134,6 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
{
|
{
|
||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
class: 'w-full',
|
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
mode: 'multiple',
|
mode: 'multiple',
|
||||||
optionFilterProp: 'label',
|
optionFilterProp: 'label',
|
||||||
@@ -148,7 +147,6 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
class: 'w-full',
|
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
options: getDictOptions(DictEnum.SYS_DEVICE_TYPE),
|
options: getDictOptions(DictEnum.SYS_DEVICE_TYPE),
|
||||||
},
|
},
|
||||||
|
@@ -99,7 +99,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider1',
|
fieldName: 'divider1',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '基本信息',
|
default: () => '基本信息',
|
||||||
}),
|
}),
|
||||||
@@ -134,7 +134,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider2',
|
fieldName: 'divider2',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '认证信息',
|
default: () => '认证信息',
|
||||||
}),
|
}),
|
||||||
@@ -157,7 +157,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider3',
|
fieldName: 'divider3',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '其他信息',
|
default: () => '其他信息',
|
||||||
}),
|
}),
|
||||||
|
@@ -82,7 +82,6 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
{
|
{
|
||||||
component: 'TreeSelect',
|
component: 'TreeSelect',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
class: 'w-full',
|
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
},
|
},
|
||||||
fieldName: 'deptId',
|
fieldName: 'deptId',
|
||||||
|
@@ -154,12 +154,13 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
fieldName: 'menuIds',
|
fieldName: 'menuIds',
|
||||||
label: '菜单权限',
|
label: '菜单权限',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'Textarea',
|
component: 'Textarea',
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
fieldName: 'remark',
|
fieldName: 'remark',
|
||||||
formItemClass: 'items-baseline',
|
formItemClass: 'items-baseline col-span-2',
|
||||||
label: '备注',
|
label: '备注',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@@ -24,12 +24,12 @@ const [BasicForm, formApi] = useVbenForm({
|
|||||||
componentProps: {
|
componentProps: {
|
||||||
class: 'w-full',
|
class: 'w-full',
|
||||||
},
|
},
|
||||||
formItemClass: 'col-span-2',
|
formItemClass: 'col-span-1',
|
||||||
},
|
},
|
||||||
layout: 'vertical',
|
layout: 'vertical',
|
||||||
schema: drawerSchema(),
|
schema: drawerSchema(),
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
wrapperClass: 'grid-cols-2',
|
wrapperClass: 'grid-cols-2 gap-x-4',
|
||||||
});
|
});
|
||||||
|
|
||||||
const menuTree = ref<any[]>([]);
|
const menuTree = ref<any[]>([]);
|
||||||
|
@@ -101,7 +101,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider1',
|
fieldName: 'divider1',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '基本信息',
|
default: () => '基本信息',
|
||||||
}),
|
}),
|
||||||
@@ -132,7 +132,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider2',
|
fieldName: 'divider2',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '管理员信息',
|
default: () => '管理员信息',
|
||||||
}),
|
}),
|
||||||
@@ -167,7 +167,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider3',
|
fieldName: 'divider3',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '租户设置',
|
default: () => '租户设置',
|
||||||
}),
|
}),
|
||||||
@@ -175,7 +175,6 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
{
|
{
|
||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
class: 'w-full',
|
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
},
|
},
|
||||||
fieldName: 'packageId',
|
fieldName: 'packageId',
|
||||||
@@ -237,7 +236,7 @@ export const drawerSchema: FormSchemaGetter = () => [
|
|||||||
orientation: 'center',
|
orientation: 'center',
|
||||||
},
|
},
|
||||||
fieldName: 'divider4',
|
fieldName: 'divider4',
|
||||||
labelClass: 'w-0',
|
hideLabel: true,
|
||||||
renderComponentContent: () => ({
|
renderComponentContent: () => ({
|
||||||
default: () => '企业信息',
|
default: () => '企业信息',
|
||||||
}),
|
}),
|
||||||
|
@@ -23,6 +23,9 @@ const [BasicForm, formApi] = useVbenForm({
|
|||||||
commonConfig: {
|
commonConfig: {
|
||||||
formItemClass: 'col-span-2',
|
formItemClass: 'col-span-2',
|
||||||
labelWidth: 100,
|
labelWidth: 100,
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
schema: drawerSchema(),
|
schema: drawerSchema(),
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
|
@@ -71,7 +71,7 @@ onMounted(loadTree);
|
|||||||
<div class="bg-background z-100 sticky left-0 top-0 p-[8px]">
|
<div class="bg-background z-100 sticky left-0 top-0 p-[8px]">
|
||||||
<InputSearch
|
<InputSearch
|
||||||
v-model:value="searchValue"
|
v-model:value="searchValue"
|
||||||
placeholder="Search"
|
:placeholder="$t('pages.common.search')"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<template #enterButton>
|
<template #enterButton>
|
||||||
|
@@ -20,6 +20,8 @@ export default defineConfig(async () => {
|
|||||||
// dts: './types/components.d.ts', // 输出类型文件
|
// dts: './types/components.d.ts', // 输出类型文件
|
||||||
// resolvers: [
|
// resolvers: [
|
||||||
// AntDesignVueResolver({
|
// AntDesignVueResolver({
|
||||||
|
// // 需要排除Button组件 全局已经默认导入了
|
||||||
|
// exclude: ['Button'],
|
||||||
// importStyle: false, // css in js
|
// importStyle: false, // css in js
|
||||||
// }),
|
// }),
|
||||||
// ],
|
// ],
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/web-ele",
|
"name": "@vben/web-ele",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"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": {
|
||||||
|
@@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
|||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
ElNotification,
|
ElNotification,
|
||||||
ElRadioGroup,
|
ElRadioGroup,
|
||||||
ElSelect,
|
ElSelect,
|
||||||
|
ElSelectV2,
|
||||||
ElSpace,
|
ElSpace,
|
||||||
ElSwitch,
|
ElSwitch,
|
||||||
ElTimePicker,
|
ElTimePicker,
|
||||||
@@ -41,10 +42,12 @@ const withDefaultPlaceholder = <T extends Component>(
|
|||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
| 'DatePicker'
|
| 'DatePicker'
|
||||||
| 'Divider'
|
| 'Divider'
|
||||||
|
| 'IconPicker'
|
||||||
| 'Input'
|
| 'Input'
|
||||||
| 'InputNumber'
|
| 'InputNumber'
|
||||||
| 'RadioGroup'
|
| 'RadioGroup'
|
||||||
@@ -61,7 +64,19 @@ async function initComponentAdapter() {
|
|||||||
// 如果你的组件体积比较大,可以使用异步加载
|
// 如果你的组件体积比较大,可以使用异步加载
|
||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: ElSelectV2,
|
||||||
|
loadingSlot: 'loading',
|
||||||
|
visibleEvent: 'onDropdownVisibleChange',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
Checkbox: ElCheckbox,
|
Checkbox: ElCheckbox,
|
||||||
CheckboxGroup: ElCheckboxGroup,
|
CheckboxGroup: ElCheckboxGroup,
|
||||||
// 自定义默认按钮
|
// 自定义默认按钮
|
||||||
@@ -73,6 +88,7 @@ async function initComponentAdapter() {
|
|||||||
return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
|
return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
|
||||||
},
|
},
|
||||||
Divider: ElDivider,
|
Divider: ElDivider,
|
||||||
|
IconPicker,
|
||||||
Input: withDefaultPlaceholder(ElInput, 'input'),
|
Input: withDefaultPlaceholder(ElInput, 'input'),
|
||||||
InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
|
InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
|
||||||
RadioGroup: ElRadioGroup,
|
RadioGroup: ElRadioGroup,
|
||||||
|
@@ -7,6 +7,7 @@ import '@vben/styles';
|
|||||||
import '@vben/styles/ele';
|
import '@vben/styles/ele';
|
||||||
|
|
||||||
import { useTitle } from '@vueuse/core';
|
import { useTitle } from '@vueuse/core';
|
||||||
|
import { ElLoading } from 'element-plus';
|
||||||
|
|
||||||
import { $t, setupI18n } from '#/locales';
|
import { $t, setupI18n } from '#/locales';
|
||||||
|
|
||||||
@@ -19,6 +20,9 @@ async function bootstrap(namespace: string) {
|
|||||||
await initComponentAdapter();
|
await initComponentAdapter();
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
// 注册Element Plus提供的v-loading指令
|
||||||
|
app.directive('loading', ElLoading.directive);
|
||||||
|
|
||||||
// 国际化 i18n 配置
|
// 国际化 i18n 配置
|
||||||
await setupI18n(app);
|
await setupI18n(app);
|
||||||
|
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -6,6 +8,7 @@ import {
|
|||||||
ElCard,
|
ElCard,
|
||||||
ElMessage,
|
ElMessage,
|
||||||
ElNotification,
|
ElNotification,
|
||||||
|
ElSegmented,
|
||||||
ElSpace,
|
ElSpace,
|
||||||
ElTable,
|
ElTable,
|
||||||
} from 'element-plus';
|
} from 'element-plus';
|
||||||
@@ -47,6 +50,10 @@ const tableData = [
|
|||||||
{ prop1: '5', prop2: 'E' },
|
{ prop1: '5', prop2: 'E' },
|
||||||
{ prop1: '6', prop2: 'F' },
|
{ prop1: '6', prop2: 'F' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const segmentedValue = ref('Mon');
|
||||||
|
|
||||||
|
const segmentedOptions = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -54,7 +61,8 @@ const tableData = [
|
|||||||
description="支持多语言,主题功能集成切换等"
|
description="支持多语言,主题功能集成切换等"
|
||||||
title="Element Plus组件使用演示"
|
title="Element Plus组件使用演示"
|
||||||
>
|
>
|
||||||
<ElCard class="mb-5">
|
<div class="flex flex-wrap gap-5">
|
||||||
|
<ElCard class="mb-5 w-auto">
|
||||||
<template #header> 按钮 </template>
|
<template #header> 按钮 </template>
|
||||||
<ElSpace>
|
<ElSpace>
|
||||||
<ElButton text>Text</ElButton>
|
<ElButton text>Text</ElButton>
|
||||||
@@ -66,7 +74,7 @@ const tableData = [
|
|||||||
<ElButton type="danger"> Error </ElButton>
|
<ElButton type="danger"> Error </ElButton>
|
||||||
</ElSpace>
|
</ElSpace>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
<ElCard class="mb-5">
|
<ElCard class="mb-5 w-80">
|
||||||
<template #header> Message </template>
|
<template #header> Message </template>
|
||||||
<ElSpace>
|
<ElSpace>
|
||||||
<ElButton type="info" @click="info"> 信息 </ElButton>
|
<ElButton type="info" @click="info"> 信息 </ElButton>
|
||||||
@@ -75,7 +83,7 @@ const tableData = [
|
|||||||
<ElButton type="success" @click="success"> 成功 </ElButton>
|
<ElButton type="success" @click="success"> 成功 </ElButton>
|
||||||
</ElSpace>
|
</ElSpace>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
<ElCard class="mb-5">
|
<ElCard class="mb-5 w-80">
|
||||||
<template #header> Notification </template>
|
<template #header> Notification </template>
|
||||||
<ElSpace>
|
<ElSpace>
|
||||||
<ElButton type="info" @click="notify('info')"> 信息 </ElButton>
|
<ElButton type="info" @click="notify('info')"> 信息 </ElButton>
|
||||||
@@ -84,11 +92,26 @@ const tableData = [
|
|||||||
<ElButton type="success" @click="notify('success')"> 成功 </ElButton>
|
<ElButton type="success" @click="notify('success')"> 成功 </ElButton>
|
||||||
</ElSpace>
|
</ElSpace>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
<ElCard class="mb-5">
|
<ElCard class="mb-5 w-auto">
|
||||||
|
<template #header> Segmented </template>
|
||||||
|
<ElSegmented
|
||||||
|
v-model="segmentedValue"
|
||||||
|
:options="segmentedOptions"
|
||||||
|
size="large"
|
||||||
|
/>
|
||||||
|
</ElCard>
|
||||||
|
<ElCard class="mb-5 w-80">
|
||||||
|
<template #header> V-Loading </template>
|
||||||
|
<div class="flex size-72 items-center justify-center" v-loading="true">
|
||||||
|
一些演示的内容
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
<ElCard class="mb-5 w-80">
|
||||||
<ElTable :data="tableData" stripe>
|
<ElTable :data="tableData" stripe>
|
||||||
<ElTable.TableColumn label="测试列1" prop="prop1" />
|
<ElTable.TableColumn label="测试列1" prop="prop1" />
|
||||||
<ElTable.TableColumn label="测试列2" prop="prop2" />
|
<ElTable.TableColumn label="测试列2" prop="prop2" />
|
||||||
</ElTable>
|
</ElTable>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/web-naive",
|
"name": "@vben/web-naive",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"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": {
|
||||||
|
@@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
|||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -42,10 +42,12 @@ const withDefaultPlaceholder = <T extends Component>(
|
|||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
| 'DatePicker'
|
| 'DatePicker'
|
||||||
| 'Divider'
|
| 'Divider'
|
||||||
|
| 'IconPicker'
|
||||||
| 'Input'
|
| 'Input'
|
||||||
| 'InputNumber'
|
| 'InputNumber'
|
||||||
| 'RadioGroup'
|
| 'RadioGroup'
|
||||||
@@ -63,6 +65,18 @@ async function initComponentAdapter() {
|
|||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: NSelect,
|
||||||
|
modelField: 'value',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
Checkbox: NCheckbox,
|
Checkbox: NCheckbox,
|
||||||
CheckboxGroup: NCheckboxGroup,
|
CheckboxGroup: NCheckboxGroup,
|
||||||
DatePicker: NDatePicker,
|
DatePicker: NDatePicker,
|
||||||
@@ -75,6 +89,7 @@ async function initComponentAdapter() {
|
|||||||
return h(NButton, { ...props, attrs, type: 'primary' }, slots);
|
return h(NButton, { ...props, attrs, type: 'primary' }, slots);
|
||||||
},
|
},
|
||||||
Divider: NDivider,
|
Divider: NDivider,
|
||||||
|
IconPicker,
|
||||||
Input: withDefaultPlaceholder(NInput, 'input'),
|
Input: withDefaultPlaceholder(NInput, 'input'),
|
||||||
InputNumber: withDefaultPlaceholder(NInputNumber, 'input'),
|
InputNumber: withDefaultPlaceholder(NInputNumber, 'input'),
|
||||||
RadioGroup: NRadioGroup,
|
RadioGroup: NRadioGroup,
|
||||||
|
@@ -148,6 +148,16 @@ function sidebarComponents(): DefaultTheme.SidebarItem[] {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
collapsed: false,
|
||||||
|
text: '布局组件',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
link: 'layout-ui/page',
|
||||||
|
text: 'Page 页面',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
text: '通用组件',
|
text: '通用组件',
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/docs",
|
"name": "@vben/docs",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "vitepress build",
|
"build": "vitepress build",
|
||||||
|
@@ -88,6 +88,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
|||||||
| closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
|
| closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
|
||||||
| confirmText | 确认按钮文本 | `string\|slot` | `确认` |
|
| confirmText | 确认按钮文本 | `string\|slot` | `确认` |
|
||||||
| cancelText | 取消按钮文本 | `string\|slot` | `取消` |
|
| cancelText | 取消按钮文本 | `string\|slot` | `取消` |
|
||||||
|
| placement | 抽屉弹出位置 | `'left'\|'right'\|'top'\|'bottom'` | `right` |
|
||||||
| showCancelButton | 显示取消按钮 | `boolean` | `true` |
|
| showCancelButton | 显示取消按钮 | `boolean` | `true` |
|
||||||
| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
|
| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
|
||||||
| class | modal的class,宽度通过这个配置 | `string` | - |
|
| class | modal的class,宽度通过这个配置 | `string` | - |
|
||||||
|
@@ -87,7 +87,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
|||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState } from '@vben/common-ui';
|
import { globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -149,6 +149,7 @@ export type ComponentType =
|
|||||||
| 'TimePicker'
|
| 'TimePicker'
|
||||||
| 'TreeSelect'
|
| 'TreeSelect'
|
||||||
| 'Upload'
|
| 'Upload'
|
||||||
|
| 'IconPicker';
|
||||||
| BaseFormComponentType;
|
| BaseFormComponentType;
|
||||||
|
|
||||||
async function initComponentAdapter() {
|
async function initComponentAdapter() {
|
||||||
@@ -166,6 +167,7 @@ async function initComponentAdapter() {
|
|||||||
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
||||||
},
|
},
|
||||||
Divider,
|
Divider,
|
||||||
|
IconPicker,
|
||||||
Input: withDefaultPlaceholder(Input, 'input'),
|
Input: withDefaultPlaceholder(Input, 'input'),
|
||||||
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
||||||
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
||||||
@@ -419,7 +421,7 @@ export interface FormSchema<
|
|||||||
help?: string;
|
help?: string;
|
||||||
/** 表单项 */
|
/** 表单项 */
|
||||||
label?: string;
|
label?: string;
|
||||||
// 自定义组件内部渲染
|
/** 自定义组件内部渲染 */
|
||||||
renderComponentContent?: RenderComponentContentType;
|
renderComponentContent?: RenderComponentContentType;
|
||||||
/** 字段规则 */
|
/** 字段规则 */
|
||||||
rules?: FormSchemaRuleType;
|
rules?: FormSchemaRuleType;
|
||||||
@@ -500,3 +502,20 @@ import { z } from '#/adapter/form';
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Slots
|
||||||
|
|
||||||
|
可以使用以下插槽在表单中插入自定义的内容
|
||||||
|
|
||||||
|
| 插槽名 | 描述 |
|
||||||
|
| ------------- | ------------------ |
|
||||||
|
| reset-before | 重置按钮之前的位置 |
|
||||||
|
| submit-before | 提交按钮之前的位置 |
|
||||||
|
| expand-before | 展开按钮之前的位置 |
|
||||||
|
| expand-after | 展开按钮之后的位置 |
|
||||||
|
|
||||||
|
::: tip 字段插槽
|
||||||
|
|
||||||
|
除了以上内置插槽之外,`schema`属性中每个字段的`fieldName`都可以作为插槽名称,这些字段插槽的优先级高于`component`定义的组件。也就是说,当提供了与`fieldName`同名的插槽时,这些插槽的内容将会作为这些字段的组件,此时`component`的值将会被忽略。
|
||||||
|
|
||||||
|
:::
|
||||||
|
@@ -93,13 +93,14 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
| modal | 显示遮罩 | `boolean` | `true` |
|
| modal | 显示遮罩 | `boolean` | `true` |
|
||||||
| header | 显示header | `boolean` | `true` |
|
| header | 显示header | `boolean` | `true` |
|
||||||
| footer | 显示footer | `boolean\|slot` | `true` |
|
| footer | 显示footer | `boolean\|slot` | `true` |
|
||||||
|
| confirmDisabled | 禁用确认按钮 | `boolean` | `false` |
|
||||||
| confirmLoading | 确认按钮loading状态 | `boolean` | `false` |
|
| confirmLoading | 确认按钮loading状态 | `boolean` | `false` |
|
||||||
| closeOnClickModal | 点击遮罩关闭弹窗 | `boolean` | `true` |
|
| closeOnClickModal | 点击遮罩关闭弹窗 | `boolean` | `true` |
|
||||||
| closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
|
| closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
|
||||||
| confirmText | 确认按钮文本 | `string\|slot` | `确认` |
|
| confirmText | 确认按钮文本 | `string\|slot` | `确认` |
|
||||||
| cancelText | 取消按钮文本 | `string\|slot` | `取消` |
|
| cancelText | 取消按钮文本 | `string\|slot` | `取消` |
|
||||||
| showCancelButton | 显示取消按钮 | `boolean` | `true` |
|
| showCancelButton | 显示取消按钮 | `boolean` | `true` |
|
||||||
| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
|
| showConfirmButton | 显示确认按钮 | `boolean` | `true` |
|
||||||
| class | modal的class,宽度通过这个配置 | `string` | - |
|
| class | modal的class,宽度通过这个配置 | `string` | - |
|
||||||
| contentClass | modal内容区域的class | `string` | - |
|
| contentClass | modal内容区域的class | `string` | - |
|
||||||
| footerClass | modal底部区域的class | `string` | - |
|
| footerClass | modal底部区域的class | `string` | - |
|
||||||
|
@@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
## 布局组件
|
||||||
|
|
||||||
|
布局组件一般在页面内容区域用作顶层容器组件,提供一些统一的布局样式和基本功能。
|
||||||
|
|
||||||
## 通用组件
|
## 通用组件
|
||||||
|
|
||||||
通用组件是一些常用的组件,比如弹窗、抽屉、表单等。大部分基于 `Tailwind CSS` 实现,可适用于不同 UI 组件库的应用。
|
通用组件是一些常用的组件,比如弹窗、抽屉、表单等。大部分基于 `Tailwind CSS` 实现,可适用于不同 UI 组件库的应用。
|
||||||
|
45
docs/src/components/layout-ui/page.md
Normal file
45
docs/src/components/layout-ui/page.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
outline: deep
|
||||||
|
---
|
||||||
|
|
||||||
|
# Page 常规页面组件
|
||||||
|
|
||||||
|
提供一个常规页面布局的组件,包括头部、内容区域、底部三个部分。
|
||||||
|
|
||||||
|
::: info 写在前面
|
||||||
|
|
||||||
|
本组件是一个基本布局组件。如果有更多的通用页面布局需求(比如双列布局等),可以根据实际需求自行封装。
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 基础用法
|
||||||
|
|
||||||
|
将`Page`作为你的业务页面的根组件即可。
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
| 属性名 | 描述 | 类型 | 默认值 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| title | 页面标题 | `string\|slot` | - |
|
||||||
|
| description | 页面描述(标题下的内容) | `string\|slot` | - |
|
||||||
|
| contentClass | 内容区域的class | `string` | - |
|
||||||
|
| headerClass | 头部区域的class | `string` | - |
|
||||||
|
| footerClass | 底部区域的class | `string` | - |
|
||||||
|
| autoContentHeight | 自动调整内容区域的高度 | `boolean` | `false` |
|
||||||
|
| fixedHeader | 固定头部在页面内容区域顶部,在滚动时保持可见 | `boolean` | `false` |
|
||||||
|
|
||||||
|
::: tip 注意
|
||||||
|
|
||||||
|
如果`title`、`description`、`extra`三者均未提供有效内容(通过`props`或者`slots`均可),则页面头部区域不会渲染。
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
| 插槽名称 | 描述 |
|
||||||
|
| ----------- | ------------ |
|
||||||
|
| default | 页面内容 |
|
||||||
|
| title | 页面标题 |
|
||||||
|
| description | 页面描述 |
|
||||||
|
| extra | 页面头部右侧 |
|
||||||
|
| footer | 页面底部 |
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/commitlint-config",
|
"name": "@vben/commitlint-config",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/stylelint-config",
|
"name": "@vben/stylelint-config",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/node-utils",
|
"name": "@vben/node-utils",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/tailwind-config",
|
"name": "@vben/tailwind-config",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/tsconfig",
|
"name": "@vben/tsconfig",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/vite-config",
|
"name": "@vben/vite-config",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import type { ApplicationPluginOptions } from '../typing';
|
import type { ApplicationPluginOptions } from '../typing';
|
||||||
|
|
||||||
|
import { existsSync } from 'node:fs';
|
||||||
import { join } from 'node:path';
|
import { join } from 'node:path';
|
||||||
|
|
||||||
import { fs } from '@vben/node-utils';
|
import { fs } from '@vben/node-utils';
|
||||||
@@ -21,12 +22,11 @@ function getConfFiles() {
|
|||||||
const script = process.env.npm_lifecycle_script as string;
|
const script = process.env.npm_lifecycle_script as string;
|
||||||
const reg = /--mode ([\d_a-z]+)/;
|
const reg = /--mode ([\d_a-z]+)/;
|
||||||
const result = reg.exec(script);
|
const result = reg.exec(script);
|
||||||
|
let mode = 'production';
|
||||||
if (result) {
|
if (result) {
|
||||||
const mode = result[1];
|
mode = result[1] as string;
|
||||||
return ['.env', `.env.${mode}`];
|
|
||||||
}
|
}
|
||||||
return ['.env', '.env.production'];
|
return ['.env', '.env.local', `.env.${mode}`, `.env.${mode}.local`];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,11 +42,14 @@ async function loadEnv<T = Record<string, string>>(
|
|||||||
|
|
||||||
for (const confFile of confFiles) {
|
for (const confFile of confFiles) {
|
||||||
try {
|
try {
|
||||||
const envPath = await fs.readFile(join(process.cwd(), confFile), {
|
const confFilePath = join(process.cwd(), confFile);
|
||||||
|
if (existsSync(confFilePath)) {
|
||||||
|
const envPath = await fs.readFile(confFilePath, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
});
|
});
|
||||||
const env = dotenv.parse(envPath);
|
const env = dotenv.parse(envPath);
|
||||||
envConfig = { ...envConfig, ...env };
|
envConfig = { ...envConfig, ...env };
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error while parsing ${confFile}`, error);
|
console.error(`Error while parsing ${confFile}`, error);
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vben-admin-monorepo",
|
"name": "vben-admin-monorepo",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"monorepo",
|
"monorepo",
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
"node": ">=20.10.0",
|
"node": ">=20.10.0",
|
||||||
"pnpm": ">=9.12.0"
|
"pnpm": ">=9.12.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@9.14.2",
|
"packageManager": "pnpm@9.14.4",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"peerDependencyRules": {
|
"peerDependencyRules": {
|
||||||
"allowedVersions": {
|
"allowedVersions": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/design",
|
"name": "@vben-core/design",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
".": {
|
".": {
|
||||||
"types": "./src/index.ts",
|
"types": "./src/index.ts",
|
||||||
"development": "./src/index.ts",
|
"development": "./src/index.ts",
|
||||||
"default": "./dist/style.css"
|
"default": "./dist/design.css"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -58,6 +58,8 @@
|
|||||||
|
|
||||||
/* Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc */
|
/* Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc */
|
||||||
--accent: 216 5% 19%;
|
--accent: 216 5% 19%;
|
||||||
|
--accent-dark: 240 0% 22%;
|
||||||
|
--accent-darker: 240 0% 26%;
|
||||||
--accent-lighter: 216 5% 12%;
|
--accent-lighter: 216 5% 12%;
|
||||||
--accent-hover: 216 5% 24%;
|
--accent-hover: 216 5% 24%;
|
||||||
--accent-foreground: 0 0% 98%;
|
--accent-foreground: 0 0% 98%;
|
||||||
|
@@ -58,6 +58,8 @@
|
|||||||
|
|
||||||
/* Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc */
|
/* Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc */
|
||||||
--accent: 240 5% 96%;
|
--accent: 240 5% 96%;
|
||||||
|
--accent-dark: 216 14% 93%;
|
||||||
|
--accent-darker: 216 11% 91%;
|
||||||
--accent-lighter: 240 0% 98%;
|
--accent-lighter: 240 0% 98%;
|
||||||
--accent-hover: 200deg 10% 90%;
|
--accent-hover: 200deg 10% 90%;
|
||||||
--accent-foreground: 240 6% 10%;
|
--accent-foreground: 240 6% 10%;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/icons",
|
"name": "@vben-core/icons",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/shared",
|
"name": "@vben-core/shared",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -86,12 +86,16 @@
|
|||||||
"dayjs": "catalog:",
|
"dayjs": "catalog:",
|
||||||
"defu": "catalog:",
|
"defu": "catalog:",
|
||||||
"lodash.clonedeep": "catalog:",
|
"lodash.clonedeep": "catalog:",
|
||||||
|
"lodash.get": "catalog:",
|
||||||
|
"lodash.isequal": "catalog:",
|
||||||
"nprogress": "catalog:",
|
"nprogress": "catalog:",
|
||||||
"tailwind-merge": "catalog:",
|
"tailwind-merge": "catalog:",
|
||||||
"theme-colors": "catalog:"
|
"theme-colors": "catalog:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash.clonedeep": "catalog:",
|
"@types/lodash.clonedeep": "catalog:",
|
||||||
|
"@types/lodash.get": "catalog:",
|
||||||
|
"@types/lodash.isequal": "catalog:",
|
||||||
"@types/nprogress": "catalog:"
|
"@types/nprogress": "catalog:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,3 +15,5 @@ export * from './update-css-variables';
|
|||||||
export * from './util';
|
export * from './util';
|
||||||
export * from './window';
|
export * from './window';
|
||||||
export { default as cloneDeep } from 'lodash.clonedeep';
|
export { default as cloneDeep } from 'lodash.clonedeep';
|
||||||
|
export { default as get } from 'lodash.get';
|
||||||
|
export { default as isEqual } from 'lodash.isequal';
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/typings",
|
"name": "@vben-core/typings",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/composables",
|
"name": "@vben-core/composables",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/preferences",
|
"name": "@vben-core/preferences",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/form-ui",
|
"name": "@vben-core/form-ui",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -185,7 +185,7 @@ export class FormApi {
|
|||||||
const fieldSet = new Set(fields);
|
const fieldSet = new Set(fields);
|
||||||
const schema = this.state?.schema ?? [];
|
const schema = this.state?.schema ?? [];
|
||||||
|
|
||||||
const filterSchema = schema.filter((item) => fieldSet.has(item.fieldName));
|
const filterSchema = schema.filter((item) => !fieldSet.has(item.fieldName));
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
schema: filterSchema,
|
schema: filterSchema,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/layout-ui",
|
"name": "@vben-core/layout-ui",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -63,7 +63,7 @@ const logoStyle = computed((): CSSProperties => {
|
|||||||
<header
|
<header
|
||||||
:class="theme"
|
:class="theme"
|
||||||
:style="style"
|
:style="style"
|
||||||
class="border-border bg-header top-0 flex w-full flex-[0_0_auto] items-center border-b transition-[margin-top] duration-200"
|
class="border-border bg-header top-0 flex w-full flex-[0_0_auto] items-center border-b pl-2 transition-[margin-top] duration-200"
|
||||||
>
|
>
|
||||||
<div v-if="slots.logo" :style="logoStyle">
|
<div v-if="slots.logo" :style="logoStyle">
|
||||||
<slot name="logo"></slot>
|
<slot name="logo"></slot>
|
||||||
|
@@ -191,7 +191,10 @@ watchEffect(() => {
|
|||||||
function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
||||||
const { extraWidth, fixedExtra, isSidebarMixed, show, width } = props;
|
const { extraWidth, fixedExtra, isSidebarMixed, show, width } = props;
|
||||||
|
|
||||||
let widthValue = `${width + (isSidebarMixed && fixedExtra && extraVisible.value ? extraWidth : 0)}px`;
|
let widthValue =
|
||||||
|
width === 0
|
||||||
|
? '0px'
|
||||||
|
: `${width + (isSidebarMixed && fixedExtra && extraVisible.value ? extraWidth : 0)}px`;
|
||||||
|
|
||||||
const { collapseWidth } = props;
|
const { collapseWidth } = props;
|
||||||
|
|
||||||
|
@@ -192,7 +192,7 @@ const headerFixed = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const showSidebar = computed(() => {
|
const showSidebar = computed(() => {
|
||||||
return isSideMode.value && sidebarEnable.value;
|
return isSideMode.value && sidebarEnable.value && !props.sidebarHidden;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -503,7 +503,7 @@ function handleHeaderToggle() {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
ref="contentRef"
|
ref="contentRef"
|
||||||
class="flex flex-1 flex-col overflow-hidden transition-all duration-300 ease-in"
|
class="flex flex-1 flex-col transition-all duration-300 ease-in"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
@@ -533,7 +533,7 @@ function handleHeaderToggle() {
|
|||||||
<template #toggle-button>
|
<template #toggle-button>
|
||||||
<VbenIconButton
|
<VbenIconButton
|
||||||
v-if="showHeaderToggleButton"
|
v-if="showHeaderToggleButton"
|
||||||
class="my-0 ml-2 mr-1 rounded-md"
|
class="my-0 mr-1 rounded-md"
|
||||||
@click="handleHeaderToggle"
|
@click="handleHeaderToggle"
|
||||||
>
|
>
|
||||||
<Menu class="size-4" />
|
<Menu class="size-4" />
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/menu-ui",
|
"name": "@vben-core/menu-ui",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -41,6 +41,7 @@ export class DrawerApi {
|
|||||||
loading: false,
|
loading: false,
|
||||||
modal: true,
|
modal: true,
|
||||||
openAutoFocus: false,
|
openAutoFocus: false,
|
||||||
|
placement: 'right',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
showConfirmButton: true,
|
showConfirmButton: true,
|
||||||
title: '',
|
title: '',
|
||||||
|
@@ -4,6 +4,8 @@ import type { DrawerApi } from './drawer-api';
|
|||||||
|
|
||||||
import type { Component, Ref } from 'vue';
|
import type { Component, Ref } from 'vue';
|
||||||
|
|
||||||
|
export type DrawerPlacement = 'bottom' | 'left' | 'right' | 'top';
|
||||||
|
|
||||||
export interface DrawerProps {
|
export interface DrawerProps {
|
||||||
/**
|
/**
|
||||||
* 取消按钮文字
|
* 取消按钮文字
|
||||||
@@ -72,6 +74,12 @@ export interface DrawerProps {
|
|||||||
* 是否自动聚焦
|
* 是否自动聚焦
|
||||||
*/
|
*/
|
||||||
openAutoFocus?: boolean;
|
openAutoFocus?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽屉位置
|
||||||
|
* @default right
|
||||||
|
*/
|
||||||
|
placement?: DrawerPlacement;
|
||||||
/**
|
/**
|
||||||
* 是否显示取消按钮
|
* 是否显示取消按钮
|
||||||
* @default true
|
* @default true
|
||||||
|
@@ -62,6 +62,7 @@ const {
|
|||||||
loading: showLoading,
|
loading: showLoading,
|
||||||
modal,
|
modal,
|
||||||
openAutoFocus,
|
openAutoFocus,
|
||||||
|
placement,
|
||||||
showCancelButton,
|
showCancelButton,
|
||||||
showConfirmButton,
|
showConfirmButton,
|
||||||
title,
|
title,
|
||||||
@@ -119,11 +120,13 @@ function handleFocusOutside(e: Event) {
|
|||||||
<SheetContent
|
<SheetContent
|
||||||
:class="
|
:class="
|
||||||
cn('flex w-[520px] flex-col', drawerClass, {
|
cn('flex w-[520px] flex-col', drawerClass, {
|
||||||
'!w-full': isMobile,
|
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
|
||||||
|
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
:modal="modal"
|
:modal="modal"
|
||||||
:open="state?.isOpen"
|
:open="state?.isOpen"
|
||||||
|
:side="placement"
|
||||||
@close-auto-focus="handleFocusOutside"
|
@close-auto-focus="handleFocusOutside"
|
||||||
@escape-key-down="escapeKeyDown"
|
@escape-key-down="escapeKeyDown"
|
||||||
@focus-outside="handleFocusOutside"
|
@focus-outside="handleFocusOutside"
|
||||||
|
@@ -41,6 +41,7 @@ export class ModalApi {
|
|||||||
class: '',
|
class: '',
|
||||||
closeOnClickModal: true,
|
closeOnClickModal: true,
|
||||||
closeOnPressEscape: true,
|
closeOnPressEscape: true,
|
||||||
|
confirmDisabled: false,
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
contentClass: '',
|
contentClass: '',
|
||||||
draggable: false,
|
draggable: false,
|
||||||
|
@@ -35,6 +35,10 @@ export interface ModalProps {
|
|||||||
* @default true
|
* @default true
|
||||||
*/
|
*/
|
||||||
closeOnPressEscape?: boolean;
|
closeOnPressEscape?: boolean;
|
||||||
|
/**
|
||||||
|
* 禁用确认按钮
|
||||||
|
*/
|
||||||
|
confirmDisabled?: boolean;
|
||||||
/**
|
/**
|
||||||
* 确定按钮 loading
|
* 确定按钮 loading
|
||||||
* @default false
|
* @default false
|
||||||
|
@@ -59,6 +59,7 @@ const {
|
|||||||
closable,
|
closable,
|
||||||
closeOnClickModal,
|
closeOnClickModal,
|
||||||
closeOnPressEscape,
|
closeOnPressEscape,
|
||||||
|
confirmDisabled,
|
||||||
confirmLoading,
|
confirmLoading,
|
||||||
confirmText,
|
confirmText,
|
||||||
contentClass,
|
contentClass,
|
||||||
@@ -235,7 +236,7 @@ function handleFocusOutside(e: Event) {
|
|||||||
ref="wrapperRef"
|
ref="wrapperRef"
|
||||||
:class="
|
:class="
|
||||||
cn('relative min-h-40 flex-1 overflow-y-auto p-3', contentClass, {
|
cn('relative min-h-40 flex-1 overflow-y-auto p-3', contentClass, {
|
||||||
'overflow-hidden': showLoading,
|
'pointer-events-none overflow-hidden': showLoading,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
@@ -285,6 +286,7 @@ function handleFocusOutside(e: Event) {
|
|||||||
<component
|
<component
|
||||||
:is="components.PrimaryButton || VbenButton"
|
:is="components.PrimaryButton || VbenButton"
|
||||||
v-if="showConfirmButton"
|
v-if="showConfirmButton"
|
||||||
|
:disabled="confirmDisabled"
|
||||||
:loading="confirmLoading"
|
:loading="confirmLoading"
|
||||||
@click="() => modalApi?.onConfirm()"
|
@click="() => modalApi?.onConfirm()"
|
||||||
>
|
>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/shadcn-ui",
|
"name": "@vben-core/shadcn-ui",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"#main": "./dist/index.mjs",
|
"#main": "./dist/index.mjs",
|
||||||
"#module": "./dist/index.mjs",
|
"#module": "./dist/index.mjs",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben-core/tabs-ui",
|
"name": "@vben-core/tabs-ui",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/constants",
|
"name": "@vben/constants",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/access",
|
"name": "@vben/access",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/common-ui",
|
"name": "@vben/common-ui",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"@vben-core/form-ui": "workspace:*",
|
"@vben-core/form-ui": "workspace:*",
|
||||||
"@vben-core/popup-ui": "workspace:*",
|
"@vben-core/popup-ui": "workspace:*",
|
||||||
|
"@vben-core/preferences": "workspace:*",
|
||||||
"@vben-core/shadcn-ui": "workspace:*",
|
"@vben-core/shadcn-ui": "workspace:*",
|
||||||
"@vben-core/shared": "workspace:*",
|
"@vben-core/shared": "workspace:*",
|
||||||
"@vben/constants": "workspace:*",
|
"@vben/constants": "workspace:*",
|
||||||
|
@@ -0,0 +1,182 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { AnyPromiseFunction } from '@vben/types';
|
||||||
|
|
||||||
|
import { computed, ref, unref, useAttrs, type VNode, watch } from 'vue';
|
||||||
|
|
||||||
|
import { LoaderCircle } from '@vben/icons';
|
||||||
|
import { get, isEqual, isFunction } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
|
import { objectOmit } from '@vueuse/core';
|
||||||
|
|
||||||
|
type OptionsItem = {
|
||||||
|
[name: string]: any;
|
||||||
|
disabled?: boolean;
|
||||||
|
label?: string;
|
||||||
|
value?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
// 组件
|
||||||
|
component: VNode;
|
||||||
|
numberToString?: boolean;
|
||||||
|
api?: (arg?: any) => Promise<OptionsItem[] | Record<string, any>>;
|
||||||
|
params?: Record<string, any>;
|
||||||
|
resultField?: string;
|
||||||
|
labelField?: string;
|
||||||
|
valueField?: string;
|
||||||
|
immediate?: boolean;
|
||||||
|
alwaysLoad?: boolean;
|
||||||
|
beforeFetch?: AnyPromiseFunction<any, any>;
|
||||||
|
afterFetch?: AnyPromiseFunction<any, any>;
|
||||||
|
options?: OptionsItem[];
|
||||||
|
// 尾部插槽
|
||||||
|
loadingSlot?: string;
|
||||||
|
// 可见时触发的事件名
|
||||||
|
visibleEvent?: string;
|
||||||
|
modelField?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({ name: 'ApiSelect', inheritAttrs: false });
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
labelField: 'label',
|
||||||
|
valueField: 'value',
|
||||||
|
resultField: '',
|
||||||
|
visibleEvent: '',
|
||||||
|
numberToString: false,
|
||||||
|
params: () => ({}),
|
||||||
|
immediate: true,
|
||||||
|
alwaysLoad: false,
|
||||||
|
loadingSlot: '',
|
||||||
|
beforeFetch: undefined,
|
||||||
|
afterFetch: undefined,
|
||||||
|
modelField: 'modelValue',
|
||||||
|
api: undefined,
|
||||||
|
options: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
optionsChange: [OptionsItem[]];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const modelValue = defineModel({ default: '' });
|
||||||
|
|
||||||
|
const attrs = useAttrs();
|
||||||
|
|
||||||
|
const refOptions = ref<OptionsItem[]>([]);
|
||||||
|
const loading = ref(false);
|
||||||
|
// 首次是否加载过了
|
||||||
|
const isFirstLoaded = ref(false);
|
||||||
|
|
||||||
|
const getOptions = computed(() => {
|
||||||
|
const { labelField, valueField, numberToString } = props;
|
||||||
|
|
||||||
|
const data: OptionsItem[] = [];
|
||||||
|
const refOptionsData = unref(refOptions);
|
||||||
|
|
||||||
|
for (const next of refOptionsData) {
|
||||||
|
if (next) {
|
||||||
|
const value = get(next, valueField);
|
||||||
|
data.push({
|
||||||
|
...objectOmit(next, [labelField, valueField]),
|
||||||
|
label: get(next, labelField),
|
||||||
|
value: numberToString ? `${value}` : value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.length > 0 ? data : props.options;
|
||||||
|
});
|
||||||
|
|
||||||
|
const bindProps = computed(() => {
|
||||||
|
return {
|
||||||
|
[props.modelField]: unref(modelValue),
|
||||||
|
[`onUpdate:${props.modelField}`]: (val: string) => {
|
||||||
|
modelValue.value = val;
|
||||||
|
},
|
||||||
|
...objectOmit(attrs, ['onUpdate:value']),
|
||||||
|
...(props.visibleEvent
|
||||||
|
? {
|
||||||
|
[props.visibleEvent]: handleFetchForVisible,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fetchApi() {
|
||||||
|
let { api, beforeFetch, afterFetch, params, resultField } = props;
|
||||||
|
|
||||||
|
if (!api || !isFunction(api) || loading.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refOptions.value = [];
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
if (beforeFetch && isFunction(beforeFetch)) {
|
||||||
|
params = (await beforeFetch(params)) || params;
|
||||||
|
}
|
||||||
|
let res = await api(params);
|
||||||
|
if (afterFetch && isFunction(afterFetch)) {
|
||||||
|
res = (await afterFetch(res)) || res;
|
||||||
|
}
|
||||||
|
isFirstLoaded.value = true;
|
||||||
|
if (Array.isArray(res)) {
|
||||||
|
refOptions.value = res;
|
||||||
|
emitChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resultField) {
|
||||||
|
refOptions.value = get(res, resultField) || [];
|
||||||
|
}
|
||||||
|
emitChange();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(error);
|
||||||
|
// reset status
|
||||||
|
isFirstLoaded.value = false;
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleFetchForVisible(visible: boolean) {
|
||||||
|
if (visible) {
|
||||||
|
if (props.alwaysLoad) {
|
||||||
|
await fetchApi();
|
||||||
|
} else if (!props.immediate && !unref(isFirstLoaded)) {
|
||||||
|
await fetchApi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.params,
|
||||||
|
(value, oldValue) => {
|
||||||
|
if (isEqual(value, oldValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchApi();
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: props.immediate },
|
||||||
|
);
|
||||||
|
|
||||||
|
function emitChange() {
|
||||||
|
emit('optionsChange', unref(getOptions));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div v-bind="{ ...$attrs }">
|
||||||
|
<component
|
||||||
|
:is="component"
|
||||||
|
v-bind="bindProps"
|
||||||
|
:options="getOptions"
|
||||||
|
:placeholder="$attrs.placeholder"
|
||||||
|
>
|
||||||
|
<template v-for="item in Object.keys($slots)" #[item]="data">
|
||||||
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
|
</template>
|
||||||
|
<template v-if="loadingSlot && loading" #[loadingSlot]>
|
||||||
|
<LoaderCircle class="animate-spin" />
|
||||||
|
</template>
|
||||||
|
</component>
|
||||||
|
</div>
|
||||||
|
</template>
|
@@ -0,0 +1 @@
|
|||||||
|
export { default as ApiSelect } from './api-select.vue';
|
@@ -1,46 +0,0 @@
|
|||||||
import { mount } from '@vue/test-utils';
|
|
||||||
import { describe, expect, it } from 'vitest';
|
|
||||||
|
|
||||||
import { EllipsisText } from '..';
|
|
||||||
|
|
||||||
describe('ellipsis-text.vue', () => {
|
|
||||||
it('renders the correct content and truncates text', async () => {
|
|
||||||
const wrapper = mount(EllipsisText, {
|
|
||||||
props: {
|
|
||||||
line: 1,
|
|
||||||
title: 'Test Title',
|
|
||||||
},
|
|
||||||
slots: {
|
|
||||||
default: 'This is a very long text that should be truncated.',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(wrapper.text()).toContain('This is a very long text');
|
|
||||||
// 检查 ellipsis 是否应用了正确的 class
|
|
||||||
const ellipsis = wrapper.find('.truncate');
|
|
||||||
expect(ellipsis.exists()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('expands text on click if expand is true', async () => {
|
|
||||||
const wrapper = mount(EllipsisText, {
|
|
||||||
props: {
|
|
||||||
expand: true,
|
|
||||||
line: 1,
|
|
||||||
},
|
|
||||||
slots: {
|
|
||||||
default: 'This is a very long text that should be truncated.',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const ellipsis = wrapper.find('.truncate');
|
|
||||||
|
|
||||||
// 点击 ellipsis,应该触发 expandChange,参数为 false
|
|
||||||
await ellipsis.trigger('click');
|
|
||||||
expect(wrapper.emitted('expandChange')).toBeTruthy();
|
|
||||||
expect(wrapper.emitted('expandChange')?.[0]).toEqual([true]);
|
|
||||||
|
|
||||||
// 再次点击,应该触发 expandChange,参数为 false
|
|
||||||
await ellipsis.trigger('click');
|
|
||||||
expect(wrapper.emitted('expandChange')?.length).toBe(2);
|
|
||||||
expect(wrapper.emitted('expandChange')?.[1]).toEqual([false]);
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,10 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, useTemplateRef, watch, watchEffect } from 'vue';
|
import { computed, ref, watch, watchEffect } from 'vue';
|
||||||
|
|
||||||
import { usePagination } from '@vben/hooks';
|
import { usePagination } from '@vben/hooks';
|
||||||
import { EmptyIcon, Grip } from '@vben/icons';
|
import { EmptyIcon, Grip, listIcons } from '@vben/icons';
|
||||||
|
import { $t } from '@vben/locales';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
Input,
|
||||||
Pagination,
|
Pagination,
|
||||||
PaginationEllipsis,
|
PaginationEllipsis,
|
||||||
PaginationFirst,
|
PaginationFirst,
|
||||||
@@ -18,9 +20,11 @@ import {
|
|||||||
VbenPopover,
|
VbenPopover,
|
||||||
} from '@vben-core/shadcn-ui';
|
} from '@vben-core/shadcn-ui';
|
||||||
|
|
||||||
|
import { refDebounced } from '@vueuse/core';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value?: string;
|
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
|
prefix?: string;
|
||||||
/**
|
/**
|
||||||
* 图标列表
|
* 图标列表
|
||||||
*/
|
*/
|
||||||
@@ -28,48 +32,65 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
value: '',
|
prefix: 'ant-design',
|
||||||
pageSize: 36,
|
pageSize: 36,
|
||||||
icons: () => [],
|
icons: () => [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
change: [string];
|
change: [string];
|
||||||
'update:value': [string];
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const refTrigger = useTemplateRef<HTMLElement>('refTrigger');
|
const modelValue = defineModel({ default: '', type: String });
|
||||||
const currentSelect = ref('');
|
|
||||||
const currentList = ref(props.icons);
|
|
||||||
const currentPage = ref(1);
|
|
||||||
|
|
||||||
watch(
|
const visible = ref(false);
|
||||||
() => props.icons,
|
const currentSelect = ref('');
|
||||||
(newIcons) => {
|
const currentPage = ref(1);
|
||||||
currentList.value = newIcons;
|
const keyword = ref('');
|
||||||
},
|
const keywordDebounce = refDebounced(keyword, 300);
|
||||||
{ immediate: true },
|
const currentList = computed(() => {
|
||||||
);
|
try {
|
||||||
|
if (props.prefix) {
|
||||||
|
const icons = listIcons('', props.prefix);
|
||||||
|
if (icons.length === 0) {
|
||||||
|
console.warn(`No icons found for prefix: ${props.prefix}`);
|
||||||
|
}
|
||||||
|
return icons;
|
||||||
|
} else {
|
||||||
|
return props.icons;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load icons:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const showList = computed(() => {
|
||||||
|
return currentList.value.filter((item) =>
|
||||||
|
item.includes(keywordDebounce.value),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const { paginationList, total, setCurrentPage } = usePagination(
|
const { paginationList, total, setCurrentPage } = usePagination(
|
||||||
currentList,
|
showList,
|
||||||
props.pageSize,
|
props.pageSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
currentSelect.value = props.value;
|
currentSelect.value = modelValue.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => currentSelect.value,
|
() => currentSelect.value,
|
||||||
(v) => {
|
(v) => {
|
||||||
emit('update:value', v);
|
|
||||||
emit('change', v);
|
emit('change', v);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClick = (icon: string) => {
|
const handleClick = (icon: string) => {
|
||||||
currentSelect.value = icon;
|
currentSelect.value = icon;
|
||||||
|
modelValue.value = icon;
|
||||||
|
close();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
@@ -77,22 +98,46 @@ const handlePageChange = (page: number) => {
|
|||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
};
|
};
|
||||||
|
|
||||||
function changeOpenState() {
|
function toggleOpenState() {
|
||||||
refTrigger.value?.click?.();
|
visible.value = !visible.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ changeOpenState });
|
function open() {
|
||||||
|
visible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
visible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ toggleOpenState, open, close });
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VbenPopover
|
<VbenPopover
|
||||||
|
v-model:open="visible"
|
||||||
:content-props="{ align: 'end', alignOffset: -11, sideOffset: 8 }"
|
:content-props="{ align: 'end', alignOffset: -11, sideOffset: 8 }"
|
||||||
content-class="p-0 pt-3"
|
content-class="p-0 pt-3"
|
||||||
>
|
>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div ref="refTrigger">
|
<slot :close="close" :icon="currentSelect" :open="open" name="trigger">
|
||||||
<VbenIcon :icon="currentSelect || Grip" class="size-5" />
|
<div class="flex items-center gap-2">
|
||||||
|
<Input
|
||||||
|
:value="currentSelect"
|
||||||
|
class="flex-1 cursor-pointer"
|
||||||
|
v-bind="$attrs"
|
||||||
|
:placeholder="$t('ui.iconPicker.placeholder')"
|
||||||
|
/>
|
||||||
|
<VbenIcon :icon="currentSelect || Grip" class="size-8" />
|
||||||
</div>
|
</div>
|
||||||
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
|
<div class="mb-2 flex w-full">
|
||||||
|
<Input
|
||||||
|
v-model="keyword"
|
||||||
|
:placeholder="$t('ui.iconPicker.search')"
|
||||||
|
class="mx-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<template v-if="paginationList.length > 0">
|
<template v-if="paginationList.length > 0">
|
||||||
<div class="grid max-h-[360px] w-full grid-cols-6 justify-items-center">
|
<div class="grid max-h-[360px] w-full grid-cols-6 justify-items-center">
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './api-select';
|
||||||
export * from './captcha';
|
export * from './captcha';
|
||||||
export * from './code-mirror';
|
export * from './code-mirror';
|
||||||
export * from './ellipsis-text';
|
export * from './ellipsis-text';
|
||||||
|
@@ -1,5 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onMounted, ref, useTemplateRef } from 'vue';
|
import {
|
||||||
|
computed,
|
||||||
|
nextTick,
|
||||||
|
onMounted,
|
||||||
|
ref,
|
||||||
|
type StyleValue,
|
||||||
|
useTemplateRef,
|
||||||
|
} from 'vue';
|
||||||
|
|
||||||
|
import { preferences } from '@vben-core/preferences';
|
||||||
|
import { cn } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -9,6 +19,10 @@ interface Props {
|
|||||||
* 根据content可见高度自适应
|
* 根据content可见高度自适应
|
||||||
*/
|
*/
|
||||||
autoContentHeight?: boolean;
|
autoContentHeight?: boolean;
|
||||||
|
/** 头部固定 */
|
||||||
|
fixedHeader?: boolean;
|
||||||
|
headerClass?: string;
|
||||||
|
footerClass?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@@ -20,6 +34,7 @@ const {
|
|||||||
description = '',
|
description = '',
|
||||||
autoContentHeight = false,
|
autoContentHeight = false,
|
||||||
title = '',
|
title = '',
|
||||||
|
fixedHeader = false,
|
||||||
} = defineProps<Props>();
|
} = defineProps<Props>();
|
||||||
|
|
||||||
const headerHeight = ref(0);
|
const headerHeight = ref(0);
|
||||||
@@ -29,6 +44,17 @@ const shouldAutoHeight = ref(false);
|
|||||||
const headerRef = useTemplateRef<HTMLDivElement>('headerRef');
|
const headerRef = useTemplateRef<HTMLDivElement>('headerRef');
|
||||||
const footerRef = useTemplateRef<HTMLDivElement>('footerRef');
|
const footerRef = useTemplateRef<HTMLDivElement>('footerRef');
|
||||||
|
|
||||||
|
const headerStyle = computed<StyleValue>(() => {
|
||||||
|
return fixedHeader
|
||||||
|
? {
|
||||||
|
position: 'sticky',
|
||||||
|
zIndex: 200,
|
||||||
|
top:
|
||||||
|
preferences.header.mode === 'fixed' ? 'var(--vben-header-height)' : 0,
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
});
|
||||||
|
|
||||||
const contentStyle = computed(() => {
|
const contentStyle = computed(() => {
|
||||||
if (autoContentHeight) {
|
if (autoContentHeight) {
|
||||||
return {
|
return {
|
||||||
@@ -69,7 +95,16 @@ onMounted(() => {
|
|||||||
$slots.extra
|
$slots.extra
|
||||||
"
|
"
|
||||||
ref="headerRef"
|
ref="headerRef"
|
||||||
class="bg-card relative px-6 py-4"
|
:class="
|
||||||
|
cn(
|
||||||
|
'bg-card relative px-6 py-4',
|
||||||
|
headerClass,
|
||||||
|
fixedHeader
|
||||||
|
? 'border-border border-b transition-all duration-200'
|
||||||
|
: '',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:style="headerStyle"
|
||||||
>
|
>
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<div v-if="title" class="mb-2 flex text-lg font-semibold">
|
<div v-if="title" class="mb-2 flex text-lg font-semibold">
|
||||||
@@ -95,7 +130,12 @@ onMounted(() => {
|
|||||||
<div
|
<div
|
||||||
v-if="$slots.footer"
|
v-if="$slots.footer"
|
||||||
ref="footerRef"
|
ref="footerRef"
|
||||||
class="bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4"
|
:class="
|
||||||
|
cn(
|
||||||
|
footerClass,
|
||||||
|
'bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4',
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/hooks",
|
"name": "@vben/hooks",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -260,6 +260,9 @@ export function useElementPlusDesignTokens() {
|
|||||||
'--el-fill-color-light': getCssVariableValue('--accent'),
|
'--el-fill-color-light': getCssVariableValue('--accent'),
|
||||||
'--el-fill-color-lighter': getCssVariableValue('--accent-lighter'),
|
'--el-fill-color-lighter': getCssVariableValue('--accent-lighter'),
|
||||||
|
|
||||||
|
'--el-fill-color-dark': getCssVariableValue('--accent-dark'),
|
||||||
|
'--el-fill-color-darker': getCssVariableValue('--accent-darker'),
|
||||||
|
|
||||||
// 解决ElLoading背景色问题
|
// 解决ElLoading背景色问题
|
||||||
'--el-mask-color': isDark.value
|
'--el-mask-color': isDark.value
|
||||||
? 'rgba(0,0,0,.8)'
|
? 'rgba(0,0,0,.8)'
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/layouts",
|
"name": "@vben/layouts",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -110,8 +110,17 @@ const {
|
|||||||
sidebarVisible,
|
sidebarVisible,
|
||||||
} = useMixedMenu();
|
} = useMixedMenu();
|
||||||
|
|
||||||
function wrapperMenus(menus: MenuRecordRaw[]) {
|
/**
|
||||||
return mapTree(menus, (item) => {
|
* 包装菜单,翻译菜单名称
|
||||||
|
* @param menus 原始菜单数据
|
||||||
|
* @param deep 是否深度包装。对于双列布局,只需要包装第一层,因为更深层的数据会在扩展菜单中重新包装
|
||||||
|
*/
|
||||||
|
function wrapperMenus(menus: MenuRecordRaw[], deep: boolean = true) {
|
||||||
|
return deep
|
||||||
|
? mapTree(menus, (item) => {
|
||||||
|
return { ...cloneDeep(item), name: $t(item.name) };
|
||||||
|
})
|
||||||
|
: menus.map((item) => {
|
||||||
return { ...cloneDeep(item), name: $t(item.name) };
|
return { ...cloneDeep(item), name: $t(item.name) };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -257,7 +266,7 @@ const headerSlots = computed(() => {
|
|||||||
<template #mixed-menu>
|
<template #mixed-menu>
|
||||||
<LayoutMixedMenu
|
<LayoutMixedMenu
|
||||||
:active-path="extraActiveMenu"
|
:active-path="extraActiveMenu"
|
||||||
:menus="wrapperMenus(headerMenus)"
|
:menus="wrapperMenus(headerMenus, false)"
|
||||||
:rounded="isMenuRounded"
|
:rounded="isMenuRounded"
|
||||||
:theme="sidebarTheme"
|
:theme="sidebarTheme"
|
||||||
@default-select="handleDefaultSelect"
|
@default-select="handleDefaultSelect"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/plugins",
|
"name": "@vben/plugins",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -43,7 +43,11 @@ function extendProxyOption(
|
|||||||
const data = await configFn(
|
const data = await configFn(
|
||||||
params,
|
params,
|
||||||
{
|
{
|
||||||
...customValues,
|
/**
|
||||||
|
* 开启toolbarConfig.refresh功能
|
||||||
|
* 点击刷新按钮 这里的值为PointerEvent 会携带错误参数
|
||||||
|
*/
|
||||||
|
...(customValues instanceof PointerEvent ? {} : customValues),
|
||||||
...formValues,
|
...formValues,
|
||||||
},
|
},
|
||||||
...args,
|
...args,
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
--vxe-ui-loading-background-color: hsl(var(--overlay-content));
|
--vxe-ui-loading-background-color: hsl(var(--overlay-content));
|
||||||
|
|
||||||
/* table */
|
/* table */
|
||||||
--vxe-ui-table-header-background-color: hsl(var(--accent));
|
--vxe-ui-table-header-background-color: hsl(0deg 0% 98%);
|
||||||
--vxe-ui-table-border-color: hsl(var(--border));
|
--vxe-ui-table-border-color: hsl(var(--border));
|
||||||
--vxe-ui-table-row-hover-background-color: hsl(var(--accent-hover));
|
--vxe-ui-table-row-hover-background-color: hsl(var(--accent-hover));
|
||||||
--vxe-ui-table-row-striped-background-color: hsl(var(--accent) / 60%);
|
--vxe-ui-table-row-striped-background-color: hsl(var(--accent) / 60%);
|
||||||
@@ -49,6 +49,10 @@
|
|||||||
/* --vxe-ui-table-fixed-scrolling-box-shadow-color: rgb(0 0 0 / 80%); */
|
/* --vxe-ui-table-fixed-scrolling-box-shadow-color: rgb(0 0 0 / 80%); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[data-vxe-ui-theme='dark'] .vxe-grid {
|
||||||
|
--vxe-ui-table-header-background-color: hsl(var(--accent) / 50%);
|
||||||
|
}
|
||||||
|
|
||||||
.vxe-pager {
|
.vxe-pager {
|
||||||
.vxe-pager--prev-btn:not(.is--disabled):active,
|
.vxe-pager--prev-btn:not(.is--disabled):active,
|
||||||
.vxe-pager--next-btn:not(.is--disabled):active,
|
.vxe-pager--next-btn:not(.is--disabled):active,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/request",
|
"name": "@vben/request",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/icons",
|
"name": "@vben/icons",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/locales",
|
"name": "@vben/locales",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -21,6 +21,10 @@
|
|||||||
"pointAriaLabel": "Click point",
|
"pointAriaLabel": "Click point",
|
||||||
"clickInOrder": "Please click in order"
|
"clickInOrder": "Please click in order"
|
||||||
},
|
},
|
||||||
|
"iconPicker": {
|
||||||
|
"placeholder": "Select an icon",
|
||||||
|
"search": "Search icon..."
|
||||||
|
},
|
||||||
"fallback": {
|
"fallback": {
|
||||||
"pageNotFound": "Oops! Page Not Found",
|
"pageNotFound": "Oops! Page Not Found",
|
||||||
"pageNotFoundDesc": "Sorry, we couldn't find the page you were looking for.",
|
"pageNotFoundDesc": "Sorry, we couldn't find the page you were looking for.",
|
||||||
|
@@ -21,6 +21,10 @@
|
|||||||
"pointAriaLabel": "点击点",
|
"pointAriaLabel": "点击点",
|
||||||
"clickInOrder": "请依次点击"
|
"clickInOrder": "请依次点击"
|
||||||
},
|
},
|
||||||
|
"iconPicker": {
|
||||||
|
"placeholder": "选择一个图标",
|
||||||
|
"search": "搜索图标..."
|
||||||
|
},
|
||||||
"fallback": {
|
"fallback": {
|
||||||
"pageNotFound": "哎呀!未找到页面",
|
"pageNotFound": "哎呀!未找到页面",
|
||||||
"pageNotFoundDesc": "抱歉,我们无法找到您要找的页面。",
|
"pageNotFoundDesc": "抱歉,我们无法找到您要找的页面。",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/preferences",
|
"name": "@vben/preferences",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/stores",
|
"name": "@vben/stores",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/styles",
|
"name": "@vben/styles",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -78,14 +78,6 @@ html {
|
|||||||
--vxe-ui-border-radius: 8px !important;
|
--vxe-ui-border-radius: 8px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
vxe表格头部背景色 与antd保持一致 只需要处理light模式 夜间模式用vxe默认的
|
|
||||||
*/
|
|
||||||
html[data-vxe-ui-theme='light'] {
|
|
||||||
/** 只支持hsl格式 */
|
|
||||||
--vxe-ui-table-header-background-color: hsl(0deg 0% 98%) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
vxe表格loading 只加载表格 不加载上面的表单
|
vxe表格loading 只加载表格 不加载上面的表单
|
||||||
*/
|
*/
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/types",
|
"name": "@vben/types",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/utils",
|
"name": "@vben/utils",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/playground",
|
"name": "@vben/playground",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"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": {
|
||||||
|
@@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
|
|||||||
import type { Component, SetupContext } from 'vue';
|
import type { Component, SetupContext } from 'vue';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { globalShareState } from '@vben/common-ui';
|
import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -48,12 +48,14 @@ const withDefaultPlaceholder = <T extends Component>(
|
|||||||
|
|
||||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||||
export type ComponentType =
|
export type ComponentType =
|
||||||
|
| 'ApiSelect'
|
||||||
| 'AutoComplete'
|
| 'AutoComplete'
|
||||||
| 'Checkbox'
|
| 'Checkbox'
|
||||||
| 'CheckboxGroup'
|
| 'CheckboxGroup'
|
||||||
| 'DatePicker'
|
| 'DatePicker'
|
||||||
| 'DefaultButton'
|
| 'DefaultButton'
|
||||||
| 'Divider'
|
| 'Divider'
|
||||||
|
| 'IconPicker'
|
||||||
| 'Input'
|
| 'Input'
|
||||||
| 'InputNumber'
|
| 'InputNumber'
|
||||||
| 'InputPassword'
|
| 'InputPassword'
|
||||||
@@ -78,6 +80,20 @@ async function initComponentAdapter() {
|
|||||||
// Button: () =>
|
// Button: () =>
|
||||||
// import('xxx').then((res) => res.Button),
|
// import('xxx').then((res) => res.Button),
|
||||||
|
|
||||||
|
ApiSelect: (props, { attrs, slots }) => {
|
||||||
|
return h(
|
||||||
|
ApiSelect,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...attrs,
|
||||||
|
component: Select,
|
||||||
|
loadingSlot: 'suffixIcon',
|
||||||
|
modelField: 'value',
|
||||||
|
visibleEvent: 'onVisibleChange',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
);
|
||||||
|
},
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
CheckboxGroup,
|
CheckboxGroup,
|
||||||
@@ -87,6 +103,7 @@ async function initComponentAdapter() {
|
|||||||
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
return h(Button, { ...props, attrs, type: 'default' }, slots);
|
||||||
},
|
},
|
||||||
Divider,
|
Divider,
|
||||||
|
IconPicker,
|
||||||
Input: withDefaultPlaceholder(Input, 'input'),
|
Input: withDefaultPlaceholder(Input, 'input'),
|
||||||
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
|
||||||
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
|
||||||
|
@@ -79,17 +79,17 @@ async function changeAccount(role: string) {
|
|||||||
|
|
||||||
<Card class="mb-5" title="组件形式控制 - 权限码">
|
<Card class="mb-5" title="组件形式控制 - 权限码">
|
||||||
<AccessControl :codes="['AC_100100']" type="code">
|
<AccessControl :codes="['AC_100100']" type="code">
|
||||||
<Button class="mr-4"> Super 账号可见 ["AC_1000001"] </Button>
|
<Button class="mr-4"> Super 账号可见 ["AC_100100"] </Button>
|
||||||
</AccessControl>
|
</AccessControl>
|
||||||
<AccessControl :codes="['AC_100030']" type="code">
|
<AccessControl :codes="['AC_100030']" type="code">
|
||||||
<Button class="mr-4"> Admin 账号可见 ["AC_100010"] </Button>
|
<Button class="mr-4"> Admin 账号可见 ["AC_100030"] </Button>
|
||||||
</AccessControl>
|
</AccessControl>
|
||||||
<AccessControl :codes="['AC_1000001']" type="code">
|
<AccessControl :codes="['AC_1000001']" type="code">
|
||||||
<Button class="mr-4"> User 账号可见 ["AC_1000001"] </Button>
|
<Button class="mr-4"> User 账号可见 ["AC_1000001"] </Button>
|
||||||
</AccessControl>
|
</AccessControl>
|
||||||
<AccessControl :codes="['AC_100100', 'AC_100010']" type="code">
|
<AccessControl :codes="['AC_100100', 'AC_100030']" type="code">
|
||||||
<Button class="mr-4">
|
<Button class="mr-4">
|
||||||
Super & Admin 账号可见 ["AC_100100","AC_1000001"]
|
Super & Admin 账号可见 ["AC_100100","AC_100030"]
|
||||||
</Button>
|
</Button>
|
||||||
</AccessControl>
|
</AccessControl>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -115,35 +115,35 @@ async function changeAccount(role: string) {
|
|||||||
|
|
||||||
<Card class="mb-5" title="函数形式控制">
|
<Card class="mb-5" title="函数形式控制">
|
||||||
<Button v-if="hasAccessByCodes(['AC_100100'])" class="mr-4">
|
<Button v-if="hasAccessByCodes(['AC_100100'])" class="mr-4">
|
||||||
Super 账号可见 ["AC_1000001"]
|
Super 账号可见 ["AC_100100"]
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-if="hasAccessByCodes(['AC_100030'])" class="mr-4">
|
<Button v-if="hasAccessByCodes(['AC_100030'])" class="mr-4">
|
||||||
Admin 账号可见 ["AC_100010"]
|
Admin 账号可见 ["AC_100030"]
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-if="hasAccessByCodes(['AC_1000001'])" class="mr-4">
|
<Button v-if="hasAccessByCodes(['AC_1000001'])" class="mr-4">
|
||||||
User 账号可见 ["AC_1000001"]
|
User 账号可见 ["AC_1000001"]
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-if="hasAccessByCodes(['AC_100100', 'AC_1000001'])" class="mr-4">
|
<Button v-if="hasAccessByCodes(['AC_100100', 'AC_100030'])" class="mr-4">
|
||||||
Super & Admin 账号可见 ["AC_100100","AC_1000001"]
|
Super & Admin 账号可见 ["AC_100100","AC_100030"]
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card class="mb-5" title="指令方式 - 权限码">
|
<Card class="mb-5" title="指令方式 - 权限码">
|
||||||
<Button class="mr-4" v-access:code="['AC_100100']">
|
<Button class="mr-4" v-access:code="['AC_100100']">
|
||||||
Super 账号可见 ["AC_1000001"]
|
Super 账号可见 ["AC_100100"]
|
||||||
</Button>
|
</Button>
|
||||||
<Button class="mr-4" v-access:code="['AC_100030']">
|
<Button class="mr-4" v-access:code="['AC_100030']">
|
||||||
Admin 账号可见 ["AC_100010"]
|
Admin 账号可见 ["AC_100030"]
|
||||||
</Button>
|
</Button>
|
||||||
<Button class="mr-4" v-access:code="['AC_1000001']">
|
<Button class="mr-4" v-access:code="['AC_1000001']">
|
||||||
User 账号可见 ["AC_1000001"]
|
User 账号可见 ["AC_1000001"]
|
||||||
</Button>
|
</Button>
|
||||||
<Button class="mr-4" v-access:code="['AC_100100', 'AC_1000001']">
|
<Button class="mr-4" v-access:code="['AC_100100', 'AC_100030']">
|
||||||
Super & Admin 账号可见 ["AC_100100","AC_1000001"]
|
Super & Admin 账号可见 ["AC_100100","AC_100030"]
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card class="mb-5" title="指令方式 - 角色">
|
<Card v-if="accessMode === 'frontend'" class="mb-5" title="指令方式 - 角色">
|
||||||
<Button class="mr-4" v-access:role="['super']"> Super 角色可见 </Button>
|
<Button class="mr-4" v-access:role="['super']"> Super 角色可见 </Button>
|
||||||
<Button class="mr-4" v-access:role="['admin']"> Admin 角色可见 </Button>
|
<Button class="mr-4" v-access:role="['admin']"> Admin 角色可见 </Button>
|
||||||
<Button class="mr-4" v-access:role="['user']"> User 角色可见 </Button>
|
<Button class="mr-4" v-access:role="['user']"> User 角色可见 </Button>
|
||||||
|
@@ -1,87 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import { computed, ref } from 'vue';
|
|
||||||
|
|
||||||
import { IconPicker } from '@vben/common-ui';
|
|
||||||
import { listIcons } from '@vben/icons';
|
|
||||||
|
|
||||||
import { Input } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import iconsData from './icons.data';
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
allowClear?: boolean;
|
|
||||||
pageSize?: number;
|
|
||||||
/**
|
|
||||||
* 可以通过prefix获取系统中使用的图标集
|
|
||||||
*/
|
|
||||||
prefix?: string;
|
|
||||||
readonly?: boolean;
|
|
||||||
value?: string;
|
|
||||||
width?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't inherit FormItem disabled、placeholder...
|
|
||||||
defineOptions({
|
|
||||||
inheritAttrs: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
allowClear: true,
|
|
||||||
pageSize: 36,
|
|
||||||
prefix: '',
|
|
||||||
readonly: false,
|
|
||||||
value: '',
|
|
||||||
width: '100%',
|
|
||||||
});
|
|
||||||
|
|
||||||
const refIconPicker = ref();
|
|
||||||
const currentSelect = ref('');
|
|
||||||
|
|
||||||
const currentList = computed(() => {
|
|
||||||
try {
|
|
||||||
if (props.prefix) {
|
|
||||||
const icons = listIcons('', props.prefix);
|
|
||||||
if (icons.length === 0) {
|
|
||||||
console.warn(`No icons found for prefix: ${props.prefix}`);
|
|
||||||
}
|
|
||||||
return icons;
|
|
||||||
} else {
|
|
||||||
const prefix = iconsData.prefix;
|
|
||||||
return iconsData.icons.map((icon) => `${prefix}:${icon}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to load icons:', error);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const triggerPopover = () => {
|
|
||||||
refIconPicker.value?.changeOpenState?.();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (icon: string) => {
|
|
||||||
currentSelect.value = icon;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Input
|
|
||||||
v-model:value="currentSelect"
|
|
||||||
:allow-clear="props.allowClear"
|
|
||||||
:readonly="props.readonly"
|
|
||||||
:style="{ width }"
|
|
||||||
class="cursor-pointer"
|
|
||||||
placeholder="点击选中图标"
|
|
||||||
@click="triggerPopover"
|
|
||||||
>
|
|
||||||
<template #addonAfter>
|
|
||||||
<IconPicker
|
|
||||||
ref="refIconPicker"
|
|
||||||
:icons="currentList"
|
|
||||||
:page-size="pageSize"
|
|
||||||
:value="currentSelect"
|
|
||||||
@change="handleChange"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</Input>
|
|
||||||
</template>
|
|
@@ -1,793 +0,0 @@
|
|||||||
export default {
|
|
||||||
icons: [
|
|
||||||
'account-book-filled',
|
|
||||||
'account-book-outlined',
|
|
||||||
'account-book-twotone',
|
|
||||||
'aim-outlined',
|
|
||||||
'alert-filled',
|
|
||||||
'alert-outlined',
|
|
||||||
'alert-twotone',
|
|
||||||
'alibaba-outlined',
|
|
||||||
'align-center-outlined',
|
|
||||||
'align-left-outlined',
|
|
||||||
'align-right-outlined',
|
|
||||||
'alipay-circle-filled',
|
|
||||||
'alipay-circle-outlined',
|
|
||||||
'alipay-outlined',
|
|
||||||
'alipay-square-filled',
|
|
||||||
'aliwangwang-filled',
|
|
||||||
'aliwangwang-outlined',
|
|
||||||
'aliyun-outlined',
|
|
||||||
'amazon-circle-filled',
|
|
||||||
'amazon-outlined',
|
|
||||||
'amazon-square-filled',
|
|
||||||
'android-filled',
|
|
||||||
'android-outlined',
|
|
||||||
'ant-cloud-outlined',
|
|
||||||
'ant-design-outlined',
|
|
||||||
'apartment-outlined',
|
|
||||||
'api-filled',
|
|
||||||
'api-outlined',
|
|
||||||
'api-twotone',
|
|
||||||
'apple-filled',
|
|
||||||
'apple-outlined',
|
|
||||||
'appstore-add-outlined',
|
|
||||||
'appstore-filled',
|
|
||||||
'appstore-outlined',
|
|
||||||
'appstore-twotone',
|
|
||||||
'area-chart-outlined',
|
|
||||||
'arrow-down-outlined',
|
|
||||||
'arrow-left-outlined',
|
|
||||||
'arrow-right-outlined',
|
|
||||||
'arrow-up-outlined',
|
|
||||||
'arrows-alt-outlined',
|
|
||||||
'audio-filled',
|
|
||||||
'audio-muted-outlined',
|
|
||||||
'audio-outlined',
|
|
||||||
'audio-twotone',
|
|
||||||
'audit-outlined',
|
|
||||||
'backward-filled',
|
|
||||||
'backward-outlined',
|
|
||||||
'bank-filled',
|
|
||||||
'bank-outlined',
|
|
||||||
'bank-twotone',
|
|
||||||
'bar-chart-outlined',
|
|
||||||
'barcode-outlined',
|
|
||||||
'bars-outlined',
|
|
||||||
'behance-circle-filled',
|
|
||||||
'behance-outlined',
|
|
||||||
'behance-square-filled',
|
|
||||||
'behance-square-outlined',
|
|
||||||
'bell-filled',
|
|
||||||
'bell-outlined',
|
|
||||||
'bell-twotone',
|
|
||||||
'bg-colors-outlined',
|
|
||||||
'block-outlined',
|
|
||||||
'bold-outlined',
|
|
||||||
'book-filled',
|
|
||||||
'book-outlined',
|
|
||||||
'book-twotone',
|
|
||||||
'border-bottom-outlined',
|
|
||||||
'border-horizontal-outlined',
|
|
||||||
'border-inner-outlined',
|
|
||||||
'border-left-outlined',
|
|
||||||
'border-outer-outlined',
|
|
||||||
'border-outlined',
|
|
||||||
'border-right-outlined',
|
|
||||||
'border-top-outlined',
|
|
||||||
'border-verticle-outlined',
|
|
||||||
'borderless-table-outlined',
|
|
||||||
'box-plot-filled',
|
|
||||||
'box-plot-outlined',
|
|
||||||
'box-plot-twotone',
|
|
||||||
'branches-outlined',
|
|
||||||
'bug-filled',
|
|
||||||
'bug-outlined',
|
|
||||||
'bug-twotone',
|
|
||||||
'build-filled',
|
|
||||||
'build-outlined',
|
|
||||||
'build-twotone',
|
|
||||||
'bulb-filled',
|
|
||||||
'bulb-outlined',
|
|
||||||
'bulb-twotone',
|
|
||||||
'calculator-filled',
|
|
||||||
'calculator-outlined',
|
|
||||||
'calculator-twotone',
|
|
||||||
'calendar-filled',
|
|
||||||
'calendar-outlined',
|
|
||||||
'calendar-twotone',
|
|
||||||
'camera-filled',
|
|
||||||
'camera-outlined',
|
|
||||||
'camera-twotone',
|
|
||||||
'car-filled',
|
|
||||||
'car-outlined',
|
|
||||||
'car-twotone',
|
|
||||||
'caret-down-filled',
|
|
||||||
'caret-down-outlined',
|
|
||||||
'caret-left-filled',
|
|
||||||
'caret-left-outlined',
|
|
||||||
'caret-right-filled',
|
|
||||||
'caret-right-outlined',
|
|
||||||
'caret-up-filled',
|
|
||||||
'caret-up-outlined',
|
|
||||||
'carry-out-filled',
|
|
||||||
'carry-out-outlined',
|
|
||||||
'carry-out-twotone',
|
|
||||||
'check-circle-filled',
|
|
||||||
'check-circle-outlined',
|
|
||||||
'check-circle-twotone',
|
|
||||||
'check-outlined',
|
|
||||||
'check-square-filled',
|
|
||||||
'check-square-outlined',
|
|
||||||
'check-square-twotone',
|
|
||||||
'chrome-filled',
|
|
||||||
'chrome-outlined',
|
|
||||||
'ci-circle-filled',
|
|
||||||
'ci-circle-outlined',
|
|
||||||
'ci-circle-twotone',
|
|
||||||
'ci-outlined',
|
|
||||||
'ci-twotone',
|
|
||||||
'clear-outlined',
|
|
||||||
'clock-circle-filled',
|
|
||||||
'clock-circle-outlined',
|
|
||||||
'clock-circle-twotone',
|
|
||||||
'close-circle-filled',
|
|
||||||
'close-circle-outlined',
|
|
||||||
'close-circle-twotone',
|
|
||||||
'close-outlined',
|
|
||||||
'close-square-filled',
|
|
||||||
'close-square-outlined',
|
|
||||||
'close-square-twotone',
|
|
||||||
'cloud-download-outlined',
|
|
||||||
'cloud-filled',
|
|
||||||
'cloud-outlined',
|
|
||||||
'cloud-server-outlined',
|
|
||||||
'cloud-sync-outlined',
|
|
||||||
'cloud-twotone',
|
|
||||||
'cloud-upload-outlined',
|
|
||||||
'cluster-outlined',
|
|
||||||
'code-filled',
|
|
||||||
'code-outlined',
|
|
||||||
'code-sandbox-circle-filled',
|
|
||||||
'code-sandbox-outlined',
|
|
||||||
'code-sandbox-square-filled',
|
|
||||||
'code-twotone',
|
|
||||||
'codepen-circle-filled',
|
|
||||||
'codepen-circle-outlined',
|
|
||||||
'codepen-outlined',
|
|
||||||
'codepen-square-filled',
|
|
||||||
'coffee-outlined',
|
|
||||||
'column-height-outlined',
|
|
||||||
'column-width-outlined',
|
|
||||||
'comment-outlined',
|
|
||||||
'compass-filled',
|
|
||||||
'compass-outlined',
|
|
||||||
'compass-twotone',
|
|
||||||
'compress-outlined',
|
|
||||||
'console-sql-outlined',
|
|
||||||
'contacts-filled',
|
|
||||||
'contacts-outlined',
|
|
||||||
'contacts-twotone',
|
|
||||||
'container-filled',
|
|
||||||
'container-outlined',
|
|
||||||
'container-twotone',
|
|
||||||
'control-filled',
|
|
||||||
'control-outlined',
|
|
||||||
'control-twotone',
|
|
||||||
'copy-filled',
|
|
||||||
'copy-outlined',
|
|
||||||
'copy-twotone',
|
|
||||||
'copyright-circle-filled',
|
|
||||||
'copyright-circle-outlined',
|
|
||||||
'copyright-circle-twotone',
|
|
||||||
'copyright-outlined',
|
|
||||||
'copyright-twotone',
|
|
||||||
'credit-card-filled',
|
|
||||||
'credit-card-outlined',
|
|
||||||
'credit-card-twotone',
|
|
||||||
'crown-filled',
|
|
||||||
'crown-outlined',
|
|
||||||
'crown-twotone',
|
|
||||||
'customer-service-filled',
|
|
||||||
'customer-service-outlined',
|
|
||||||
'customer-service-twotone',
|
|
||||||
'dash-outlined',
|
|
||||||
'dashboard-filled',
|
|
||||||
'dashboard-outlined',
|
|
||||||
'dashboard-twotone',
|
|
||||||
'database-filled',
|
|
||||||
'database-outlined',
|
|
||||||
'database-twotone',
|
|
||||||
'delete-column-outlined',
|
|
||||||
'delete-filled',
|
|
||||||
'delete-outlined',
|
|
||||||
'delete-row-outlined',
|
|
||||||
'delete-twotone',
|
|
||||||
'delivered-procedure-outlined',
|
|
||||||
'deployment-unit-outlined',
|
|
||||||
'desktop-outlined',
|
|
||||||
'diff-filled',
|
|
||||||
'diff-outlined',
|
|
||||||
'diff-twotone',
|
|
||||||
'dingding-outlined',
|
|
||||||
'dingtalk-circle-filled',
|
|
||||||
'dingtalk-outlined',
|
|
||||||
'dingtalk-square-filled',
|
|
||||||
'disconnect-outlined',
|
|
||||||
'dislike-filled',
|
|
||||||
'dislike-outlined',
|
|
||||||
'dislike-twotone',
|
|
||||||
'dollar-circle-filled',
|
|
||||||
'dollar-circle-outlined',
|
|
||||||
'dollar-circle-twotone',
|
|
||||||
'dollar-outlined',
|
|
||||||
'dollar-twotone',
|
|
||||||
'dot-chart-outlined',
|
|
||||||
'double-left-outlined',
|
|
||||||
'double-right-outlined',
|
|
||||||
'down-circle-filled',
|
|
||||||
'down-circle-outlined',
|
|
||||||
'down-circle-twotone',
|
|
||||||
'down-outlined',
|
|
||||||
'down-square-filled',
|
|
||||||
'down-square-outlined',
|
|
||||||
'down-square-twotone',
|
|
||||||
'download-outlined',
|
|
||||||
'drag-outlined',
|
|
||||||
'dribbble-circle-filled',
|
|
||||||
'dribbble-outlined',
|
|
||||||
'dribbble-square-filled',
|
|
||||||
'dribbble-square-outlined',
|
|
||||||
'dropbox-circle-filled',
|
|
||||||
'dropbox-outlined',
|
|
||||||
'dropbox-square-filled',
|
|
||||||
'edit-filled',
|
|
||||||
'edit-outlined',
|
|
||||||
'edit-twotone',
|
|
||||||
'ellipsis-outlined',
|
|
||||||
'enter-outlined',
|
|
||||||
'environment-filled',
|
|
||||||
'environment-outlined',
|
|
||||||
'environment-twotone',
|
|
||||||
'euro-circle-filled',
|
|
||||||
'euro-circle-outlined',
|
|
||||||
'euro-circle-twotone',
|
|
||||||
'euro-outlined',
|
|
||||||
'euro-twotone',
|
|
||||||
'exception-outlined',
|
|
||||||
'exclamation-circle-filled',
|
|
||||||
'exclamation-circle-outlined',
|
|
||||||
'exclamation-circle-twotone',
|
|
||||||
'exclamation-outlined',
|
|
||||||
'expand-alt-outlined',
|
|
||||||
'expand-outlined',
|
|
||||||
'experiment-filled',
|
|
||||||
'experiment-outlined',
|
|
||||||
'experiment-twotone',
|
|
||||||
'export-outlined',
|
|
||||||
'eye-filled',
|
|
||||||
'eye-invisible-filled',
|
|
||||||
'eye-invisible-outlined',
|
|
||||||
'eye-invisible-twotone',
|
|
||||||
'eye-outlined',
|
|
||||||
'eye-twotone',
|
|
||||||
'facebook-filled',
|
|
||||||
'facebook-outlined',
|
|
||||||
'fall-outlined',
|
|
||||||
'fast-backward-filled',
|
|
||||||
'fast-backward-outlined',
|
|
||||||
'fast-forward-filled',
|
|
||||||
'fast-forward-outlined',
|
|
||||||
'field-binary-outlined',
|
|
||||||
'field-number-outlined',
|
|
||||||
'field-string-outlined',
|
|
||||||
'field-time-outlined',
|
|
||||||
'file-add-filled',
|
|
||||||
'file-add-outlined',
|
|
||||||
'file-add-twotone',
|
|
||||||
'file-done-outlined',
|
|
||||||
'file-excel-filled',
|
|
||||||
'file-excel-outlined',
|
|
||||||
'file-excel-twotone',
|
|
||||||
'file-exclamation-filled',
|
|
||||||
'file-exclamation-outlined',
|
|
||||||
'file-exclamation-twotone',
|
|
||||||
'file-filled',
|
|
||||||
'file-gif-outlined',
|
|
||||||
'file-image-filled',
|
|
||||||
'file-image-outlined',
|
|
||||||
'file-image-twotone',
|
|
||||||
'file-jpg-outlined',
|
|
||||||
'file-markdown-filled',
|
|
||||||
'file-markdown-outlined',
|
|
||||||
'file-markdown-twotone',
|
|
||||||
'file-outlined',
|
|
||||||
'file-pdf-filled',
|
|
||||||
'file-pdf-outlined',
|
|
||||||
'file-pdf-twotone',
|
|
||||||
'file-ppt-filled',
|
|
||||||
'file-ppt-outlined',
|
|
||||||
'file-ppt-twotone',
|
|
||||||
'file-protect-outlined',
|
|
||||||
'file-search-outlined',
|
|
||||||
'file-sync-outlined',
|
|
||||||
'file-text-filled',
|
|
||||||
'file-text-outlined',
|
|
||||||
'file-text-twotone',
|
|
||||||
'file-twotone',
|
|
||||||
'file-unknown-filled',
|
|
||||||
'file-unknown-outlined',
|
|
||||||
'file-unknown-twotone',
|
|
||||||
'file-word-filled',
|
|
||||||
'file-word-outlined',
|
|
||||||
'file-word-twotone',
|
|
||||||
'file-zip-filled',
|
|
||||||
'file-zip-outlined',
|
|
||||||
'file-zip-twotone',
|
|
||||||
'filter-filled',
|
|
||||||
'filter-outlined',
|
|
||||||
'filter-twotone',
|
|
||||||
'fire-filled',
|
|
||||||
'fire-outlined',
|
|
||||||
'fire-twotone',
|
|
||||||
'flag-filled',
|
|
||||||
'flag-outlined',
|
|
||||||
'flag-twotone',
|
|
||||||
'folder-add-filled',
|
|
||||||
'folder-add-outlined',
|
|
||||||
'folder-add-twotone',
|
|
||||||
'folder-filled',
|
|
||||||
'folder-open-filled',
|
|
||||||
'folder-open-outlined',
|
|
||||||
'folder-open-twotone',
|
|
||||||
'folder-outlined',
|
|
||||||
'folder-twotone',
|
|
||||||
'folder-view-outlined',
|
|
||||||
'font-colors-outlined',
|
|
||||||
'font-size-outlined',
|
|
||||||
'fork-outlined',
|
|
||||||
'form-outlined',
|
|
||||||
'format-painter-filled',
|
|
||||||
'format-painter-outlined',
|
|
||||||
'forward-filled',
|
|
||||||
'forward-outlined',
|
|
||||||
'frown-filled',
|
|
||||||
'frown-outlined',
|
|
||||||
'frown-twotone',
|
|
||||||
'fullscreen-exit-outlined',
|
|
||||||
'fullscreen-outlined',
|
|
||||||
'function-outlined',
|
|
||||||
'fund-filled',
|
|
||||||
'fund-outlined',
|
|
||||||
'fund-projection-screen-outlined',
|
|
||||||
'fund-twotone',
|
|
||||||
'fund-view-outlined',
|
|
||||||
'funnel-plot-filled',
|
|
||||||
'funnel-plot-outlined',
|
|
||||||
'funnel-plot-twotone',
|
|
||||||
'gateway-outlined',
|
|
||||||
'gif-outlined',
|
|
||||||
'gift-filled',
|
|
||||||
'gift-outlined',
|
|
||||||
'gift-twotone',
|
|
||||||
'github-filled',
|
|
||||||
'github-outlined',
|
|
||||||
'gitlab-filled',
|
|
||||||
'gitlab-outlined',
|
|
||||||
'global-outlined',
|
|
||||||
'gold-filled',
|
|
||||||
'gold-outlined',
|
|
||||||
'gold-twotone',
|
|
||||||
'golden-filled',
|
|
||||||
'google-circle-filled',
|
|
||||||
'google-outlined',
|
|
||||||
'google-plus-circle-filled',
|
|
||||||
'google-plus-outlined',
|
|
||||||
'google-plus-square-filled',
|
|
||||||
'google-square-filled',
|
|
||||||
'group-outlined',
|
|
||||||
'hdd-filled',
|
|
||||||
'hdd-outlined',
|
|
||||||
'hdd-twotone',
|
|
||||||
'heart-filled',
|
|
||||||
'heart-outlined',
|
|
||||||
'heart-twotone',
|
|
||||||
'heat-map-outlined',
|
|
||||||
'highlight-filled',
|
|
||||||
'highlight-outlined',
|
|
||||||
'highlight-twotone',
|
|
||||||
'history-outlined',
|
|
||||||
'home-filled',
|
|
||||||
'home-outlined',
|
|
||||||
'home-twotone',
|
|
||||||
'hourglass-filled',
|
|
||||||
'hourglass-outlined',
|
|
||||||
'hourglass-twotone',
|
|
||||||
'html5-filled',
|
|
||||||
'html5-outlined',
|
|
||||||
'html5-twotone',
|
|
||||||
'idcard-filled',
|
|
||||||
'idcard-outlined',
|
|
||||||
'idcard-twotone',
|
|
||||||
'ie-circle-filled',
|
|
||||||
'ie-outlined',
|
|
||||||
'ie-square-filled',
|
|
||||||
'import-outlined',
|
|
||||||
'inbox-outlined',
|
|
||||||
'info-circle-filled',
|
|
||||||
'info-circle-outlined',
|
|
||||||
'info-circle-twotone',
|
|
||||||
'info-outlined',
|
|
||||||
'insert-row-above-outlined',
|
|
||||||
'insert-row-below-outlined',
|
|
||||||
'insert-row-left-outlined',
|
|
||||||
'insert-row-right-outlined',
|
|
||||||
'instagram-filled',
|
|
||||||
'instagram-outlined',
|
|
||||||
'insurance-filled',
|
|
||||||
'insurance-outlined',
|
|
||||||
'insurance-twotone',
|
|
||||||
'interaction-filled',
|
|
||||||
'interaction-outlined',
|
|
||||||
'interaction-twotone',
|
|
||||||
'issues-close-outlined',
|
|
||||||
'italic-outlined',
|
|
||||||
'key-outlined',
|
|
||||||
'laptop-outlined',
|
|
||||||
'layout-filled',
|
|
||||||
'layout-outlined',
|
|
||||||
'layout-twotone',
|
|
||||||
'left-circle-filled',
|
|
||||||
'left-circle-outlined',
|
|
||||||
'left-circle-twotone',
|
|
||||||
'left-outlined',
|
|
||||||
'left-square-filled',
|
|
||||||
'left-square-outlined',
|
|
||||||
'left-square-twotone',
|
|
||||||
'like-filled',
|
|
||||||
'like-outlined',
|
|
||||||
'like-twotone',
|
|
||||||
'line-chart-outlined',
|
|
||||||
'line-height-outlined',
|
|
||||||
'line-outlined',
|
|
||||||
'link-outlined',
|
|
||||||
'linkedin-filled',
|
|
||||||
'linkedin-outlined',
|
|
||||||
'loading-3-quarters-outlined',
|
|
||||||
'loading-outlined',
|
|
||||||
'lock-filled',
|
|
||||||
'lock-outlined',
|
|
||||||
'lock-twotone',
|
|
||||||
'login-outlined',
|
|
||||||
'logout-outlined',
|
|
||||||
'mac-command-filled',
|
|
||||||
'mac-command-outlined',
|
|
||||||
'mail-filled',
|
|
||||||
'mail-outlined',
|
|
||||||
'mail-twotone',
|
|
||||||
'man-outlined',
|
|
||||||
'medicine-box-filled',
|
|
||||||
'medicine-box-outlined',
|
|
||||||
'medicine-box-twotone',
|
|
||||||
'medium-circle-filled',
|
|
||||||
'medium-outlined',
|
|
||||||
'medium-square-filled',
|
|
||||||
'medium-workmark-outlined',
|
|
||||||
'meh-filled',
|
|
||||||
'meh-outlined',
|
|
||||||
'meh-twotone',
|
|
||||||
'menu-fold-outlined',
|
|
||||||
'menu-outlined',
|
|
||||||
'menu-unfold-outlined',
|
|
||||||
'merge-cells-outlined',
|
|
||||||
'message-filled',
|
|
||||||
'message-outlined',
|
|
||||||
'message-twotone',
|
|
||||||
'minus-circle-filled',
|
|
||||||
'minus-circle-outlined',
|
|
||||||
'minus-circle-twotone',
|
|
||||||
'minus-outlined',
|
|
||||||
'minus-square-filled',
|
|
||||||
'minus-square-outlined',
|
|
||||||
'minus-square-twotone',
|
|
||||||
'mobile-filled',
|
|
||||||
'mobile-outlined',
|
|
||||||
'mobile-twotone',
|
|
||||||
'money-collect-filled',
|
|
||||||
'money-collect-outlined',
|
|
||||||
'money-collect-twotone',
|
|
||||||
'monitor-outlined',
|
|
||||||
'more-outlined',
|
|
||||||
'node-collapse-outlined',
|
|
||||||
'node-expand-outlined',
|
|
||||||
'node-index-outlined',
|
|
||||||
'notification-filled',
|
|
||||||
'notification-outlined',
|
|
||||||
'notification-twotone',
|
|
||||||
'number-outlined',
|
|
||||||
'one-to-one-outlined',
|
|
||||||
'ordered-list-outlined',
|
|
||||||
'paper-clip-outlined',
|
|
||||||
'partition-outlined',
|
|
||||||
'pause-circle-filled',
|
|
||||||
'pause-circle-outlined',
|
|
||||||
'pause-circle-twotone',
|
|
||||||
'pause-outlined',
|
|
||||||
'pay-circle-filled',
|
|
||||||
'pay-circle-outlined',
|
|
||||||
'percentage-outlined',
|
|
||||||
'phone-filled',
|
|
||||||
'phone-outlined',
|
|
||||||
'phone-twotone',
|
|
||||||
'pic-center-outlined',
|
|
||||||
'pic-left-outlined',
|
|
||||||
'pic-right-outlined',
|
|
||||||
'picture-filled',
|
|
||||||
'picture-outlined',
|
|
||||||
'picture-twotone',
|
|
||||||
'pie-chart-filled',
|
|
||||||
'pie-chart-outlined',
|
|
||||||
'pie-chart-twotone',
|
|
||||||
'play-circle-filled',
|
|
||||||
'play-circle-outlined',
|
|
||||||
'play-circle-twotone',
|
|
||||||
'play-square-filled',
|
|
||||||
'play-square-outlined',
|
|
||||||
'play-square-twotone',
|
|
||||||
'plus-circle-filled',
|
|
||||||
'plus-circle-outlined',
|
|
||||||
'plus-circle-twotone',
|
|
||||||
'plus-outlined',
|
|
||||||
'plus-square-filled',
|
|
||||||
'plus-square-outlined',
|
|
||||||
'plus-square-twotone',
|
|
||||||
'pound-circle-filled',
|
|
||||||
'pound-circle-outlined',
|
|
||||||
'pound-circle-twotone',
|
|
||||||
'pound-outlined',
|
|
||||||
'poweroff-outlined',
|
|
||||||
'printer-filled',
|
|
||||||
'printer-outlined',
|
|
||||||
'printer-twotone',
|
|
||||||
'profile-filled',
|
|
||||||
'profile-outlined',
|
|
||||||
'profile-twotone',
|
|
||||||
'project-filled',
|
|
||||||
'project-outlined',
|
|
||||||
'project-twotone',
|
|
||||||
'property-safety-filled',
|
|
||||||
'property-safety-outlined',
|
|
||||||
'property-safety-twotone',
|
|
||||||
'pull-request-outlined',
|
|
||||||
'pushpin-filled',
|
|
||||||
'pushpin-outlined',
|
|
||||||
'pushpin-twotone',
|
|
||||||
'qq-circle-filled',
|
|
||||||
'qq-outlined',
|
|
||||||
'qq-square-filled',
|
|
||||||
'qrcode-outlined',
|
|
||||||
'question-circle-filled',
|
|
||||||
'question-circle-outlined',
|
|
||||||
'question-circle-twotone',
|
|
||||||
'question-outlined',
|
|
||||||
'radar-chart-outlined',
|
|
||||||
'radius-bottomleft-outlined',
|
|
||||||
'radius-bottomright-outlined',
|
|
||||||
'radius-setting-outlined',
|
|
||||||
'radius-upleft-outlined',
|
|
||||||
'radius-upright-outlined',
|
|
||||||
'read-filled',
|
|
||||||
'read-outlined',
|
|
||||||
'reconciliation-filled',
|
|
||||||
'reconciliation-outlined',
|
|
||||||
'reconciliation-twotone',
|
|
||||||
'red-envelope-filled',
|
|
||||||
'red-envelope-outlined',
|
|
||||||
'red-envelope-twotone',
|
|
||||||
'reddit-circle-filled',
|
|
||||||
'reddit-outlined',
|
|
||||||
'reddit-square-filled',
|
|
||||||
'redo-outlined',
|
|
||||||
'reload-outlined',
|
|
||||||
'rest-filled',
|
|
||||||
'rest-outlined',
|
|
||||||
'rest-twotone',
|
|
||||||
'retweet-outlined',
|
|
||||||
'right-circle-filled',
|
|
||||||
'right-circle-outlined',
|
|
||||||
'right-circle-twotone',
|
|
||||||
'right-outlined',
|
|
||||||
'right-square-filled',
|
|
||||||
'right-square-outlined',
|
|
||||||
'right-square-twotone',
|
|
||||||
'rise-outlined',
|
|
||||||
'robot-filled',
|
|
||||||
'robot-outlined',
|
|
||||||
'rocket-filled',
|
|
||||||
'rocket-outlined',
|
|
||||||
'rocket-twotone',
|
|
||||||
'rollback-outlined',
|
|
||||||
'rotate-left-outlined',
|
|
||||||
'rotate-right-outlined',
|
|
||||||
'safety-certificate-filled',
|
|
||||||
'safety-certificate-outlined',
|
|
||||||
'safety-certificate-twotone',
|
|
||||||
'safety-outlined',
|
|
||||||
'save-filled',
|
|
||||||
'save-outlined',
|
|
||||||
'save-twotone',
|
|
||||||
'scan-outlined',
|
|
||||||
'schedule-filled',
|
|
||||||
'schedule-outlined',
|
|
||||||
'schedule-twotone',
|
|
||||||
'scissor-outlined',
|
|
||||||
'search-outlined',
|
|
||||||
'security-scan-filled',
|
|
||||||
'security-scan-outlined',
|
|
||||||
'security-scan-twotone',
|
|
||||||
'select-outlined',
|
|
||||||
'send-outlined',
|
|
||||||
'setting-filled',
|
|
||||||
'setting-outlined',
|
|
||||||
'setting-twotone',
|
|
||||||
'shake-outlined',
|
|
||||||
'share-alt-outlined',
|
|
||||||
'shop-filled',
|
|
||||||
'shop-outlined',
|
|
||||||
'shop-twotone',
|
|
||||||
'shopping-cart-outlined',
|
|
||||||
'shopping-filled',
|
|
||||||
'shopping-outlined',
|
|
||||||
'shopping-twotone',
|
|
||||||
'shrink-outlined',
|
|
||||||
'signal-filled',
|
|
||||||
'sisternode-outlined',
|
|
||||||
'sketch-circle-filled',
|
|
||||||
'sketch-outlined',
|
|
||||||
'sketch-square-filled',
|
|
||||||
'skin-filled',
|
|
||||||
'skin-outlined',
|
|
||||||
'skin-twotone',
|
|
||||||
'skype-filled',
|
|
||||||
'skype-outlined',
|
|
||||||
'slack-circle-filled',
|
|
||||||
'slack-outlined',
|
|
||||||
'slack-square-filled',
|
|
||||||
'slack-square-outlined',
|
|
||||||
'sliders-filled',
|
|
||||||
'sliders-outlined',
|
|
||||||
'sliders-twotone',
|
|
||||||
'small-dash-outlined',
|
|
||||||
'smile-filled',
|
|
||||||
'smile-outlined',
|
|
||||||
'smile-twotone',
|
|
||||||
'snippets-filled',
|
|
||||||
'snippets-outlined',
|
|
||||||
'snippets-twotone',
|
|
||||||
'solution-outlined',
|
|
||||||
'sort-ascending-outlined',
|
|
||||||
'sort-descending-outlined',
|
|
||||||
'sound-filled',
|
|
||||||
'sound-outlined',
|
|
||||||
'sound-twotone',
|
|
||||||
'split-cells-outlined',
|
|
||||||
'star-filled',
|
|
||||||
'star-outlined',
|
|
||||||
'star-twotone',
|
|
||||||
'step-backward-filled',
|
|
||||||
'step-backward-outlined',
|
|
||||||
'step-forward-filled',
|
|
||||||
'step-forward-outlined',
|
|
||||||
'stock-outlined',
|
|
||||||
'stop-filled',
|
|
||||||
'stop-outlined',
|
|
||||||
'stop-twotone',
|
|
||||||
'strikethrough-outlined',
|
|
||||||
'subnode-outlined',
|
|
||||||
'swap-left-outlined',
|
|
||||||
'swap-outlined',
|
|
||||||
'swap-right-outlined',
|
|
||||||
'switcher-filled',
|
|
||||||
'switcher-outlined',
|
|
||||||
'switcher-twotone',
|
|
||||||
'sync-outlined',
|
|
||||||
'table-outlined',
|
|
||||||
'tablet-filled',
|
|
||||||
'tablet-outlined',
|
|
||||||
'tablet-twotone',
|
|
||||||
'tag-filled',
|
|
||||||
'tag-outlined',
|
|
||||||
'tag-twotone',
|
|
||||||
'tags-filled',
|
|
||||||
'tags-outlined',
|
|
||||||
'tags-twotone',
|
|
||||||
'taobao-circle-filled',
|
|
||||||
'taobao-circle-outlined',
|
|
||||||
'taobao-outlined',
|
|
||||||
'taobao-square-filled',
|
|
||||||
'team-outlined',
|
|
||||||
'thunderbolt-filled',
|
|
||||||
'thunderbolt-outlined',
|
|
||||||
'thunderbolt-twotone',
|
|
||||||
'to-top-outlined',
|
|
||||||
'tool-filled',
|
|
||||||
'tool-outlined',
|
|
||||||
'tool-twotone',
|
|
||||||
'trademark-circle-filled',
|
|
||||||
'trademark-circle-outlined',
|
|
||||||
'trademark-circle-twotone',
|
|
||||||
'trademark-outlined',
|
|
||||||
'transaction-outlined',
|
|
||||||
'translation-outlined',
|
|
||||||
'trophy-filled',
|
|
||||||
'trophy-outlined',
|
|
||||||
'trophy-twotone',
|
|
||||||
'twitter-circle-filled',
|
|
||||||
'twitter-outlined',
|
|
||||||
'twitter-square-filled',
|
|
||||||
'underline-outlined',
|
|
||||||
'undo-outlined',
|
|
||||||
'ungroup-outlined',
|
|
||||||
'unlock-filled',
|
|
||||||
'unlock-outlined',
|
|
||||||
'unlock-twotone',
|
|
||||||
'unordered-list-outlined',
|
|
||||||
'up-circle-filled',
|
|
||||||
'up-circle-outlined',
|
|
||||||
'up-circle-twotone',
|
|
||||||
'up-outlined',
|
|
||||||
'up-square-filled',
|
|
||||||
'up-square-outlined',
|
|
||||||
'up-square-twotone',
|
|
||||||
'upload-outlined',
|
|
||||||
'usb-filled',
|
|
||||||
'usb-outlined',
|
|
||||||
'usb-twotone',
|
|
||||||
'user-add-outlined',
|
|
||||||
'user-delete-outlined',
|
|
||||||
'user-outlined',
|
|
||||||
'user-switch-outlined',
|
|
||||||
'usergroup-add-outlined',
|
|
||||||
'usergroup-delete-outlined',
|
|
||||||
'verified-outlined',
|
|
||||||
'vertical-align-bottom-outlined',
|
|
||||||
'vertical-align-middle-outlined',
|
|
||||||
'vertical-align-top-outlined',
|
|
||||||
'vertical-left-outlined',
|
|
||||||
'vertical-right-outlined',
|
|
||||||
'video-camera-add-outlined',
|
|
||||||
'video-camera-filled',
|
|
||||||
'video-camera-outlined',
|
|
||||||
'video-camera-twotone',
|
|
||||||
'wallet-filled',
|
|
||||||
'wallet-outlined',
|
|
||||||
'wallet-twotone',
|
|
||||||
'warning-filled',
|
|
||||||
'warning-outlined',
|
|
||||||
'warning-twotone',
|
|
||||||
'wechat-filled',
|
|
||||||
'wechat-outlined',
|
|
||||||
'weibo-circle-filled',
|
|
||||||
'weibo-circle-outlined',
|
|
||||||
'weibo-outlined',
|
|
||||||
'weibo-square-filled',
|
|
||||||
'weibo-square-outlined',
|
|
||||||
'whats-app-outlined',
|
|
||||||
'wifi-outlined',
|
|
||||||
'windows-filled',
|
|
||||||
'windows-outlined',
|
|
||||||
'woman-outlined',
|
|
||||||
'yahoo-filled',
|
|
||||||
'yahoo-outlined',
|
|
||||||
'youtube-filled',
|
|
||||||
'youtube-outlined',
|
|
||||||
'yuque-filled',
|
|
||||||
'yuque-outlined',
|
|
||||||
'zhihu-circle-filled',
|
|
||||||
'zhihu-outlined',
|
|
||||||
'zhihu-square-filled',
|
|
||||||
'zoom-in-outlined',
|
|
||||||
'zoom-out-outlined',
|
|
||||||
],
|
|
||||||
prefix: 'ant-design',
|
|
||||||
};
|
|
@@ -1,6 +1,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { IconPicker, Page } from '@vben/common-ui';
|
||||||
import {
|
import {
|
||||||
|
IconifyIcon,
|
||||||
MdiGithub,
|
MdiGithub,
|
||||||
MdiGoogle,
|
MdiGoogle,
|
||||||
MdiKeyboardEsc,
|
MdiKeyboardEsc,
|
||||||
@@ -16,9 +19,9 @@ import {
|
|||||||
SvgDownloadIcon,
|
SvgDownloadIcon,
|
||||||
} from '@vben/icons';
|
} from '@vben/icons';
|
||||||
|
|
||||||
import { Card } from 'ant-design-vue';
|
import { Card, Input } from 'ant-design-vue';
|
||||||
|
|
||||||
import IconPicker from './icon-picker.vue';
|
const iconValue = ref('ant-design:trademark-outlined');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -60,15 +63,64 @@ import IconPicker from './icon-picker.vue';
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card class="mb-5" title="图标选择器(Iconify)">
|
<Card class="mb-5" title="Tailwind CSS">
|
||||||
<div class="flex items-center gap-5">
|
<div class="flex items-center gap-5 text-3xl">
|
||||||
<IconPicker width="300px" />
|
<span class="icon-[ant-design--alipay-circle-outlined]"></span>
|
||||||
|
<span class="icon-[ant-design--account-book-filled]"></span>
|
||||||
|
<span class="icon-[ant-design--container-outlined]"></span>
|
||||||
|
<span class="icon-[svg-spinners--wind-toy]"></span>
|
||||||
|
<span class="icon-[svg-spinners--blocks-wave]"></span>
|
||||||
|
<span class="icon-[line-md--compass-filled-loop]"></span>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card title="图标选择器(Svg)">
|
<Card class="mb-5" title="图标选择器">
|
||||||
|
<div class="mb-5 flex items-center gap-5">
|
||||||
|
<span>原始样式(Iconify):</span>
|
||||||
|
<IconPicker class="w-[200px]" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-5 flex items-center gap-5">
|
||||||
|
<span>原始样式(svg):</span>
|
||||||
|
<IconPicker class="w-[200px]" prefix="svg" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-5 flex items-center gap-5">
|
||||||
|
<span>完整替换触发组件:</span>
|
||||||
|
<IconPicker class="w-[200px]">
|
||||||
|
<template #trigger="{ icon }">
|
||||||
|
<Input
|
||||||
|
:value="icon"
|
||||||
|
placeholder="点击这里选择图标"
|
||||||
|
style="width: 300px"
|
||||||
|
>
|
||||||
|
<template #addonAfter>
|
||||||
|
<IconifyIcon
|
||||||
|
:icon="icon || 'ant-design:appstore-filled'"
|
||||||
|
class="text-2xl"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Input>
|
||||||
|
</template>
|
||||||
|
</IconPicker>
|
||||||
|
</div>
|
||||||
<div class="flex items-center gap-5">
|
<div class="flex items-center gap-5">
|
||||||
<IconPicker prefix="svg" width="300px" />
|
<span>可手动输入,只能点击图标打开弹窗:</span>
|
||||||
|
<Input
|
||||||
|
v-model:value="iconValue"
|
||||||
|
allow-clear
|
||||||
|
placeholder="点击这里选择图标"
|
||||||
|
style="width: 300px"
|
||||||
|
>
|
||||||
|
<template #addonAfter>
|
||||||
|
<IconPicker v-model="iconValue" class="w-[200px]">
|
||||||
|
<template #trigger="{ icon }">
|
||||||
|
<IconifyIcon
|
||||||
|
:icon="icon || 'ant-design:appstore-filled'"
|
||||||
|
class="text-2xl"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</IconPicker>
|
||||||
|
</template>
|
||||||
|
</Input>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</Page>
|
</Page>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page, useVbenDrawer } from '@vben/common-ui';
|
import { type DrawerPlacement, Page, useVbenDrawer } from '@vben/common-ui';
|
||||||
|
|
||||||
import { Button, Card } from 'ant-design-vue';
|
import { Button, Card } from 'ant-design-vue';
|
||||||
|
|
||||||
@@ -13,6 +13,7 @@ import SharedDataDemo from './shared-data-demo.vue';
|
|||||||
const [BaseDrawer, baseDrawerApi] = useVbenDrawer({
|
const [BaseDrawer, baseDrawerApi] = useVbenDrawer({
|
||||||
// 连接抽离的组件
|
// 连接抽离的组件
|
||||||
connectedComponent: BaseDemo,
|
connectedComponent: BaseDemo,
|
||||||
|
// placement: 'left',
|
||||||
});
|
});
|
||||||
|
|
||||||
const [AutoHeightDrawer, autoHeightDrawerApi] = useVbenDrawer({
|
const [AutoHeightDrawer, autoHeightDrawerApi] = useVbenDrawer({
|
||||||
@@ -31,7 +32,8 @@ const [FormDrawer, formDrawerApi] = useVbenDrawer({
|
|||||||
connectedComponent: FormDrawerDemo,
|
connectedComponent: FormDrawerDemo,
|
||||||
});
|
});
|
||||||
|
|
||||||
function openBaseDrawer() {
|
function openBaseDrawer(placement: DrawerPlacement = 'right') {
|
||||||
|
baseDrawerApi.setState({ placement });
|
||||||
baseDrawerApi.open();
|
baseDrawerApi.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +83,16 @@ function openFormDrawer() {
|
|||||||
|
|
||||||
<Card class="mb-4" title="基本使用">
|
<Card class="mb-4" title="基本使用">
|
||||||
<p class="mb-3">一个基础的抽屉示例</p>
|
<p class="mb-3">一个基础的抽屉示例</p>
|
||||||
<Button type="primary" @click="openBaseDrawer">打开抽屉</Button>
|
<Button type="primary" @click="openBaseDrawer('right')">右侧打开</Button>
|
||||||
|
<Button class="ml-2" type="primary" @click="openBaseDrawer('bottom')">
|
||||||
|
底部打开
|
||||||
|
</Button>
|
||||||
|
<Button class="ml-2" type="primary" @click="openBaseDrawer('left')">
|
||||||
|
左侧打开
|
||||||
|
</Button>
|
||||||
|
<Button class="ml-2" type="primary" @click="openBaseDrawer('top')">
|
||||||
|
顶部打开
|
||||||
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card class="mb-4" title="内容高度自适应滚动">
|
<Card class="mb-4" title="内容高度自适应滚动">
|
||||||
|
@@ -1,13 +1,18 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
import { Button, Card, message } from 'ant-design-vue';
|
import { Button, Card, message, TabPane, Tabs } from 'ant-design-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { getAllMenusApi } from '#/api';
|
||||||
|
|
||||||
import DocButton from '../doc-button.vue';
|
import DocButton from '../doc-button.vue';
|
||||||
|
|
||||||
|
const activeTab = ref('basic');
|
||||||
|
|
||||||
const [BaseForm, baseFormApi] = useVbenForm({
|
const [BaseForm, baseFormApi] = useVbenForm({
|
||||||
// 所有表单项共用,可单独在表单内覆盖
|
// 所有表单项共用,可单独在表单内覆盖
|
||||||
commonConfig: {
|
commonConfig: {
|
||||||
@@ -36,6 +41,27 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
|||||||
// 界面显示的label
|
// 界面显示的label
|
||||||
label: '字符串',
|
label: '字符串',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 组件需要在 #/adapter.ts内注册,并加上类型
|
||||||
|
component: 'ApiSelect',
|
||||||
|
// 对应组件的参数
|
||||||
|
componentProps: {
|
||||||
|
// 菜单接口转options格式
|
||||||
|
afterFetch: (data: { name: string; path: string }[]) => {
|
||||||
|
return data.map((item: any) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.path,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
// 菜单接口
|
||||||
|
api: getAllMenusApi,
|
||||||
|
placeholder: '请选择',
|
||||||
|
},
|
||||||
|
// 字段名
|
||||||
|
fieldName: 'api',
|
||||||
|
// 界面显示的label
|
||||||
|
label: 'ApiSelect',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'InputPassword',
|
component: 'InputPassword',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
@@ -53,6 +79,11 @@ const [BaseForm, baseFormApi] = useVbenForm({
|
|||||||
label: '数字(带后缀)',
|
label: '数字(带后缀)',
|
||||||
suffix: () => '¥',
|
suffix: () => '¥',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: 'IconPicker',
|
||||||
|
fieldName: 'icon',
|
||||||
|
label: '图标',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
@@ -331,18 +362,31 @@ function handleSetFormValue() {
|
|||||||
<Page
|
<Page
|
||||||
content-class="flex flex-col gap-4"
|
content-class="flex flex-col gap-4"
|
||||||
description="表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。"
|
description="表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。"
|
||||||
|
fixed-header
|
||||||
|
header-class="pb-0"
|
||||||
title="表单组件"
|
title="表单组件"
|
||||||
>
|
>
|
||||||
|
<template #description>
|
||||||
|
<div class="text-muted-foreground">
|
||||||
|
<p>
|
||||||
|
表单组件基础示例,请注意,该页面用到的参数代码会添加一些简单注释,方便理解,请仔细查看。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Tabs v-model:active-key="activeTab" :tab-bar-style="{ marginBottom: 0 }">
|
||||||
|
<TabPane key="basic" tab="基础示例" />
|
||||||
|
<TabPane key="layout" tab="自定义布局" />
|
||||||
|
</Tabs>
|
||||||
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<DocButton path="/components/common-ui/vben-form" />
|
<DocButton path="/components/common-ui/vben-form" />
|
||||||
</template>
|
</template>
|
||||||
<Card title="基础示例">
|
<Card v-show="activeTab === 'basic'" title="基础示例">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<Button type="primary" @click="handleSetFormValue">设置表单值</Button>
|
<Button type="primary" @click="handleSetFormValue">设置表单值</Button>
|
||||||
</template>
|
</template>
|
||||||
<BaseForm />
|
<BaseForm />
|
||||||
</Card>
|
</Card>
|
||||||
<Card title="使用tailwind自定义布局">
|
<Card v-show="activeTab === 'layout'" title="使用tailwind自定义布局">
|
||||||
<CustomLayoutForm />
|
<CustomLayoutForm />
|
||||||
</Card>
|
</Card>
|
||||||
</Page>
|
</Page>
|
||||||
|
@@ -22,10 +22,10 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function handleUpdate(len: number) {
|
function handleUpdate(len: number) {
|
||||||
modalApi.setState({ loading: true });
|
modalApi.setState({ confirmDisabled: true, loading: true });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
list.value = Array.from({ length: len }, (_v, k) => k + 1);
|
list.value = Array.from({ length: len }, (_v, k) => k + 1);
|
||||||
modalApi.setState({ loading: false });
|
modalApi.setState({ confirmDisabled: false, loading: false });
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -77,6 +77,7 @@ function openFormModal() {
|
|||||||
<template>
|
<template>
|
||||||
<Page
|
<Page
|
||||||
description="弹窗组件常用于在不离开当前页面的情况下,显示额外的信息、表单或操作提示,更多api请查看组件文档。"
|
description="弹窗组件常用于在不离开当前页面的情况下,显示额外的信息、表单或操作提示,更多api请查看组件文档。"
|
||||||
|
fixed-header
|
||||||
title="弹窗组件示例"
|
title="弹窗组件示例"
|
||||||
>
|
>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
@@ -13,7 +13,7 @@ packages:
|
|||||||
- docs
|
- docs
|
||||||
- playground
|
- playground
|
||||||
catalog:
|
catalog:
|
||||||
'@ast-grep/napi': ^0.30.0
|
'@ast-grep/napi': ^0.31.0
|
||||||
'@changesets/changelog-github': ^0.5.0
|
'@changesets/changelog-github': ^0.5.0
|
||||||
'@changesets/cli': ^2.27.10
|
'@changesets/cli': ^2.27.10
|
||||||
'@changesets/git': ^3.0.2
|
'@changesets/git': ^3.0.2
|
||||||
@@ -21,74 +21,76 @@ catalog:
|
|||||||
'@commitlint/cli': ^19.6.0
|
'@commitlint/cli': ^19.6.0
|
||||||
'@commitlint/config-conventional': ^19.6.0
|
'@commitlint/config-conventional': ^19.6.0
|
||||||
'@ctrl/tinycolor': ^4.1.0
|
'@ctrl/tinycolor': ^4.1.0
|
||||||
'@eslint/js': ^9.15.0
|
'@eslint/js': ^9.16.0
|
||||||
'@faker-js/faker': ^9.2.0
|
'@faker-js/faker': ^9.3.0
|
||||||
'@iconify/json': ^2.2.275
|
'@iconify/json': ^2.2.279
|
||||||
'@iconify/tailwind': ^1.1.3
|
'@iconify/tailwind': ^1.1.3
|
||||||
'@iconify/vue': ^4.1.2
|
'@iconify/vue': ^4.1.2
|
||||||
'@intlify/core-base': ^10.0.4
|
'@intlify/core-base': ^10.0.5
|
||||||
'@intlify/unplugin-vue-i18n': ^6.0.0
|
'@intlify/unplugin-vue-i18n': ^6.0.0
|
||||||
'@jspm/generator': ^2.4.1
|
'@jspm/generator': ^2.4.1
|
||||||
'@manypkg/get-packages': ^2.2.2
|
'@manypkg/get-packages': ^2.2.2
|
||||||
'@nolebase/vitepress-plugin-git-changelog': ^2.10.0
|
'@nolebase/vitepress-plugin-git-changelog': ^2.11.1
|
||||||
'@playwright/test': ^1.49.0
|
'@playwright/test': ^1.49.0
|
||||||
'@pnpm/workspace.read-manifest': ^2.2.1
|
'@pnpm/workspace.read-manifest': ^1000.0.0
|
||||||
'@stylistic/stylelint-plugin': ^3.1.1
|
'@stylistic/stylelint-plugin': ^3.1.1
|
||||||
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e
|
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e
|
||||||
'@tailwindcss/typography': ^0.5.15
|
'@tailwindcss/typography': ^0.5.15
|
||||||
'@tanstack/vue-query': ^5.61.3
|
'@tanstack/vue-query': ^5.62.2
|
||||||
'@tanstack/vue-store': ^0.5.7
|
'@tanstack/vue-store': ^0.6.0
|
||||||
'@types/archiver': ^6.0.3
|
'@types/archiver': ^6.0.3
|
||||||
'@types/eslint': ^9.6.1
|
'@types/eslint': ^9.6.1
|
||||||
'@types/html-minifier-terser': ^7.0.2
|
'@types/html-minifier-terser': ^7.0.2
|
||||||
'@types/jsonwebtoken': ^9.0.7
|
'@types/jsonwebtoken': ^9.0.7
|
||||||
'@types/lodash.clonedeep': ^4.5.9
|
'@types/lodash.clonedeep': ^4.5.9
|
||||||
'@types/node': ^22.9.3
|
'@types/lodash.get': ^4.4.9
|
||||||
|
'@types/lodash.isequal': ^4.5.8
|
||||||
|
'@types/node': ^22.10.1
|
||||||
'@types/nprogress': ^0.2.3
|
'@types/nprogress': ^0.2.3
|
||||||
'@types/postcss-import': ^14.0.3
|
'@types/postcss-import': ^14.0.3
|
||||||
'@types/qrcode': ^1.5.5
|
'@types/qrcode': ^1.5.5
|
||||||
'@types/sortablejs': ^1.15.8
|
'@types/sortablejs': ^1.15.8
|
||||||
'@typescript-eslint/eslint-plugin': ^8.15.0
|
'@typescript-eslint/eslint-plugin': ^8.17.0
|
||||||
'@typescript-eslint/parser': ^8.15.0
|
'@typescript-eslint/parser': ^8.17.0
|
||||||
'@vee-validate/zod': ^4.14.7
|
'@vee-validate/zod': ^4.14.7
|
||||||
'@vite-pwa/vitepress': ^0.5.3
|
'@vite-pwa/vitepress': ^0.5.3
|
||||||
'@vitejs/plugin-vue': ^5.2.0
|
'@vitejs/plugin-vue': ^5.2.1
|
||||||
'@vitejs/plugin-vue-jsx': ^4.1.0
|
'@vitejs/plugin-vue-jsx': ^4.1.1
|
||||||
'@vue/reactivity': ^3.5.13
|
'@vue/reactivity': ^3.5.13
|
||||||
'@vue/shared': ^3.5.13
|
'@vue/shared': ^3.5.13
|
||||||
'@vue/test-utils': ^2.4.6
|
'@vue/test-utils': ^2.4.6
|
||||||
'@vueuse/core': ^11.3.0
|
'@vueuse/core': ^12.0.0
|
||||||
'@vueuse/integrations': ^11.3.0
|
'@vueuse/integrations': ^12.0.0
|
||||||
ant-design-vue: ^4.2.6
|
ant-design-vue: ^4.2.6
|
||||||
archiver: ^7.0.1
|
archiver: ^7.0.1
|
||||||
autoprefixer: ^10.4.20
|
autoprefixer: ^10.4.20
|
||||||
axios: ^1.7.7
|
axios: ^1.7.9
|
||||||
axios-mock-adapter: ^2.1.0
|
axios-mock-adapter: ^2.1.0
|
||||||
cac: ^6.7.14
|
cac: ^6.7.14
|
||||||
chalk: ^5.3.0
|
chalk: ^5.3.0
|
||||||
cheerio: 1.0.0
|
cheerio: 1.0.0
|
||||||
circular-dependency-scanner: ^2.3.0
|
circular-dependency-scanner: ^2.3.0
|
||||||
class-variance-authority: ^0.7.0
|
class-variance-authority: ^0.7.1
|
||||||
clsx: ^2.1.1
|
clsx: ^2.1.1
|
||||||
commitlint-plugin-function-rules: ^4.0.1
|
commitlint-plugin-function-rules: ^4.0.1
|
||||||
consola: ^3.2.3
|
consola: ^3.2.3
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
cspell: 8.16.0
|
cspell: ^8.16.1
|
||||||
cssnano: ^7.0.6
|
cssnano: ^7.0.6
|
||||||
cz-git: ^1.11.0
|
cz-git: ^1.11.0
|
||||||
czg: ^1.11.0
|
czg: ^1.11.0
|
||||||
dayjs: ^1.11.13
|
dayjs: ^1.11.13
|
||||||
defu: ^6.1.4
|
defu: ^6.1.4
|
||||||
depcheck: ^1.4.7
|
depcheck: ^1.4.7
|
||||||
dotenv: ^16.4.5
|
dotenv: ^16.4.7
|
||||||
echarts: ^5.5.1
|
echarts: ^5.5.1
|
||||||
element-plus: ^2.8.8
|
element-plus: ^2.9.0
|
||||||
eslint: ^9.15.0
|
eslint: ^9.16.0
|
||||||
eslint-config-turbo: ^2.3.1
|
eslint-config-turbo: ^2.3.3
|
||||||
eslint-plugin-command: ^0.2.6
|
eslint-plugin-command: ^0.2.6
|
||||||
eslint-plugin-eslint-comments: ^3.2.0
|
eslint-plugin-eslint-comments: ^3.2.0
|
||||||
eslint-plugin-import-x: ^4.4.3
|
eslint-plugin-import-x: ^4.5.0
|
||||||
eslint-plugin-jsdoc: ^50.5.0
|
eslint-plugin-jsdoc: ^50.6.0
|
||||||
eslint-plugin-jsonc: ^2.18.2
|
eslint-plugin-jsonc: ^2.18.2
|
||||||
eslint-plugin-n: ^17.14.0
|
eslint-plugin-n: ^17.14.0
|
||||||
eslint-plugin-no-only-tests: ^3.3.0
|
eslint-plugin-no-only-tests: ^3.3.0
|
||||||
@@ -98,13 +100,13 @@ catalog:
|
|||||||
eslint-plugin-unicorn: ^56.0.1
|
eslint-plugin-unicorn: ^56.0.1
|
||||||
eslint-plugin-unused-imports: ^4.1.4
|
eslint-plugin-unused-imports: ^4.1.4
|
||||||
eslint-plugin-vitest: ^0.5.4
|
eslint-plugin-vitest: ^0.5.4
|
||||||
eslint-plugin-vue: ^9.31.0
|
eslint-plugin-vue: ^9.32.0
|
||||||
execa: ^9.5.1
|
execa: ^9.5.1
|
||||||
find-up: ^7.0.0
|
find-up: ^7.0.0
|
||||||
get-port: ^7.1.0
|
get-port: ^7.1.0
|
||||||
globals: ^15.12.0
|
globals: ^15.13.0
|
||||||
h3: ^1.13.0
|
h3: ^1.13.0
|
||||||
happy-dom: ^15.11.6
|
happy-dom: ^15.11.7
|
||||||
html-minifier-terser: ^7.2.0
|
html-minifier-terser: ^7.2.0
|
||||||
husky: ^9.1.7
|
husky: ^9.1.7
|
||||||
is-ci: ^3.0.1
|
is-ci: ^3.0.1
|
||||||
@@ -112,9 +114,11 @@ catalog:
|
|||||||
jsonwebtoken: ^9.0.2
|
jsonwebtoken: ^9.0.2
|
||||||
lint-staged: ^15.2.10
|
lint-staged: ^15.2.10
|
||||||
lodash.clonedeep: ^4.5.0
|
lodash.clonedeep: ^4.5.0
|
||||||
lucide-vue-next: ^0.460.0
|
lodash.get: ^4.4.2
|
||||||
|
lodash.isequal: ^4.5.0
|
||||||
|
lucide-vue-next: ^0.465.0
|
||||||
medium-zoom: ^1.1.0
|
medium-zoom: ^1.1.0
|
||||||
naive-ui: ^2.40.1
|
naive-ui: ^2.40.3
|
||||||
nitropack: ^2.10.4
|
nitropack: ^2.10.4
|
||||||
nprogress: ^0.2.0
|
nprogress: ^0.2.0
|
||||||
ora: ^8.1.1
|
ora: ^8.1.1
|
||||||
@@ -128,18 +132,18 @@ catalog:
|
|||||||
postcss-import: ^16.1.0
|
postcss-import: ^16.1.0
|
||||||
postcss-preset-env: ^10.1.1
|
postcss-preset-env: ^10.1.1
|
||||||
postcss-scss: ^4.0.9
|
postcss-scss: ^4.0.9
|
||||||
prettier: ^3.3.3
|
prettier: ^3.4.2
|
||||||
prettier-plugin-tailwindcss: ^0.6.9
|
prettier-plugin-tailwindcss: ^0.6.9
|
||||||
publint: ^0.2.12
|
publint: ^0.2.12
|
||||||
qrcode: ^1.5.4
|
qrcode: ^1.5.4
|
||||||
radix-vue: ^1.9.10
|
radix-vue: ^1.9.10
|
||||||
resolve.exports: ^2.0.2
|
resolve.exports: ^2.0.3
|
||||||
rimraf: ^6.0.1
|
rimraf: ^6.0.1
|
||||||
rollup: ^4.27.4
|
rollup: ^4.28.0
|
||||||
rollup-plugin-visualizer: ^5.12.0
|
rollup-plugin-visualizer: ^5.12.0
|
||||||
sass: 1.80.6
|
sass: 1.80.6
|
||||||
sortablejs: ^1.15.4
|
sortablejs: ^1.15.6
|
||||||
stylelint: ^16.10.0
|
stylelint: ^16.11.0
|
||||||
stylelint-config-recess-order: ^5.1.1
|
stylelint-config-recess-order: ^5.1.1
|
||||||
stylelint-config-recommended: ^14.0.1
|
stylelint-config-recommended: ^14.0.1
|
||||||
stylelint-config-recommended-scss: ^14.1.0
|
stylelint-config-recommended-scss: ^14.1.0
|
||||||
@@ -148,29 +152,29 @@ catalog:
|
|||||||
stylelint-order: ^6.0.4
|
stylelint-order: ^6.0.4
|
||||||
stylelint-prettier: ^5.0.2
|
stylelint-prettier: ^5.0.2
|
||||||
stylelint-scss: ^6.10.0
|
stylelint-scss: ^6.10.0
|
||||||
tailwind-merge: ^2.5.4
|
tailwind-merge: ^2.5.5
|
||||||
tailwindcss: ^3.4.15
|
tailwindcss: ^3.4.16
|
||||||
tailwindcss-animate: ^1.0.7
|
tailwindcss-animate: ^1.0.7
|
||||||
theme-colors: ^0.1.0
|
theme-colors: ^0.1.0
|
||||||
turbo: ^2.3.1
|
turbo: ^2.3.3
|
||||||
typescript: 5.6.3
|
typescript: 5.6.3
|
||||||
unbuild: ^3.0.0-rc.11
|
unbuild: ^3.0.0-rc.11
|
||||||
unplugin-element-plus: ^0.8.0
|
unplugin-element-plus: ^0.8.0
|
||||||
vee-validate: ^4.14.7
|
vee-validate: ^4.14.7
|
||||||
vite: ^5.4.11
|
vite: ^6.0.2
|
||||||
vite-plugin-compression: ^0.5.1
|
vite-plugin-compression: ^0.5.1
|
||||||
vite-plugin-dts: 4.2.1
|
vite-plugin-dts: 4.2.1
|
||||||
vite-plugin-html: ^3.2.2
|
vite-plugin-html: ^3.2.2
|
||||||
vite-plugin-lazy-import: ^1.0.7
|
vite-plugin-lazy-import: ^1.0.7
|
||||||
vite-plugin-pwa: ^0.21.0
|
vite-plugin-pwa: ^0.21.1
|
||||||
vite-plugin-vue-devtools: ^7.6.4
|
vite-plugin-vue-devtools: ^7.6.7
|
||||||
vitepress: ^1.5.0
|
vitepress: ^1.5.0
|
||||||
vitepress-plugin-group-icons: ^1.3.0
|
vitepress-plugin-group-icons: ^1.3.1
|
||||||
vitest: ^2.1.5
|
vitest: ^2.1.8
|
||||||
vue: ^3.5.13
|
vue: ^3.5.13
|
||||||
vue-eslint-parser: ^9.4.3
|
vue-eslint-parser: ^9.4.3
|
||||||
vue-i18n: ^10.0.4
|
vue-i18n: ^10.0.5
|
||||||
vue-router: ^4.4.5
|
vue-router: ^4.5.0
|
||||||
vue-tsc: ^2.1.10
|
vue-tsc: ^2.1.10
|
||||||
vxe-pc-ui: ^4.3.4
|
vxe-pc-ui: ^4.3.4
|
||||||
vxe-table: 4.9.5
|
vxe-table: 4.9.5
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vben/turbo-run",
|
"name": "@vben/turbo-run",
|
||||||
"version": "5.4.8",
|
"version": "5.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user