mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 14:13:40 +08:00
feat: add useDesign
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import AppLocalePickerLib from './src/AppLocalePicker.vue';
|
||||
import AppLogoLib from './src/AppLogo.vue';
|
||||
import AppLocalePicker from './src/AppLocalePicker.vue';
|
||||
import AppLogo from './src/AppLogo.vue';
|
||||
import AppProvider from './src/AppProvider.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const AppLocalePicker = withInstall(AppLocalePickerLib);
|
||||
export const AppLogo = withInstall(AppLogoLib);
|
||||
withInstall(AppLocalePicker, AppLogo, AppProvider);
|
||||
|
||||
export { useAppProviderContext } from './src/useAppContext';
|
||||
|
||||
export { AppLocalePicker, AppLogo, AppProvider };
|
||||
|
@@ -69,8 +69,8 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.app-locale-picker-overlay {
|
||||
<style lang="less" scoped>
|
||||
:global(.app-locale-picker-overlay) {
|
||||
.ant-dropdown-menu-item {
|
||||
min-width: 160px;
|
||||
}
|
||||
|
@@ -4,12 +4,14 @@
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
class="app-logo anticon"
|
||||
:class="{ theme, 'collapsed-show-title': getCollapsedShowTitle }"
|
||||
class="anticon"
|
||||
:class="[prefixCls, theme, { 'collapsed-show-title': getCollapsedShowTitle }]"
|
||||
@click="handleGoHome"
|
||||
>
|
||||
<img src="/@/assets/images/logo.png" />
|
||||
<div class="app-logo__title ml-2 ellipsis" v-show="showTitle">{{ globSetting.title }}</div>
|
||||
<div class="ml-2 ellipsis" :class="[`${prefixCls}__title`]" v-show="showTitle">
|
||||
{{ globSetting.title }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
@@ -23,6 +25,8 @@
|
||||
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppLogo',
|
||||
props: {
|
||||
@@ -34,6 +38,8 @@
|
||||
showTitle: propTypes.bool.def(true),
|
||||
},
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('app-logo');
|
||||
|
||||
const { getCollapsedShowTitle } = useMenuSetting();
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
@@ -48,17 +54,19 @@
|
||||
handleGoHome,
|
||||
globSetting,
|
||||
getCollapsedShowTitle,
|
||||
prefixCls,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@import (reference) '../../../design/index.less';
|
||||
@prefix-cls: ~'@{namespace}-app-logo';
|
||||
|
||||
.app-logo {
|
||||
.@{prefix-cls} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
padding-left: 12px;
|
||||
cursor: pointer;
|
||||
|
||||
&.collapsed-show-title {
|
||||
|
24
src/components/Application/src/AppProvider.vue
Normal file
24
src/components/Application/src/AppProvider.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<slot />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, toRefs } from 'vue';
|
||||
|
||||
import { createAppProviderContext } from './useAppContext';
|
||||
export default defineComponent({
|
||||
name: 'AppProvider',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String as PropType<string>,
|
||||
default: 'vben',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { prefixCls } = toRefs(props);
|
||||
createAppProviderContext({ prefixCls });
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
16
src/components/Application/src/useAppContext.ts
Normal file
16
src/components/Application/src/useAppContext.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { InjectionKey, Ref } from 'vue';
|
||||
import { createContext, useContext } from '/@/hooks/core/useContext';
|
||||
|
||||
export interface AppProviderContextProps {
|
||||
prefixCls: Ref<string>;
|
||||
}
|
||||
|
||||
const key: InjectionKey<AppProviderContextProps> = Symbol();
|
||||
|
||||
export function createAppProviderContext(context: AppProviderContextProps) {
|
||||
return createContext<AppProviderContextProps>(context, key);
|
||||
}
|
||||
|
||||
export function useAppProviderContext() {
|
||||
return useContext<AppProviderContextProps>(key);
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
import AuthorityLib from './src/index.vue';
|
||||
import Authority from './src/index.vue';
|
||||
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const Authority = withInstall(AuthorityLib);
|
||||
withInstall(Authority);
|
||||
|
||||
export { Authority };
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import BasicArrowLib from './src/BasicArrow.vue';
|
||||
import BasicHelpLib from './src/BasicHelp.vue';
|
||||
import BasicTitleLib from './src/BasicTitle.vue';
|
||||
import BasicArrow from './src/BasicArrow.vue';
|
||||
import BasicHelp from './src/BasicHelp.vue';
|
||||
import BasicTitle from './src/BasicTitle.vue';
|
||||
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const BasicArrow = withInstall(BasicArrowLib);
|
||||
export const BasicHelp = withInstall(BasicHelpLib);
|
||||
export const BasicTitle = withInstall(BasicTitleLib);
|
||||
withInstall(BasicArrow, BasicHelp, BasicTitle);
|
||||
|
||||
export { BasicArrow, BasicHelp, BasicTitle };
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import ButtonLib from './src/BasicButton.vue';
|
||||
import Button from './src/BasicButton.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const Button = withInstall(ButtonLib);
|
||||
withInstall(Button);
|
||||
|
||||
export { Button };
|
||||
|
@@ -1,4 +1,6 @@
|
||||
import ClickOutSideLib from './src/index.vue';
|
||||
import ClickOutSide from './src/index.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const ClickOutSide = withInstall(ClickOutSideLib);
|
||||
withInstall(ClickOutSide);
|
||||
|
||||
export { ClickOutSide };
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import ScrollContainerLib from './src/ScrollContainer.vue';
|
||||
import CollapseContainerLib from './src/collapse/CollapseContainer.vue';
|
||||
import LazyContainerLib from './src/LazyContainer.vue';
|
||||
import ScrollContainer from './src/ScrollContainer.vue';
|
||||
import CollapseContainer from './src/collapse/CollapseContainer.vue';
|
||||
import LazyContainer from './src/LazyContainer.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(ScrollContainer, CollapseContainer, LazyContainer);
|
||||
|
||||
export * from './src/types';
|
||||
|
||||
export const ScrollContainer = withInstall(ScrollContainerLib);
|
||||
export const CollapseContainer = withInstall(CollapseContainerLib);
|
||||
export const LazyContainer = withInstall(LazyContainerLib);
|
||||
export { ScrollContainer, CollapseContainer, LazyContainer };
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// Transform vue-count-to to support vue3 version
|
||||
|
||||
import CountToLib from './src/index.vue';
|
||||
import CountTo from './src/index.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const CountTo = withInstall(CountToLib);
|
||||
withInstall(CountTo);
|
||||
export { CountTo };
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import DescriptionLib from './src/index';
|
||||
import Description from './src/index';
|
||||
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(Description);
|
||||
|
||||
export * from './src/types';
|
||||
export { useDescription } from './src/useDescription';
|
||||
|
||||
export const Description = withInstall(DescriptionLib);
|
||||
export { Description };
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import BasicDrawerLib from './src/BasicDrawer';
|
||||
import BasicDrawer from './src/BasicDrawer';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(BasicDrawer);
|
||||
export * from './src/types';
|
||||
export { useDrawer, useDrawerInner } from './src/useDrawer';
|
||||
export const BasicDrawer = withInstall(BasicDrawerLib);
|
||||
export { BasicDrawer };
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import DropdownLib from './src/Dropdown';
|
||||
import Dropdown from './src/Dropdown';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(Dropdown);
|
||||
export * from './src/types';
|
||||
|
||||
export const Dropdown = withInstall(DropdownLib);
|
||||
export { Dropdown };
|
||||
|
@@ -1,11 +1,12 @@
|
||||
import ImportExcelLib from './src/ImportExcel.vue';
|
||||
import ExportExcelModelLib from './src/ExportExcelModel.vue';
|
||||
import ImportExcel from './src/ImportExcel.vue';
|
||||
import ExportExcelModel from './src/ExportExcelModel.vue';
|
||||
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(ImportExcel, ExportExcelModel);
|
||||
|
||||
export * from './src/types';
|
||||
|
||||
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';
|
||||
|
||||
export const ImportExcel = withInstall(ImportExcelLib);
|
||||
export const ExportExcelModel = withInstall(ExportExcelModelLib);
|
||||
export { ImportExcel, ExportExcelModel };
|
||||
|
@@ -1,10 +1,12 @@
|
||||
import BasicFormLib from './src/BasicForm.vue';
|
||||
import BasicForm from './src/BasicForm.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(BasicForm);
|
||||
|
||||
export * from './src/types/form';
|
||||
export * from './src/types/formItem';
|
||||
|
||||
export { useComponentRegister } from './src/hooks/useComponentRegister';
|
||||
export { useForm } from './src/hooks/useForm';
|
||||
|
||||
export const BasicForm = withInstall(BasicFormLib);
|
||||
export { BasicForm };
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import './src/indicator';
|
||||
import LoadingLib from './src/index.vue';
|
||||
import Loading from './src/index.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(Loading);
|
||||
export { useLoading } from './src/useLoading';
|
||||
export { createLoading } from './src/createLoading';
|
||||
|
||||
export const Loading = withInstall(LoadingLib);
|
||||
export { Loading };
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import MarkDownLib from './src/index.vue';
|
||||
import MarkDown from './src/index.vue';
|
||||
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(MarkDown);
|
||||
|
||||
export * from './src/types';
|
||||
|
||||
export const MarkDown = withInstall(MarkDownLib);
|
||||
export { MarkDown };
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import BasicMenuLib from './src/BasicMenu';
|
||||
import BasicMenu from './src/BasicMenu';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const BasicMenu = withInstall(BasicMenuLib);
|
||||
withInstall(BasicMenu);
|
||||
export { BasicMenu };
|
||||
|
@@ -15,7 +15,6 @@ import {
|
||||
ComputedRef,
|
||||
} from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import SearchInput from './SearchInput.vue';
|
||||
import MenuContent from './MenuContent';
|
||||
// import { ScrollContainer } from '/@/components/Container';
|
||||
|
||||
@@ -24,8 +23,7 @@ import { ThemeEnum } from '/@/enums/appEnum';
|
||||
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
import { useSearchInput } from './hooks/useSearchInput';
|
||||
import { useOpenKeys } from './hooks/useOpenKeys';
|
||||
import { useOpenKeys } from './useOpenKeys';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { isFunction } from '/@/utils/is';
|
||||
@@ -43,51 +41,39 @@ export default defineComponent({
|
||||
emits: ['menuClick'],
|
||||
setup(props, { slots, emit }) {
|
||||
const currentParentPath = ref('');
|
||||
|
||||
const menuState = reactive<MenuState>({
|
||||
defaultSelectedKeys: [],
|
||||
mode: props.mode,
|
||||
theme: computed(() => props.theme) as ComputedRef<ThemeEnum>,
|
||||
openKeys: [],
|
||||
searchValue: '',
|
||||
selectedKeys: [],
|
||||
collapsedOpenKeys: [],
|
||||
});
|
||||
|
||||
const { getCollapsed } = useMenuSetting();
|
||||
|
||||
const { currentRoute } = useRouter();
|
||||
|
||||
const { items, flatItems, isAppMenu, mode, accordion } = toRefs(props);
|
||||
|
||||
const { handleInputChange, handleInputClick } = useSearchInput({
|
||||
flatMenusRef: flatItems,
|
||||
emit: emit,
|
||||
menuState,
|
||||
handleMenuChange,
|
||||
});
|
||||
const { items, flatItems, mode, accordion } = toRefs(props);
|
||||
|
||||
const { handleOpenChange, resetKeys, setOpenKeys } = useOpenKeys(
|
||||
menuState,
|
||||
items,
|
||||
flatItems,
|
||||
isAppMenu,
|
||||
mode,
|
||||
accordion
|
||||
);
|
||||
|
||||
const getOpenKeys = computed(() => {
|
||||
if (props.isAppMenu) {
|
||||
return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
|
||||
}
|
||||
return menuState.openKeys;
|
||||
return unref(getCollapsed) ? menuState.collapsedOpenKeys : menuState.openKeys;
|
||||
});
|
||||
|
||||
// menu外层样式
|
||||
const getMenuWrapStyle = computed((): any => {
|
||||
const { showLogo, search } = props;
|
||||
const { showLogo } = props;
|
||||
let offset = 0;
|
||||
if (search) {
|
||||
offset += 54;
|
||||
}
|
||||
|
||||
if (showLogo) {
|
||||
offset += 46;
|
||||
}
|
||||
@@ -110,7 +96,7 @@ export default defineComponent({
|
||||
cls.push('basic-menu__sidebar-hor');
|
||||
}
|
||||
|
||||
if (!props.isHorizontal && props.isAppMenu && appStore.getProjectConfig.menuSetting.split) {
|
||||
if (!props.isHorizontal && appStore.getProjectConfig.menuSetting.split) {
|
||||
cls.push('basic-menu__second');
|
||||
}
|
||||
return cls;
|
||||
@@ -197,7 +183,6 @@ export default defineComponent({
|
||||
level={index}
|
||||
isHorizontal={props.isHorizontal}
|
||||
showTitle={unref(showTitle)}
|
||||
searchValue={menuState.searchValue}
|
||||
/>,
|
||||
]}
|
||||
</Menu.Item>
|
||||
@@ -212,7 +197,6 @@ export default defineComponent({
|
||||
item={menu}
|
||||
level={index}
|
||||
isHorizontal={props.isHorizontal}
|
||||
searchValue={menuState.searchValue}
|
||||
/>,
|
||||
],
|
||||
default: () => renderMenuItem(menu.children, index + 1),
|
||||
@@ -227,11 +211,9 @@ export default defineComponent({
|
||||
const { selectedKeys, defaultSelectedKeys, mode, theme } = menuState;
|
||||
|
||||
const inlineCollapsedObj = isInline
|
||||
? props.isAppMenu
|
||||
? {
|
||||
inlineCollapsed: unref(getCollapsed),
|
||||
}
|
||||
: { inlineCollapsed: props.inlineCollapsed }
|
||||
? {
|
||||
inlineCollapsed: unref(getCollapsed),
|
||||
}
|
||||
: {};
|
||||
return (
|
||||
<Menu
|
||||
@@ -267,17 +249,8 @@ export default defineComponent({
|
||||
) : (
|
||||
<section class={[`basic-menu-wrap`, !unref(showTitle) && 'hide-title']}>
|
||||
{getSlot(slots, 'header')}
|
||||
<SearchInput
|
||||
class={!props.search ? 'hidden' : ''}
|
||||
theme={props.theme as ThemeEnum}
|
||||
onChange={handleInputChange}
|
||||
onClick={handleInputClick}
|
||||
collapsed={unref(getCollapsed)}
|
||||
/>
|
||||
|
||||
{/* <section style={unref(getMenuWrapStyle)}> */}
|
||||
<section style={unref(getMenuWrapStyle)} class="basic-menu__content">
|
||||
{/* <ScrollContainer>{() => renderMenu()}</ScrollContainer> */}
|
||||
{renderMenu()}
|
||||
</section>
|
||||
</section>
|
||||
|
11
src/components/Menu/src/BasicMenu.vue
Normal file
11
src/components/Menu/src/BasicMenu.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div> </div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
@@ -8,11 +8,6 @@ import { useI18n } from '/@/hooks/web/useI18n';
|
||||
export default defineComponent({
|
||||
name: 'MenuContent',
|
||||
props: {
|
||||
searchValue: {
|
||||
type: String as PropType<string>,
|
||||
default: '',
|
||||
},
|
||||
|
||||
item: {
|
||||
type: Object as PropType<MenuType>,
|
||||
default: null,
|
||||
@@ -35,11 +30,7 @@ export default defineComponent({
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const getI18nName = computed(() => {
|
||||
const { name } = props.item;
|
||||
|
||||
return t(name);
|
||||
});
|
||||
const getI18nName = computed(() => t(props.item?.name));
|
||||
/**
|
||||
* @description: 渲染图标
|
||||
*/
|
||||
@@ -71,28 +62,18 @@ export default defineComponent({
|
||||
const { showTitle } = props;
|
||||
const { icon } = props.item;
|
||||
const name = unref(getI18nName);
|
||||
const searchValue = props.searchValue || '';
|
||||
const index = name.indexOf(searchValue);
|
||||
|
||||
const beforeStr = name.substr(0, index);
|
||||
const afterStr = name.substr(index + searchValue.length);
|
||||
const cls = showTitle ? ['show-title'] : ['basic-menu__name'];
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderIcon(icon!)}
|
||||
{index > -1 && searchValue ? (
|
||||
<span class={cls}>
|
||||
{beforeStr}
|
||||
<span class={`basic-menu__keyword`}>{searchValue}</span>
|
||||
{afterStr}
|
||||
</span>
|
||||
) : (
|
||||
{
|
||||
<span class={[cls]}>
|
||||
{name}
|
||||
{renderTag()}
|
||||
</span>
|
||||
)}
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<section class="menu-search-input" @Click="handleClick" :class="searchClass">
|
||||
<a-input-search
|
||||
:placeholder="t('component.menu.search')"
|
||||
class="menu-search-input__search"
|
||||
allowClear
|
||||
@change="handleChange"
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { ThemeEnum } from '/@/enums/appEnum';
|
||||
// hook
|
||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
//
|
||||
export default defineComponent({
|
||||
name: 'BasicMenuSearchInput',
|
||||
props: {
|
||||
// Whether to expand, used in the left menu
|
||||
collapsed: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
theme: {
|
||||
type: String as PropType<ThemeEnum>,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const [debounceEmitChange] = useDebounce(emitChange, 200);
|
||||
|
||||
function emitChange(value?: string): void {
|
||||
emit('change', value);
|
||||
}
|
||||
|
||||
function handleChange(e: ChangeEvent): void {
|
||||
const { collapsed } = props;
|
||||
if (collapsed) return;
|
||||
debounceEmitChange(e.target.value);
|
||||
}
|
||||
|
||||
function handleClick(): void {
|
||||
emit('click');
|
||||
}
|
||||
|
||||
const searchClass = computed(() => {
|
||||
const cls: string[] = [];
|
||||
cls.push(props.theme ? `menu-search-input__search--${props.theme}` : '');
|
||||
cls.push(props.collapsed ? 'hide-search-icon' : '');
|
||||
return cls;
|
||||
});
|
||||
|
||||
return { handleClick, searchClass, handleChange, t };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import (reference) '../../../design/index.less';
|
||||
// 输入框背景颜色 深
|
||||
@input-dark-bg-color: #516085;
|
||||
|
||||
@icon-color: #c0c4cc;
|
||||
|
||||
.menu-search-input {
|
||||
margin: 12px 8px;
|
||||
|
||||
&.hide-search-icon {
|
||||
.ant-input,
|
||||
.ant-input-suffix {
|
||||
opacity: 0;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
}
|
||||
|
||||
&__search--dark {
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-input {
|
||||
.set-bg();
|
||||
}
|
||||
|
||||
.ant-input-search-icon,
|
||||
.ant-input-clear-icon {
|
||||
color: rgba(255, 255, 255, 0.4) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&__search--light {
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-input {
|
||||
color: @text-color-base;
|
||||
background: #fff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ant-input-search-icon {
|
||||
color: @icon-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.set-bg() {
|
||||
color: #fff;
|
||||
background: @sider-dark-lighten-1-bg-color;
|
||||
border: 0;
|
||||
outline: none;
|
||||
}
|
||||
.hide-outline() {
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
</style>
|
@@ -1,58 +0,0 @@
|
||||
import type { Menu as MenuType } from '/@/router/types';
|
||||
import type { MenuState } from '../types';
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { isString } from '/@/utils/is';
|
||||
import { unref } from 'vue';
|
||||
import { es6Unique } from '/@/utils';
|
||||
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
||||
|
||||
interface UseSearchInputOptions {
|
||||
menuState: MenuState;
|
||||
flatMenusRef: Ref<MenuType[]>;
|
||||
emit: EmitType;
|
||||
handleMenuChange: Fn;
|
||||
}
|
||||
export function useSearchInput({
|
||||
menuState,
|
||||
flatMenusRef,
|
||||
handleMenuChange,
|
||||
emit,
|
||||
}: UseSearchInputOptions) {
|
||||
/**
|
||||
* @description: 输入框搜索
|
||||
*/
|
||||
function handleInputChange(value?: string): void {
|
||||
if (!isString(value)) {
|
||||
value = (value as any).target.value;
|
||||
}
|
||||
if (!value) {
|
||||
handleMenuChange && handleMenuChange();
|
||||
}
|
||||
|
||||
menuState.searchValue = value || '';
|
||||
if (!value) {
|
||||
menuState.openKeys = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const flatMenus = unref(flatMenusRef);
|
||||
let openKeys: string[] = [];
|
||||
for (const menu of flatMenus) {
|
||||
const { name, path } = menu;
|
||||
if (!name.includes(value)) {
|
||||
continue;
|
||||
}
|
||||
openKeys = openKeys.concat(getAllParentPath(flatMenus, path));
|
||||
}
|
||||
openKeys = es6Unique(openKeys);
|
||||
menuState.openKeys = openKeys;
|
||||
}
|
||||
|
||||
// 搜索框点击
|
||||
function handleInputClick(e: any): void {
|
||||
emit('clickSearchInput', e);
|
||||
}
|
||||
|
||||
return { handleInputChange, handleInputClick };
|
||||
}
|
@@ -20,11 +20,7 @@ export const basicProps = {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
// 是否显示搜索框
|
||||
search: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
|
||||
// 最好是4 倍数
|
||||
inlineIndent: {
|
||||
type: Number as PropType<number>,
|
||||
@@ -51,10 +47,7 @@ export const basicProps = {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
isAppMenu: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
|
||||
isHorizontal: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
|
@@ -17,9 +17,6 @@ export interface MenuState {
|
||||
// 展开数组
|
||||
openKeys: string[];
|
||||
|
||||
// 搜索值
|
||||
searchValue: string;
|
||||
|
||||
// 当前选中的菜单项 key 数组
|
||||
selectedKeys: string[];
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { MenuModeEnum } from '/@/enums/menuEnum';
|
||||
import type { Menu as MenuType } from '/@/router/types';
|
||||
import type { MenuState } from '../types';
|
||||
import type { MenuState } from './types';
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { unref } from 'vue';
|
||||
@@ -12,14 +12,11 @@ export function useOpenKeys(
|
||||
menuState: MenuState,
|
||||
menus: Ref<MenuType[]>,
|
||||
flatMenusRef: Ref<MenuType[]>,
|
||||
isAppMenu: Ref<boolean>,
|
||||
mode: Ref<MenuModeEnum>,
|
||||
accordion: Ref<boolean>
|
||||
) {
|
||||
const { getCollapsed } = useMenuSetting();
|
||||
/**
|
||||
* @description:设置展开
|
||||
*/
|
||||
|
||||
function setOpenKeys(menu: MenuType) {
|
||||
const flatMenus = unref(flatMenusRef);
|
||||
if (!unref(accordion)) {
|
||||
@@ -50,7 +47,7 @@ export function useOpenKeys(
|
||||
rootSubMenuKeys.push(path);
|
||||
}
|
||||
}
|
||||
if (!unref(getCollapsed) || !unref(isAppMenu)) {
|
||||
if (!unref(getCollapsed)) {
|
||||
const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1);
|
||||
if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) {
|
||||
menuState.openKeys = openKeys;
|
@@ -1,8 +1,10 @@
|
||||
import './src/index.less';
|
||||
import BasicModalLib from './src/BasicModal';
|
||||
import BasicModal from './src/BasicModal';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(BasicModal);
|
||||
|
||||
export { useModalContext } from './src/useModalContext';
|
||||
export { useModal, useModalInner } from './src/useModal';
|
||||
export * from './src/types';
|
||||
export const BasicModal = withInstall(BasicModalLib);
|
||||
export { BasicModal };
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import PageFooterLib from './src/PageFooter.vue';
|
||||
import PageFooter from './src/PageFooter.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const PageFooter = withInstall(PageFooterLib);
|
||||
withInstall(PageFooter);
|
||||
export { PageFooter };
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import StrengthMeterLib from './src/index';
|
||||
import StrengthMeter from './src/index';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const StrengthMeter = withInstall(StrengthMeterLib);
|
||||
withInstall(StrengthMeter);
|
||||
export { StrengthMeter };
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import TinymceLib from './src/Editor.vue';
|
||||
import Tinymce from './src/Editor.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const Tinymce = withInstall(TinymceLib);
|
||||
withInstall(Tinymce);
|
||||
export { Tinymce };
|
||||
|
@@ -1,8 +1,5 @@
|
||||
import type { App } from 'vue';
|
||||
import BasicUpload from './src/BasicUpload.vue';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export default (app: App): void => {
|
||||
app.component(BasicUpload.name, BasicUpload);
|
||||
};
|
||||
|
||||
withInstall(BasicUpload);
|
||||
export { BasicUpload };
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import BasicDragVerifyLib from './src/DragVerify';
|
||||
import RotateDragVerifyLib from './src/ImgRotate';
|
||||
import BasicDragVerify from './src/DragVerify';
|
||||
import RotateDragVerify from './src/ImgRotate';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
withInstall(BasicDragVerify, RotateDragVerify);
|
||||
|
||||
export * from './src/types';
|
||||
|
||||
export const RotateDragVerify = withInstall(RotateDragVerifyLib);
|
||||
export const BasicDragVerify = withInstall(BasicDragVerifyLib);
|
||||
export { BasicDragVerify, RotateDragVerify };
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import VirtualScrollLib from './src/index';
|
||||
import VirtualScroll from './src/index';
|
||||
import { withInstall } from '../util';
|
||||
|
||||
export const VirtualScroll = withInstall(VirtualScrollLib);
|
||||
withInstall(VirtualScroll);
|
||||
export { VirtualScroll };
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import type { VNodeChild, Plugin } from 'vue';
|
||||
import type { VNodeChild } from 'vue';
|
||||
import type { App } from 'vue';
|
||||
|
||||
export function withInstall<T>(component: T) {
|
||||
const comp = component as any;
|
||||
comp.install = (app: App) => {
|
||||
app.component(comp.displayName || comp.name, comp);
|
||||
};
|
||||
return comp as T & Plugin;
|
||||
export function withInstall(...components: any[]) {
|
||||
components.forEach((comp) => {
|
||||
comp.install = (app: App) => {
|
||||
app.component(comp.displayName || comp.name, comp);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function convertToUnit(
|
||||
|
Reference in New Issue
Block a user