vben
2021-01-05 31ff0559fe3b635fc2091aac0e2f5e340629134c
feat(page-wrapper): added pageWrapper component
4个文件已添加
75个文件已修改
1225 ■■■■■ 已修改文件
.vscode/settings.json 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CHANGELOG.zh_CN.md 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Form/src/hooks/useFormContext.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Page/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Page/src/PageFooter.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Page/src/PageWrapper.vue 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Table/src/hooks/useDataSource.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Upload/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/component/usePageContext.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/core/useContext.ts 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/content/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/content/useContentContext.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/content/useContentViewHeight.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/default/header/MultipleHeader.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/page/index.tsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/settings/projectSetting.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/button/index.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/count-to/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/desc/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/drawer/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/lazy/Transition.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/lazy/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/loading/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/modal/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/qrcode/index.vue 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/scroll/Action.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/scroll/VirtualScroll.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/scroll/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/strength-meter/index.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/transition/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/upload/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/verify/Rotate.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/comp/verify/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/editor/markdown/Editor.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/editor/markdown/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/editor/tinymce/Editor.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/editor/tinymce/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/excel/ArrayExport.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/excel/CustomExport.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/excel/ImportExcel.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/excel/JsonExport.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/breadcrumb/ChildrenList.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/breadcrumb/FlatList.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/click-out-side/index.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/context-menu/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/copy/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/download/index.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/full-screen/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/icon/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/img-preview/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/msg/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/ripple/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/tab-params/index.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/tabs/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/feat/watermark/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/AdvancedForm.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/CustomerForm.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/DynamicForm.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/RefForm.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/RuleForm.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/UseForm.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/form/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/desc/basic/index.vue 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/desc/high/index.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/form/basic/index.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/form/high/index.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/form/step/index.vue 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/list/basic/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/list/card/data.tsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/list/card/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/page/list/search/index.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/permission/back/Btn.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/permission/back/index.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/permission/front/Btn.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/permission/front/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/table/Basic.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/tree/ActionTree.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/tree/EditTree.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/demo/tree/index.vue 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vscode/settings.json
@@ -12,6 +12,7 @@
  "editor.cursorSmoothCaretAnimation": true,
  "editor.detectIndentation": false,
  "diffEditor.ignoreTrimWhitespace": false,
  "javascript.format.insertSpaceBeforeFunctionParenthesis": true,
  "editor.formatOnPaste": true,
  "editor.formatOnSave": true,
  "editor.suggestSelection": "first",
@@ -108,18 +109,22 @@
  // ===========================================
  // ================ Eslint ===================
  // ===========================================
  "eslint.enable": true,
  // "eslint.enable": true,
  "eslint.alwaysShowStatus": true,
  "eslint.options": {
    // 配置
    "plugins": [
      "html",
      "vue",
      "javascript",
      "jsx",
      "typescript"
    ]
    "plugins": ["html", "vue", "javascript", "jsx", "typescript"],
    "extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"]
  },
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    "typescript",
    "reacttypescript",
    "reactjavascript",
    "html",
    "vue"
  ],
  // "eslint.autoFixOnSave": true,
  // ===========================================
  // ================ Vetur ====================
  // ===========================================
@@ -181,19 +186,12 @@
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "i18n-ally.localesPaths": [
    "src/locales/lang",
  ],
  "i18n-ally.localesPaths": ["src/locales/lang"],
  "i18n-ally.keystyle": "nested",
  "i18n-ally.sortKeys": true,
  "i18n-ally.namespace": true,
  "i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
  "i18n-ally.enabledParsers": [
    "ts"
  ],
  "i18n-ally.enabledParsers": ["ts"],
  "i18n-ally.sourceLanguage": "zh",
  "i18n-ally.enabledFrameworks": [
    "vue",
    "react"
  ]
}
  "i18n-ally.enabledFrameworks": ["vue", "react"]
}
CHANGELOG.zh_CN.md
@@ -5,6 +5,7 @@
- 新增`mixSideTrigger`配置。用于配置左侧混合模式菜单打开方式。可选`hover`,默认`click`
- 新增`mixSideFixed`配置。用于固定左侧混合模式菜单
- modal 组件新增`height`和`min-height`属性
- 新增`PageWrapper`组件。并应用于示例页面
### 🐛 Bug Fixes
src/components/Form/src/hooks/useFormContext.ts
@@ -1,4 +1,4 @@
import { InjectionKey } from 'vue';
import type { InjectionKey } from 'vue';
import { createContext, useContext } from '/@/hooks/core/useContext';
export interface FormContextProps {
src/components/Page/index.ts
@@ -1,2 +1,4 @@
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
export const PageFooter = createAsyncComponent(() => import('./src/PageFooter.vue'));
export { default as PageWrapper } from './src/PageWrapper.vue';
src/components/Page/src/PageFooter.vue
@@ -1,9 +1,10 @@
<template>
  <div class="app-footer" :style="{ width: getCalcContentWidth }">
    <div class="app-footer__left">
  <div :class="prefixCls" :style="{ width: getCalcContentWidth }">
    <div :class="`${prefixCls}__left`">
      <slot name="left" />
    </div>
    <div class="app-footer__right">
    <slot />
    <div :class="`${prefixCls}__right`">
      <slot name="right" />
    </div>
  </div>
@@ -12,19 +13,21 @@
  import { defineComponent } from 'vue';
  import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  import { useDesign } from '/@/hooks/web/useDesign';
  export default defineComponent({
    name: 'PageFooter',
    setup() {
      const { prefixCls } = useDesign('page-footer');
      const { getCalcContentWidth } = useMenuSetting();
      return { getCalcContentWidth };
      return { prefixCls, getCalcContentWidth };
    },
  });
</script>
<style lang="less" scoped>
  @import (reference) '../../../design/index.less';
  @prefix-cls: ~'@{namespace}-page-footer';
  .app-footer {
  .@{prefix-cls} {
    position: fixed;
    right: 0;
    bottom: 0;
src/components/Page/src/PageWrapper.vue
New file
@@ -0,0 +1,153 @@
<template>
  <div :class="getClass">
    <PageHeader :ghost="ghost" v-bind="$attrs" ref="headerRef">
      <template #default>
        <template v-if="content">
          {{ content }}
        </template>
        <slot name="headerContent" v-else />
      </template>
      <template #[item]="data" v-for="item in getHeaderSlots">
        <slot :name="item" v-bind="data" />
      </template>
    </PageHeader>
    <div :class="[`${prefixCls}-content`, $attrs.contentClass]" :style="getContentStyle">
      <slot />
    </div>
    <PageFooter v-if="getShowFooter" ref="footerRef">
      <template #left>
        <slot name="leftFooter" />
      </template>
      <template #right>
        <slot name="rightFooter" />
      </template>
    </PageFooter>
  </div>
</template>
<script lang="ts">
  import type { CSSProperties, PropType } from 'vue';
  import { defineComponent, computed, watch, nextTick, ref, unref } from 'vue';
  import PageFooter from './PageFooter.vue';
  import { usePageContext } from '/@/hooks/component/usePageContext';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { propTypes } from '/@/utils/propTypes';
  import { omit } from 'lodash-es';
  import { PageHeader } from 'ant-design-vue';
  export default defineComponent({
    name: 'PageWrapper',
    components: { PageFooter, PageHeader },
    props: {
      dense: propTypes.bool,
      ghost: propTypes.bool,
      content: propTypes.string,
      contentStyle: {
        type: Object as PropType<CSSProperties>,
      },
      contentBackgrond: propTypes.bool,
      contentFullHeight: propTypes.bool,
    },
    setup(props, { slots }) {
      const headerRef = ref<ComponentRef>(null);
      const footerRef = ref<ComponentRef>(null);
      const { prefixCls } = useDesign('page-wrapper');
      const { contentHeight, setPageHeight, pageHeight } = usePageContext();
      const getClass = computed(() => {
        return [
          prefixCls,
          {
            [`${prefixCls}--dense`]: props.dense,
          },
        ];
      });
      const getShowFooter = computed(() => slots?.leftFooter || slots?.rightFooter);
      const getHeaderSlots = computed(() => {
        return Object.keys(omit(slots, 'default', 'leftFooter', 'rightFooter', 'headerContent'));
      });
      const getContentStyle = computed(
        (): CSSProperties => {
          const { contentBackgrond, contentFullHeight, contentStyle } = props;
          const bg = contentBackgrond ? { backgroundColor: '#fff' } : {};
          if (!contentFullHeight) {
            return { ...bg, ...contentStyle };
          }
          return {
            ...bg,
            ...contentStyle,
            minHeight: `${unref(pageHeight)}px`,
          };
        }
      );
      watch(
        () => contentHeight?.value,
        (height) => {
          if (!props.contentFullHeight) {
            return;
          }
          nextTick(() => {
            const footer = unref(footerRef);
            const header = unref(headerRef);
            let footetHeight = 0;
            const footerEl = footer?.$el;
            if (footerEl) {
              footetHeight += footerEl?.offsetHeight ?? 0;
            }
            let headerHeight = 0;
            const headerEl = header?.$el;
            if (headerEl) {
              headerHeight += headerEl?.offsetHeight ?? 0;
            }
            setPageHeight?.(height - footetHeight - headerHeight);
          });
        },
        {
          immediate: true,
        }
      );
      return {
        getContentStyle,
        footerRef,
        headerRef,
        getClass,
        getHeaderSlots,
        prefixCls,
        getShowFooter,
        pageHeight,
        omit,
      };
    },
  });
</script>
<style lang="less">
  @prefix-cls: ~'@{namespace}-page-wrapper';
  .@{prefix-cls} {
    position: relative;
    .ant-page-header {
      padding: 12px 16px;
      &:empty {
        padding: 0;
      }
    }
    &-content {
      // padding: 12px;
      margin: 16px;
    }
    &--dense {
      .@{prefix-cls}-content {
        margin: 0;
      }
    }
  }
</style>
src/components/Table/src/hooks/useDataSource.ts
@@ -7,7 +7,7 @@
import { buildUUID } from '/@/utils/uuid';
import { isFunction, isBoolean } from '/@/utils/is';
import { get } from 'lodash-es';
import { get, cloneDeep } from 'lodash-es';
import { FETCH_SETTING, ROW_KEY, PAGE_SIZE } from '../const';
@@ -114,7 +114,8 @@
      if (firstItem && lastItem) {
        if (!firstItem[ROW_KEY] || !lastItem[ROW_KEY]) {
          unref(dataSourceRef).forEach((item) => {
          const data = cloneDeep(unref(dataSourceRef));
          data.forEach((item) => {
            if (!item[ROW_KEY]) {
              item[ROW_KEY] = buildUUID();
            }
@@ -122,6 +123,7 @@
              setTableKey(item.children);
            }
          });
          dataSourceRef.value = data;
        }
      }
    }
src/components/Upload/index.ts
@@ -1,2 +1,4 @@
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
export const BasicUpload = createAsyncComponent(() => import('./src/BasicUpload.vue'));
// import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
// export const BasicUpload = createAsyncComponent(() => import('./src/BasicUpload.vue'));
export { default as BasicUpload } from './src/BasicUpload.vue';
src/hooks/component/usePageContext.ts
New file
@@ -0,0 +1,20 @@
import type { InjectionKey, ComputedRef, Ref } from 'vue';
import { createContext, useContext } from '/@/hooks/core/useContext';
import {} from 'vue';
export interface PageContextProps {
  contentHeight: ComputedRef<number>;
  pageHeight: Ref<number>;
  setPageHeight: (height: number) => Promise<void>;
}
const key: InjectionKey<PageContextProps> = Symbol();
export function createPageContext(context: PageContextProps) {
  return createContext<PageContextProps>(context, key, { native: true });
}
export function usePageContext() {
  return useContext<PageContextProps>(key);
}
src/hooks/core/useContext.ts
@@ -11,6 +11,7 @@
export interface CreateContextOptions {
  readonly?: boolean;
  createProvider?: boolean;
  native?: boolean;
}
type ShallowUnwrap<T> = {
@@ -22,11 +23,11 @@
  key: InjectionKey<T> = Symbol(),
  options: CreateContextOptions = {}
) {
  const { readonly = true, createProvider = false } = options;
  const { readonly = true, createProvider = false, native = false } = options;
  const state = reactive(context);
  const provideData = readonly ? defineReadonly(state) : state;
  !createProvider && provide(key, provideData);
  !createProvider && provide(key, native ? context : provideData);
  const Provider = createProvider
    ? defineComponent({
@@ -42,12 +43,12 @@
  return { Provider, state };
}
export const useContext = <T>(
  key: InjectionKey<T> = Symbol(),
  defaultValue?: any,
  readonly = false
): ShallowUnwrap<T> => {
  const state = inject(key, defaultValue || {});
export function useContext<T>(key: InjectionKey<T>, native?: boolean): T;
export function useContext<T>(key: InjectionKey<T>, defaultValue?: any, native?: boolean): T;
  return readonly ? defineReadonly(state) : state;
};
export function useContext<T>(
  key: InjectionKey<T> = Symbol(),
  defaultValue?: any
): ShallowUnwrap<T> {
  return inject(key, defaultValue || {});
}
src/layouts/default/content/index.vue
@@ -19,6 +19,7 @@
  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
  import PageLayout from '/@/layouts/page/index';
  import { useContentViewHeight } from './useContentViewHeight';
  import { Loading } from '/@/components/Loading';
  export default defineComponent({
@@ -28,6 +29,8 @@
      const { prefixCls } = useDesign('layout-content');
      const { getOpenPageLoading } = useTransitionSetting();
      const { getLayoutContentMode, getPageLoading } = useRootSetting();
      useContentViewHeight();
      return {
        prefixCls,
        getOpenPageLoading,
src/layouts/default/content/useContentContext.ts
New file
@@ -0,0 +1,19 @@
import type { InjectionKey, ComputedRef } from 'vue';
import { createContext, useContext } from '/@/hooks/core/useContext';
import {} from 'vue';
export interface ContentContextProps {
  contentHeight: ComputedRef<number>;
  setPageHeight: (height: number) => Promise<void>;
}
const key: InjectionKey<ContentContextProps> = Symbol();
export function createContentContext(context: ContentContextProps) {
  return createContext<ContentContextProps>(context, key, { native: true });
}
export function useContentContext() {
  return useContext<ContentContextProps>(key);
}
src/layouts/default/content/useContentViewHeight.ts
New file
@@ -0,0 +1,30 @@
import { ref, computed, unref } from 'vue';
import { createPageContext } from '/@/hooks/component/usePageContext';
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
export const headerHeightRef = ref(0);
export function useContentViewHeight() {
  const contentHeight = ref(window.innerHeight);
  const pageHeight = ref(window.innerHeight);
  const getViewHeight = computed(() => {
    return unref(contentHeight) - unref(headerHeightRef) || 0;
  });
  useWindowSizeFn(
    () => {
      contentHeight.value = window.innerHeight;
    },
    100,
    { immediate: true }
  );
  async function setPageHeight(height: number) {
    pageHeight.value = height;
  }
  createPageContext({
    contentHeight: getViewHeight,
    setPageHeight,
    pageHeight,
  });
}
src/layouts/default/header/MultipleHeader.vue
@@ -17,6 +17,7 @@
  import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
  import { useAppInject } from '/@/hooks/web/useAppInject';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { headerHeightRef } from '../content/useContentViewHeight';
  const HEADER_HEIGHT = 48;
@@ -75,6 +76,7 @@
          if (unref(getShowMultipleTab)) {
            height += TABS_HEIGHT;
          }
          headerHeightRef.value = height;
          return {
            height: `${height}px`,
          };
src/layouts/page/index.tsx
@@ -1,8 +1,7 @@
import type { FunctionalComponent } from 'vue';
import type { DefaultContext } from './transition';
import { computed, defineComponent, unref, Transition, KeepAlive } from 'vue';
import { RouterView, RouteLocation } from 'vue-router';
import { RouterView } from 'vue-router';
import FrameLayout from '/@/layouts/iframe/index.vue';
@@ -12,14 +11,7 @@
import { useCache } from './useCache';
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
import { getTransitionName } from './transition';
// import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
interface DefaultContext {
  Component: FunctionalComponent & { type: Indexable };
  route: RouteLocation;
}
// const FrameLayout=createAsyncComponent(()=>'/@/layouts/iframe/index.vue')
export default defineComponent({
  name: 'PageLayout',
  setup() {
src/settings/projectSetting.ts
@@ -85,7 +85,7 @@
    collapsedShowTitle: false,
    // Whether it can be dragged
    // Only limited to the opening of the left menu, the mouse has a drag bar on the right side of the menu
    canDrag: true,
    canDrag: false,
    // Whether to show no dom
    show: true,
    // Whether to show dom
src/views/demo/comp/button/index.vue
@@ -1,11 +1,11 @@
<template>
  <div class="p-4">
    <Alert
      message="温馨提醒"
      description="基础组件依赖于 ant-design-vue,组件库已有的基础组件,项目中不会再次进行demo展示(二次封装组件除外)"
      type="info"
      show-icon
    />
  <PageWrapper
    title="基础组件"
    content=" 基础组件依赖于ant-design-vue,组件库已有的基础组件,项目中不会再次进行demo展示(二次封装组件除外)"
  >
    <template #rightFooter>
      <a-button type="primary">确认</a-button>
    </template>
    <div class="my-2">
      <h3>success</h3>
@@ -73,15 +73,12 @@
      <a-button type="dashed" class="ml-2" disabled> 禁用 </a-button>
      <a-button type="dashed" class="ml-2" loading> loading </a-button>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Alert } from 'ant-design-vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert },
    setup() {
      return {};
    },
    components: { PageWrapper },
  });
</script>
src/views/demo/comp/count-to/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4 count-to-demo">
  <PageWrapper title="数字动画示例">
    <Card>
      <CardGrid class="count-to-demo-card">
        <CountTo prefix="$" :startVal="1" :endVal="200000" :duration="8000" />
@@ -14,20 +14,20 @@
        <CountTo separator="-" :startVal="10000" :endVal="500000" :duration="8000" />
      </CardGrid>
    </Card>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Card } from 'ant-design-vue';
  import { CountTo } from '/@/components/CountTo/index';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: {
      Card,
      CardGrid: Card.Grid,
      CountTo,
    },
    setup() {
      return {};
      PageWrapper,
    },
  });
</script>
src/views/demo/comp/desc/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="详情组件示例">
    <Description
      title="基础示例"
      :collapseOptions="{ canExpand: true, helpMessage: 'help me' }"
@@ -20,13 +20,14 @@
    <Description @register="register" class="mt-4" />
    <Description @register="register1" class="mt-4" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Alert } from 'ant-design-vue';
  import { Description, DescItem, useDescription } from '/@/components/Description/index';
  const mockData: any = {
  import { PageWrapper } from '/@/components/Page';
  const mockData: Recordable = {
    username: 'test',
    nickName: 'VB',
    age: 25,
@@ -63,7 +64,7 @@
    },
  ];
  export default defineComponent({
    components: { Description, Alert },
    components: { Description, PageWrapper },
    setup() {
      const [register] = useDescription({
        title: 'useDescription',
src/views/demo/comp/drawer/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="px-10 py-4">
  <PageWrapper title="抽屉组件使用示例">
    <Alert message="使用 useDrawer 进行抽屉操作" show-icon />
    <a-button type="primary" class="my-4" @click="openDrawerLoading">打开Drawer</a-button>
@@ -20,7 +20,7 @@
    <Drawer3 @register="register3" />
    <Drawer4 @register="register4" />
    <Drawer5 @register="register5" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
@@ -31,9 +31,10 @@
  import Drawer3 from './Drawer3.vue';
  import Drawer4 from './Drawer4.vue';
  import Drawer5 from './Drawer5.vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert, Drawer1, Drawer2, Drawer3, Drawer4, Drawer5 },
    components: { Alert, PageWrapper, Drawer1, Drawer2, Drawer3, Drawer4, Drawer5 },
    setup() {
      const [register1, { openDrawer: openDrawer1, setDrawerProps }] = useDrawer();
      const [register2, { openDrawer: openDrawer2 }] = useDrawer();
src/views/demo/comp/lazy/Transition.vue
@@ -1,6 +1,5 @@
<template>
  <div class="p-4 lazy-base-demo">
    <Alert message="自定义动画" description="懒加载组件显示动画" type="info" show-icon />
  <PageWrapper title="懒加载自定义动画示例" content="懒加载组件显示动画">
    <div class="lazy-base-demo-wrap">
      <h1>向下滚动</h1>
@@ -10,18 +9,17 @@
        </LazyContainer>
      </div>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Skeleton, Alert } from 'ant-design-vue';
  import { Skeleton } from 'ant-design-vue';
  import TargetContent from './TargetContent.vue';
  import { LazyContainer } from '/@/components/Container/index';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { LazyContainer, TargetContent, Skeleton, Alert },
    setup() {
      return {};
    },
    components: { LazyContainer, TargetContent, Skeleton, PageWrapper },
  });
</script>
<style lang="less">
src/views/demo/comp/lazy/index.vue
@@ -1,6 +1,5 @@
<template>
  <div class="p-4 lazy-base-demo">
    <Alert message="基础示例" description="向下滚动到可见区域才会加载组件" type="info" show-icon />
  <PageWrapper title="懒加载基础示例" content="向下滚动到可见区域才会加载组件">
    <div class="lazy-base-demo-wrap">
      <h1>向下滚动</h1>
@@ -13,18 +12,17 @@
        </LazyContainer>
      </div>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Skeleton, Alert } from 'ant-design-vue';
  import { Skeleton } from 'ant-design-vue';
  import TargetContent from './TargetContent.vue';
  import { LazyContainer } from '/@/components/Container/index';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { LazyContainer, TargetContent, Skeleton, Alert },
    setup() {
      return {};
    },
    components: { LazyContainer, PageWrapper, TargetContent, Skeleton },
  });
</script>
<style lang="less">
src/views/demo/comp/loading/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-5" ref="wrapEl" v-loading="loadingRef" loading-tip="加载中...">
  <PageWrapper v-loading="loadingRef" loading-tip="加载中..." title="Loading组件示例">
    <a-alert message="组件方式" />
    <a-button class="my-4 mr-4" type="primary" @click="openCompFullLoading">全屏 Loading</a-button>
    <a-button class="my-4" type="primary" @click="openCompAbsolute">容器内 Loading</a-button>
@@ -14,13 +14,15 @@
    <a-button class="my-4 mr-4" type="primary" @click="openDirectiveLoading">
      打开指令Loading
    </a-button>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, reactive, toRefs, ref } from 'vue';
  import { Loading, useLoading } from '/@/components/Loading';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Loading },
    components: { Loading, PageWrapper },
    setup() {
      const wrapEl = ref<ElRef>(null);
src/views/demo/comp/modal/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="px-10 py-4">
  <PageWrapper title="modal组件使用示例">
    <Alert
      message="使用 useModal 进行弹窗操作,默认可以拖动,可以通过 draggable
    参数进行控制是否可以拖动/全屏"
@@ -24,7 +24,7 @@
    <Modal2 @register="register2" />
    <Modal3 @register="register3" />
    <Modal4 @register="register4" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
@@ -34,8 +34,10 @@
  import Modal2 from './Modal2.vue';
  import Modal3 from './Modal3.vue';
  import Modal4 from './Modal4.vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert, Modal1, Modal2, Modal3, Modal4 },
    components: { Alert, Modal1, Modal2, Modal3, Modal4, PageWrapper },
    setup() {
      const [register1, { openModal: openModal1, setModalProps }] = useModal();
      const [register2, { openModal: openModal2 }] = useModal();
src/views/demo/comp/qrcode/index.vue
@@ -1,68 +1,76 @@
<template>
  <div class="p-4 flex flex-wrap">
    <CollapseContainer title="基础示例" :canExpan="true" class="text-center mb-6 qrcode-demo-item">
      <QrCode :value="qrCodeUrl" />
    </CollapseContainer>
  <PageWrapper title="二维码组件使用示例">
    <div class="flex flex-wrap">
      <CollapseContainer
        title="基础示例"
        :canExpan="true"
        class="text-center mb-6 qrcode-demo-item"
      >
        <QrCode :value="qrCodeUrl" />
      </CollapseContainer>
    <CollapseContainer title="渲染成img标签示例" class="text-center mb-6 qrcode-demo-item">
      <QrCode :value="qrCodeUrl" tag="img" />
    </CollapseContainer>
      <CollapseContainer title="渲染成img标签示例" class="text-center mb-6 qrcode-demo-item">
        <QrCode :value="qrCodeUrl" tag="img" />
      </CollapseContainer>
    <CollapseContainer title="配置样式示例" class="text-center mb-6 qrcode-demo-item">
      <QrCode
        :value="qrCodeUrl"
        :options="{
          color: { dark: '#55D187' },
        }"
      />
    </CollapseContainer>
      <CollapseContainer title="配置样式示例" class="text-center mb-6 qrcode-demo-item">
        <QrCode
          :value="qrCodeUrl"
          :options="{
            color: { dark: '#55D187' },
          }"
        />
      </CollapseContainer>
    <CollapseContainer title="本地logo示例" class="text-center mb-6 qrcode-demo-item">
      <QrCode :value="qrCodeUrl" :logo="LogoImg" />
    </CollapseContainer>
      <CollapseContainer title="本地logo示例" class="text-center mb-6 qrcode-demo-item">
        <QrCode :value="qrCodeUrl" :logo="LogoImg" />
      </CollapseContainer>
    <CollapseContainer title="在线logo示例" class="text-center mb-6 qrcode-demo-item">
      <QrCode
        :value="qrCodeUrl"
        logo="https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png"
        :options="{
          color: { dark: '#55D187' },
        }"
      />
    </CollapseContainer>
      <CollapseContainer title="在线logo示例" class="text-center mb-6 qrcode-demo-item">
        <QrCode
          :value="qrCodeUrl"
          logo="https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png"
          :options="{
            color: { dark: '#55D187' },
          }"
        />
      </CollapseContainer>
    <CollapseContainer title="logo配置示例" class="text-center mb-6 qrcode-demo-item">
      <QrCode
        :value="qrCodeUrl"
        :logo="{
          src: 'https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png',
          logoSize: 0.2,
          borderSize: 0.05,
          borderRadius: 50,
          bgColor: 'blue',
        }"
      />
    </CollapseContainer>
      <CollapseContainer title="logo配置示例" class="text-center mb-6 qrcode-demo-item">
        <QrCode
          :value="qrCodeUrl"
          :logo="{
            src: 'https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png',
            logoSize: 0.2,
            borderSize: 0.05,
            borderRadius: 50,
            bgColor: 'blue',
          }"
        />
      </CollapseContainer>
    <CollapseContainer title="下载示例" class="text-center qrcode-demo-item">
      <QrCode :value="qrCodeUrl" ref="qrRef" :logo="LogoImg" />
      <a-button class="mb-2" type="primary" @click="download"> 下载 </a-button>
      <div class="msg">(在线logo会导致图片跨域,需要下载图片需要自行解决跨域问题)</div>
    </CollapseContainer>
      <CollapseContainer title="下载示例" class="text-center qrcode-demo-item">
        <QrCode :value="qrCodeUrl" ref="qrRef" :logo="LogoImg" />
        <a-button class="mb-2" type="primary" @click="download"> 下载 </a-button>
        <div class="msg">(在线logo会导致图片跨域,需要下载图片需要自行解决跨域问题)</div>
      </CollapseContainer>
    <CollapseContainer title="配置大小示例" class="text-center qrcode-demo-item">
      <QrCode :value="qrCodeUrl" :width="300" />
    </CollapseContainer>
  </div>
      <CollapseContainer title="配置大小示例" class="text-center qrcode-demo-item">
        <QrCode :value="qrCodeUrl" :width="300" />
      </CollapseContainer>
    </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref, unref } from 'vue';
  import { QrCode, QrCodeActionType } from '/@/components/Qrcode/index';
  import LogoImg from '/@/assets/images/logo.png';
  import { CollapseContainer } from '/@/components/Container/index';
  import { PageWrapper } from '/@/components/Page';
  const qrCodeUrl = 'https://www.vvbin.cn';
  export default defineComponent({
    components: { CollapseContainer, QrCode },
    components: { CollapseContainer, QrCode, PageWrapper },
    setup() {
      const qrRef = ref<Nullable<QrCodeActionType>>(null);
      function download() {
src/views/demo/comp/scroll/Action.vue
@@ -1,7 +1,5 @@
<template>
  <div class="p-4">
    <Alert message="抽取el-scrollbar,并对其进行扩展,滚动条美化,适用于各个浏览器" type="info" />
  <PageWrapper title="滚动组件函数示例" content="基于el-scrollbar">
    <div class="my-4">
      <a-button @click="scrollTo(100)" class="mr-2">滚动到100px位置</a-button>
      <a-button @click="scrollTo(800)" class="mr-2">滚动到800px位置</a-button>
@@ -17,15 +15,16 @@
        </ul>
      </ScrollContainer>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref, unref } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { ScrollContainer, ScrollActionType } from '/@/components/Container/index';
  import { Alert } from 'ant-design-vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { CollapseContainer, ScrollContainer, Alert },
    components: { CollapseContainer, ScrollContainer, PageWrapper },
    setup() {
      const scrollRef = ref<Nullable<ScrollActionType>>(null);
      const getScroll = () => {
src/views/demo/comp/scroll/VirtualScroll.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4 virtual-scroll-demo">
  <PageWrapper class="virtual-scroll-demo">
    <Divider>基础滚动示例</Divider>
    <div class="virtual-scroll-demo-wrap">
      <VScroll :itemHeight="41" :items="data" :height="300" :width="300">
@@ -17,15 +17,16 @@
        </template>
      </VScroll>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { VScroll } from '/@/components/VirtualScroll/index';
  import { Divider } from 'ant-design-vue';
  const data: any[] = (() => {
    const arr: any[] = [];
  import { PageWrapper } from '/@/components/Page';
  const data: Recordable[] = (() => {
    const arr: Recordable[] = [];
    for (let index = 1; index < 20000; index++) {
      arr.push({
        title: '列表项' + index,
@@ -34,7 +35,7 @@
    return arr;
  })();
  export default defineComponent({
    components: { VScroll: VScroll, Divider },
    components: { VScroll: VScroll, Divider, PageWrapper },
    setup() {
      return { data: data };
    },
src/views/demo/comp/scroll/index.vue
@@ -1,6 +1,5 @@
<template>
  <div class="p-4">
    <Alert message="抽取el-scrollbar,并对其进行扩展,滚动条美化,适用于各个浏览器" type="info" />
  <PageWrapper title="滚动组件示例" content="基于el-scrollbar">
    <div class="scroll-wrap">
      <ScrollContainer class="mt-4">
        <ul class="p-3">
@@ -10,18 +9,16 @@
        </ul>
      </ScrollContainer>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { ScrollContainer } from '/@/components/Container/index';
  import { Alert } from 'ant-design-vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { CollapseContainer, ScrollContainer, Alert },
    setup() {
      return {};
    },
    components: { CollapseContainer, ScrollContainer, PageWrapper },
  });
</script>
<style lang="less" scoped>
src/views/demo/comp/strength-meter/index.vue
@@ -1,23 +1,25 @@
<template>
  <div class="p-4 flex justify-center">
    <div class="demo-wrap p-10">
      <StrengthMeter placeholder="默认" />
      <StrengthMeter placeholder="禁用" disabled />
      <br />
      <StrengthMeter placeholder="隐藏input" :show-input="false" value="!@#qwe12345" />
  <PageWrapper title="密码强度校验组件">
    <div class="flex justify-center">
      <div class="demo-wrap p-10">
        <StrengthMeter placeholder="默认" />
        <StrengthMeter placeholder="禁用" disabled />
        <br />
        <StrengthMeter placeholder="隐藏input" :show-input="false" value="!@#qwe12345" />
      </div>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { StrengthMeter } from '/@/components/StrengthMeter';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: {
      StrengthMeter,
    },
    setup() {
      return {};
      PageWrapper,
    },
  });
</script>
src/views/demo/comp/transition/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="动画组件示例">
    <div class="flex">
      <Select
        :options="options"
@@ -12,11 +12,12 @@
    <component :is="`${value}Transition`">
      <div class="box" v-show="show"></div>
    </component>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { Select } from 'ant-design-vue';
  import { PageWrapper } from '/@/components/Page';
  import {
    FadeTransition,
    ScaleTransition,
@@ -57,6 +58,7 @@
  export default defineComponent({
    components: {
      Select,
      PageWrapper,
      FadeTransition,
      ScaleTransition,
      SlideYTransition,
@@ -89,6 +91,6 @@
    width: 150px;
    height: 150px;
    margin-top: 20px;
    background: pink;
    background: rgb(126, 170, 236);
  }
</style>
src/views/demo/comp/upload/index.vue
@@ -1,18 +1,19 @@
<template>
  <div class="p-4">
  <PageWrapper title="上传组件示例">
    <a-alert message="基础示例" class="my-5"></a-alert>
    <BasicUpload :maxSize="20" :maxNumber="10" @change="handleChange" :api="uploadApi" />
    <a-alert message="嵌入表单,加入表单校验" class="my-5"></a-alert>
    <BasicForm @register="register" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { BasicUpload } from '/@/components/Upload';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { PageWrapper } from '/@/components/Page';
  import { uploadApi } from '/@/api/sys/upload';
@@ -31,7 +32,7 @@
    },
  ];
  export default defineComponent({
    components: { BasicUpload, BasicForm },
    components: { BasicUpload, BasicForm, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
      const [register] = useForm({
src/views/demo/comp/verify/Rotate.vue
@@ -1,17 +1,20 @@
<template>
  <div class="p-10">
  <PageWrapper title="旋转校验示例">
    <div class="flex justify-center p-4 items-center bg-gray-700">
      <RotateDragVerify :src="img" ref="el" @success="handleSuccess" />
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { RotateDragVerify } from '/@/components/Verify/index';
  import img from '/@/assets/images/header.jpg';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { RotateDragVerify },
    components: { RotateDragVerify, PageWrapper },
    setup() {
      const handleSuccess = () => {
        console.log('success!');
src/views/demo/comp/verify/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-10">
  <PageWrapper title="拖动校验示例">
    <div class="flex justify-center p-4 items-center bg-gray-700">
      <BasicDragVerify ref="el1" @success="handleSuccess" />
      <a-button type="primary" class="ml-2" @click="handleBtnClick(el1)">还原</a-button>
@@ -48,15 +48,17 @@
      </BasicDragVerify>
      <a-button type="primary" class="ml-2" @click="handleBtnClick(el5)">还原</a-button>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { BasicDragVerify, DragVerifyActionType, PassingData } from '/@/components/Verify/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { BugOutlined, RightOutlined } from '@ant-design/icons-vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicDragVerify, BugOutlined, RightOutlined },
    components: { BasicDragVerify, BugOutlined, RightOutlined, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
      const el1 = ref<Nullable<DragVerifyActionType>>(null);
src/views/demo/editor/markdown/Editor.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="MarkDown组件嵌入Form示例">
    <CollapseContainer title="MarkDown表单">
      <BasicForm
        :labelWidth="100"
@@ -9,7 +9,7 @@
      >
      </BasicForm>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, h } from 'vue';
@@ -17,6 +17,7 @@
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { MarkDown } from '/@/components/Markdown';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
@@ -43,7 +44,7 @@
    },
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
src/views/demo/editor/markdown/index.vue
@@ -1,14 +1,16 @@
<template>
  <div class="p-4">
  <PageWrapper title="MarkDown组件示例">
    <a-button @click="toggleTheme" class="mb-2" type="primary">黑暗主题</a-button>
    <MarkDown :value="value" @change="handleChange" ref="markDownRef" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref, unref } from 'vue';
  import { MarkDown, MarkDownActionType } from '/@/components/Markdown';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { MarkDown },
    components: { MarkDown, PageWrapper },
    setup() {
      const markDownRef = ref<Nullable<MarkDownActionType>>(null);
      const valueRef = ref(`
src/views/demo/editor/tinymce/Editor.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="富文本嵌入表单示例">
    <CollapseContainer title="富文本表单">
      <BasicForm
        :labelWidth="100"
@@ -9,7 +9,7 @@
      >
      </BasicForm>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, h } from 'vue';
@@ -17,6 +17,7 @@
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { Tinymce } from '/@/components/Tinymce/index';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
@@ -43,7 +44,7 @@
    },
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
src/views/demo/editor/tinymce/index.vue
@@ -1,14 +1,15 @@
<template>
  <div class="p-4">
  <PageWrapper title="富文本组件示例">
    <Tinymce v-model="value" @change="handleChange" width="100%" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { Tinymce } from '/@/components/Tinymce/index';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Tinymce },
    components: { Tinymce, PageWrapper },
    setup() {
      const value = ref('hello world!');
      function handleChange(value: string) {
src/views/demo/excel/ArrayExport.vue
@@ -1,11 +1,11 @@
<template>
  <div class="m-4">
  <PageWrapper title="导出示例" content="根据数组格式的数据进行导出">
    <BasicTable title="基础表格" :columns="columns" :dataSource="data">
      <template #toolbar>
        <a-button @click="aoaToExcel">导出</a-button>
      </template>
    </BasicTable>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
@@ -13,9 +13,10 @@
  import { BasicTable } from '/@/components/Table';
  import { aoaToSheetXlsx } from '/@/components/Excel';
  import { arrHeader, arrData, columns, data } from './data';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTable },
    components: { BasicTable, PageWrapper },
    setup() {
      function aoaToExcel() {
        // 保证data顺序与header一致
src/views/demo/excel/CustomExport.vue
@@ -1,12 +1,12 @@
<template>
  <div class="m-4">
  <PageWrapper title="导出示例" content="可以选择导出格式">
    <BasicTable title="基础表格" :columns="columns" :dataSource="data">
      <template #toolbar>
        <a-button @click="openModal">导出</a-button>
      </template>
    </BasicTable>
    <ExpExcelModel @register="register" @success="defaultHeader" />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
@@ -15,9 +15,10 @@
  import { jsonToSheetXlsx, ExpExcelModel, ExportModalResult } from '/@/components/Excel';
  import { columns, data } from './data';
  import { useModal } from '/@/components/Modal';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTable, ExpExcelModel },
    components: { BasicTable, ExpExcelModel, PageWrapper },
    setup() {
      function defaultHeader({ filename, bookType }: ExportModalResult) {
        // 默认Object.keys(data[0])作为header
src/views/demo/excel/ImportExcel.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="excel数据导入示例">
    <ImpExcel @success="loadDataSuccess">
      <a-button class="m-3">导入Excel</a-button>
    </ImpExcel>
@@ -10,16 +10,17 @@
      :columns="table.columns"
      :dataSource="table.dataSource"
    ></BasicTable>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { ImpExcel, ExcelData } from '/@/components/Excel';
  import { BasicTable, BasicColumn } from '/@/components/Table';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTable, ImpExcel },
    components: { BasicTable, ImpExcel, PageWrapper },
    setup() {
      const tableListRef = ref<
src/views/demo/excel/JsonExport.vue
@@ -1,12 +1,12 @@
<template>
  <div class="m-4">
  <PageWrapper title="导出示例" content="根据JSON格式的数据进行导出">
    <BasicTable title="基础表格" :columns="columns" :dataSource="data">
      <template #toolbar>
        <a-button @click="defaultHeader">导出:默认头部</a-button>
        <a-button @click="customHeader">导出:自定义头部</a-button>
      </template>
    </BasicTable>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
@@ -14,9 +14,10 @@
  import { BasicTable } from '/@/components/Table';
  import { jsonToSheetXlsx } from '/@/components/Excel';
  import { columns, data } from './data';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTable },
    components: { BasicTable, PageWrapper },
    setup() {
      function defaultHeader() {
        // 默认Object.keys(data[0])作为header
src/views/demo/feat/breadcrumb/ChildrenList.vue
@@ -1,10 +1,13 @@
<template>
  <div class="p-5">
  <PageWrapper title="层级面包屑示例" content="子级页面面包屑会添加到当前层级后面">
    <router-link to="/feat/breadcrumb/children/childrenDetail">进入子级详情页</router-link>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({});
  export default defineComponent({
    components: { PageWrapper },
  });
</script>
src/views/demo/feat/breadcrumb/FlatList.vue
@@ -1,10 +1,13 @@
<template>
  <div class="p-5">
  <PageWrapper title="平级面包屑示例" content="子级页面面包屑会覆盖当前层级">
    <router-link to="/feat/breadcrumb/flatDetail">进入平级详情页</router-link>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({});
  export default defineComponent({
    components: { PageWrapper },
  });
</script>
src/views/demo/feat/click-out-side/index.vue
@@ -1,19 +1,19 @@
<template>
  <div class="p-10">
    <Alert message="点内外部触发事件" show-icon></Alert>
    <ClickOutSide @clickOutside="handleClickOutside" class="flex justify-center mt-10">
  <PageWrapper title="点内外部触发事件">
    <ClickOutSide @clickOutside="handleClickOutside" class="flex justify-center">
      <div @click="innerClick" class="demo-box">
        {{ text }}
      </div>
    </ClickOutSide>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { Alert } from 'ant-design-vue';
  import { ClickOutSide } from '/@/components/ClickOutSide';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { ClickOutSide, Alert },
    components: { ClickOutSide, PageWrapper },
    setup() {
      const text = ref('Click');
      function handleClickOutside() {
src/views/demo/feat/context-menu/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="右键菜单示例">
    <CollapseContainer title="Simple">
      <a-button type="primary" @contextmenu="handleContext">Right Click on me</a-button>
    </CollapseContainer>
@@ -7,15 +7,17 @@
    <CollapseContainer title="Multiple" class="mt-4">
      <a-button type="primary" @contextmenu="handleMultipleContext">Right Click on me</a-button>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { useContextMenu } from '/@/hooks/web/useContextMenu';
  import { CollapseContainer } from '/@/components/Container';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { CollapseContainer },
    components: { CollapseContainer, PageWrapper },
    setup() {
      const [createContextMenu] = useContextMenu();
      const { createMessage } = useMessage();
src/views/demo/feat/copy/index.vue
@@ -1,22 +1,23 @@
<template>
  <div class="p-4">
  <PageWrapper title="文本复制示例">
    <CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Copy Example">
      <div class="flex justify-center">
        <a-input placeholder="请输入" v-model:value="value" />
        <a-button type="primary" @click="handleCopy">Copy</a-button>
      </div>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, unref, ref } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    name: 'Copy',
    components: { CollapseContainer },
    components: { CollapseContainer, PageWrapper },
    setup() {
      const valueRef = ref('');
      const { createMessage } = useMessage();
src/views/demo/feat/download/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-5 demo-box">
  <PageWrapper title="文件下载示例">
    <a-alert message="根据后台接口文件流下载" />
    <a-button type="primary" class="my-4" @click="handleDownByData"> 文件流下载 </a-button>
@@ -13,7 +13,7 @@
    <a-button type="primary" class="my-4" @click="handleDownloadByOnlineUrl">
      图片Url下载
    </a-button>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
@@ -24,7 +24,10 @@
    downloadByOnlineUrl,
  } from '/@/utils/file/download';
  import imgBase64 from './imgBase64';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { PageWrapper },
    setup() {
      function handleDownByData() {
        downloadByData('text content', 'testName.txt');
src/views/demo/feat/full-screen/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="全屏示例">
    <CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Window Full Screen">
      <a-button type="primary" @click="enterFullscreen" class="mr-2">
        Enter Window Full Screen
@@ -25,14 +25,16 @@
    >
      <a-button type="primary" @click="toggleDom" class="mr-2"> Exit Dom Full Screen </a-button>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useFullscreen } from '/@/hooks/web/useFullScreen';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { CollapseContainer },
    components: { CollapseContainer, PageWrapper },
    setup() {
      const domRef = ref<Nullable<HTMLElement>>(null);
      const {
src/views/demo/feat/icon/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="Icon组件示例">
    <CollapseContainer title="Antv Icon使用 (直接按需引入相应组件即可)">
      <div class="flex justify-around">
        <GithubFilled :style="{ fontSize: '30px' }" />
@@ -27,7 +27,7 @@
      description="Icon组件基本包含所有的图标,在下面网址内你可以查询到你想要的任何图标。并且打包只会打包所用到的图标。唯一不足的可能就是需要连接外网进行使用。"
    />
    <a-button type="link" @click="toIconify">Iconify 图标大全</a-button>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
@@ -46,9 +46,11 @@
  import Icon from '/@/components/Icon/index';
  import { openWindow } from '/@/utils';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: {
      PageWrapper,
      CollapseContainer,
      GithubFilled,
      QqCircleFilled,
src/views/demo/feat/img-preview/index.vue
@@ -1,24 +1,26 @@
<template>
  <div class="p-4">
  <PageWrapper title="图片预览示例">
    <Alert message="有预览图" type="info" />
    <div class="flex justify-center mt-4">
      <img :src="img" v-for="img in imgList" :key="img" class="mr-2" @click="handleClick(img)" />
    </div>
    <Alert message="无预览图" type="info" />
    <a-button @click="handlePreview" type="primary" class="mt-4">预览图片</a-button>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Alert } from 'ant-design-vue';
  import { createImgPreview } from '/@/components/Preview/index';
  import { PageWrapper } from '/@/components/Page';
  const imgList: string[] = [
    'https://picsum.photos/id/66/346/216',
    'https://picsum.photos/id/67/346/216',
    'https://picsum.photos/id/68/346/216',
  ];
  export default defineComponent({
    components: { Alert },
    components: { Alert, PageWrapper },
    setup() {
      function handleClick(img: string) {
        createImgPreview({ imageList: [img] });
src/views/demo/feat/msg/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="消息示例">
    <CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Message">
      <a-button @click="infoMsg('Info message')" class="mr-2"> Info </a-button>
      <a-button @click="successMsg('Success message')" class="mr-2" color="success">
@@ -32,14 +32,16 @@
    >
      <a-button @click="handleNotify" color="success" class="mr-2">Success</a-button>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { CollapseContainer },
    components: { CollapseContainer, PageWrapper },
    setup() {
      const {
        createMessage,
src/views/demo/feat/ripple/index.vue
@@ -1,19 +1,17 @@
<template>
  <div class="p-4">
  <PageWrapper title="Ripple示例">
    <div class="demo-box" v-ripple>content</div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Alert } from 'ant-design-vue';
  import RippleDirective from '/@/directives/ripple';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert },
    components: { PageWrapper },
    directives: {
      Ripple: RippleDirective,
    },
    setup() {
      return {};
    },
  });
</script>
src/views/demo/feat/tab-params/index.vue
@@ -1,16 +1,19 @@
<template>
  <div class="p-4">
  <PageWrapper title="带参数标签页" content="支持带参数多tab缓存">
    Current Param : {{ params }}
    <br />
    Keep Alive
    <input />
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { computed, defineComponent, unref } from 'vue';
  import { useRouter } from 'vue-router';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    name: 'TestTab',
    components: { PageWrapper },
    setup() {
      const { currentRoute } = useRouter();
      return {
src/views/demo/feat/tabs/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="标签页操作示例">
    <CollapseContainer title="在下面输入框输入文本,切换后回来内容会保存">
      <a-input placeholder="请输入" />
    </CollapseContainer>
@@ -12,15 +12,16 @@
      <a-button class="mr-2" @click="closeCurrent">关闭当前</a-button>
      <a-button class="mr-2" @click="refreshPage">刷新当前</a-button>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useTabs } from '/@/hooks/web/useTabs';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    name: 'TabsDemo',
    components: { CollapseContainer },
    components: { CollapseContainer, PageWrapper },
    setup() {
      const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTabs();
src/views/demo/feat/watermark/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="水印示例">
    <CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Global WaterMark">
      <a-button type="primary" class="mr-2" @click="setWatermark('WaterMark Info')">
        Create
@@ -9,15 +9,16 @@
        Reset
      </a-button>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useWatermark } from '/@/hooks/web/useWatermark';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { CollapseContainer },
    components: { CollapseContainer, PageWrapper },
    setup() {
      const areaRef = ref<Nullable<HTMLElement>>(null);
      const { setWatermark, clear } = useWatermark();
src/views/demo/form/AdvancedForm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="可折叠表单示例">
    <CollapseContainer title="基础收缩示例">
      <BasicForm @register="register" />
    </CollapseContainer>
@@ -7,12 +7,13 @@
    <CollapseContainer title="超过3行自动收起" class="mt-4">
      <BasicForm @register="register1" />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { CollapseContainer } from '/@/components/Container/index';
  import { PageWrapper } from '/@/components/Page';
  const getSchamas = (): FormSchema[] => {
    return [
@@ -148,7 +149,7 @@
    ];
  }
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const [register] = useForm({
        labelWidth: 120,
src/views/demo/form/CustomerForm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="自定义组件示例">
    <CollapseContainer title="自定义表单">
      <BasicForm @register="register" @submit="handleSubmit">
        <template #f3="{ model, field }">
@@ -7,7 +7,7 @@
        </template>
      </BasicForm>
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, h } from 'vue';
@@ -15,6 +15,8 @@
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { Input } from 'ant-design-vue';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
      field: 'field1',
@@ -60,7 +62,7 @@
    },
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
      const [register, { setProps }] = useForm({
src/views/demo/form/DynamicForm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="动态表单示例">
    <div class="mb-4">
      <a-button @click="changeLabel3" class="mr-2">更改字段3label</a-button>
      <a-button @click="changeLabel34" class="mr-2">同时更改字段3,4label</a-button>
@@ -13,12 +13,14 @@
    <CollapseContainer class="mt-5" title="componentProps动态改变">
      <BasicForm @register="register1" />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { CollapseContainer } from '/@/components/Container/index';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
      field: 'field1',
@@ -177,7 +179,7 @@
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const [
        register,
src/views/demo/form/RefForm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="Ref操作示例">
    <div class="mb-4">
      <a-button @click="setProps({ labelWidth: 150 })" class="mr-2">更改labelWidth</a-button>
      <a-button @click="setProps({ labelWidth: 120 })" class="mr-2">还原labelWidth</a-button>
@@ -62,13 +62,15 @@
        :actionColOptions="{ span: 24 }"
      />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { BasicForm, FormSchema, FormActionType, FormProps } from '/@/components/Form/index';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
      field: 'field1',
@@ -165,7 +167,7 @@
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const formElRef = ref<Nullable<FormActionType>>(null);
      const { createMessage } = useMessage();
src/views/demo/form/RuleForm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="表单校验示例">
    <div class="mb-4">
      <a-button @click="validateForm" class="mr-2">手动校验表单</a-button>
      <a-button @click="resetValidate" class="mr-2">清空校验信息</a-button>
@@ -9,13 +9,15 @@
    <CollapseContainer title="表单校验">
      <BasicForm @register="register" @submit="handleSubmit" />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
      field: 'field1',
@@ -141,7 +143,7 @@
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
      const [register, { validateFields, clearValidate, getFieldsValue, setFieldsValue }] = useForm(
src/views/demo/form/UseForm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="UseForm操作示例">
    <div class="mb-4">
      <a-button @click="setProps({ labelWidth: 150 })" class="mr-2">更改labelWidth</a-button>
      <a-button @click="setProps({ labelWidth: 120 })" class="mr-2">还原labelWidth</a-button>
@@ -56,13 +56,15 @@
    <CollapseContainer title="useForm示例">
      <BasicForm @register="register" @submit="handleSubmit" />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  const schemas: FormSchema[] = [
    {
      field: 'field1',
@@ -159,7 +161,7 @@
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
src/views/demo/form/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="m-4">
  <PageWrapper title="表单基础示例">
    <CollapseContainer title="基础示例">
      <BasicForm
        autoFocusFirstItem
@@ -9,13 +9,14 @@
        @submit="handleSubmit"
      />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { BasicForm, FormSchema } from '/@/components/Form/index';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  import { optionsListApi } from '/@/api/demo/select';
  const schemas: FormSchema[] = [
@@ -238,7 +239,7 @@
  ];
  export default defineComponent({
    components: { BasicForm, CollapseContainer },
    components: { BasicForm, CollapseContainer, PageWrapper },
    setup() {
      const check = ref(null);
      const { createMessage } = useMessage();
src/views/demo/page/desc/basic/index.vue
@@ -1,37 +1,34 @@
<template>
  <div>
    <a-page-header title="基础详情页" :ghost="false" />
  <PageWrapper title="基础详情页" contentBackgrond>
    <Description
      size="middle"
      title="退款申请"
      :bordered="false"
      :column="3"
      :data="refundData"
      :schema="refundSchema"
    />
    <a-divider />
    <Description
      size="middle"
      title="用户信息"
      :bordered="false"
      :column="3"
      :data="personData"
      :schema="personSchema"
    />
    <a-divider />
    <div class="m-5 desc-wrap">
      <Description
        size="middle"
        title="退款申请"
        :bordered="false"
        :column="3"
        :data="refundData"
        :schema="refundSchema"
      />
      <a-divider />
      <Description
        size="middle"
        title="用户信息"
        :bordered="false"
        :column="3"
        :data="personData"
        :schema="personSchema"
      />
      <a-divider />
      <BasicTable @register="registerRefundTable" />
      <a-divider />
      <BasicTable @register="registerTimeTable" />
    </div>
  </div>
    <BasicTable @register="registerRefundTable" />
    <a-divider />
    <BasicTable @register="registerTimeTable" />
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Description } from '/@/components/Description/index';
  import { BasicTable, useTable } from '/@/components/Table';
  import { PageWrapper } from '/@/components/Page';
  import {
    refundSchema,
@@ -44,7 +41,7 @@
    refundTimeTableData,
  } from './data';
  export default defineComponent({
    components: { Description, BasicTable },
    components: { Description, BasicTable, PageWrapper },
    setup() {
      const [registerRefundTable] = useTable({
        title: '退货商品',
src/views/demo/page/desc/high/index.vue
@@ -1,17 +1,19 @@
<template>
  <div>
    <a-page-header title="单号:234231029431" class="high-desc">
      <template #extra>
        <a-button key="3"> 操作一 </a-button>
        <a-button key="2"> 操作二 </a-button>
        <a-button key="1" type="primary"> 主操作 </a-button>
      </template>
      <template #footer>
        <a-tabs default-active-key="1">
          <a-tab-pane key="1" tab="详情" />
          <a-tab-pane key="2" tab="规则" />
        </a-tabs>
      </template>
  <PageWrapper title="单号:234231029431" contentBackgrond>
    <template #extra>
      <a-button key="3"> 操作一 </a-button>
      <a-button key="2"> 操作二 </a-button>
      <a-button key="1" type="primary"> 主操作 </a-button>
    </template>
    <template #footer>
      <a-tabs default-active-key="1">
        <a-tab-pane key="1" tab="详情" />
        <a-tab-pane key="2" tab="规则" />
      </a-tabs>
    </template>
    <div class="m-4 pt-4 desc-wrap">
      <a-descriptions size="small" :column="2">
        <a-descriptions-item label="创建人"> 曲丽丽 </a-descriptions-item>
        <a-descriptions-item label="订购产品"> XX 服务 </a-descriptions-item>
@@ -20,9 +22,6 @@
        <a-descriptions-item label="生效日期"> 2017-07-07 ~ 2017-08-08 </a-descriptions-item>
        <a-descriptions-item label="备注"> 请于两个工作日内确认 </a-descriptions-item>
      </a-descriptions>
    </a-page-header>
    <div class="m-5 desc-wrap">
      <a-card title="流程进度" :bordered="false">
        <a-steps :current="1" progress-dot size="small">
          <a-step title="创建项目">
@@ -84,16 +83,17 @@
      </a-card>
      <BasicTable @register="registerTimeTable" />
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Description } from '/@/components/Description/index';
  import { BasicTable, useTable } from '/@/components/Table';
  import { PageWrapper } from '/@/components/Page';
  import { refundTimeTableSchema, refundTimeTableData } from './data';
  export default defineComponent({
    components: { Description, BasicTable },
    components: { Description, BasicTable, PageWrapper },
    setup() {
      const [registerTimeTable] = useTable({
        title: '退货进度',
@@ -110,8 +110,3 @@
    },
  });
</script>
<style lang="less" scoped>
  .high-desc {
    background: #fff;
  }
</style>
src/views/demo/page/form/basic/index.vue
@@ -1,21 +1,21 @@
<template>
  <div>
    <a-page-header title="基础表单" :ghost="false">
      表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。
    </a-page-header>
    <div class="m-5 form-wrap">
      <BasicForm @register="register" />
    </div>
  </div>
  <PageWrapper
    title="基础表单"
    contentBackgrond
    content=" 表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。"
  >
    <BasicForm @register="register" />
  </PageWrapper>
</template>
<script lang="ts">
  import { BasicForm, useForm } from '/@/components/Form';
  import { defineComponent } from 'vue';
  import { schemas } from './data';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicForm },
    components: { BasicForm, PageWrapper },
    setup() {
      const { createMessage } = useMessage();
      const [register, { validate, setProps }] = useForm({
src/views/demo/page/form/high/index.vue
@@ -1,38 +1,34 @@
<template>
  <div class="high-form">
    <a-page-header title="高级表单" :ghost="false">
      高级表单常见于一次性输入和提交大批量数据的场景。
    </a-page-header>
  <PageWrapper
    class="high-form"
    title="高级表单"
    contentBackgrond
    content=" 高级表单常见于一次性输入和提交大批量数据的场景。"
  >
    <a-card title="仓库管理" :bordered="false">
      <BasicForm @register="register" />
    </a-card>
    <a-card title="任务管理" :bordered="false" class="mt-5">
      <BasicForm @register="registerTask" />
    </a-card>
    <a-card title="成员管理" :bordered="false" class="mt-5">
      <PersonTable ref="tableRef" />
    </a-card>
    <div class="m-5">
      <a-card title="仓库管理" :bordered="false">
        <BasicForm @register="register" />
      </a-card>
      <a-card title="任务管理" :bordered="false" class="mt-5">
        <BasicForm @register="registerTask" />
      </a-card>
      <a-card title="成员管理" :bordered="false" class="mt-5">
        <PersonTable ref="tableRef" />
      </a-card>
    </div>
    <PageFooter>
      <template #right>
        <a-button type="primary" @click="submitAll">提交</a-button>
      </template>
    </PageFooter>
  </div>
    <template #rightFooter>
      <a-button type="primary" @click="submitAll">提交</a-button>
    </template>
  </PageWrapper>
</template>
<script lang="ts">
  import { BasicForm, useForm } from '/@/components/Form';
  import { defineComponent, ref } from 'vue';
  import PersonTable from './PersonTable.vue';
  import { PageFooter } from '/@/components/Page';
  import { PageWrapper } from '/@/components/Page';
  import { schemas, taskSchemas } from './data';
  export default defineComponent({
    components: { BasicForm, PersonTable, PageFooter },
    components: { BasicForm, PersonTable, PageWrapper },
    setup() {
      const tableRef = ref<{ getDataSource: () => any } | null>(null);
src/views/demo/page/form/step/index.vue
@@ -1,37 +1,37 @@
<template>
  <div>
    <a-page-header title="分步表单" :ghost="false">
      将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。
    </a-page-header>
    <div class="m-5 step-form-content">
      <div class="step-form-form">
        <a-steps :current="current">
          <a-step title="填写转账信息"> </a-step>
          <a-step title="确认转账信息"> </a-step>
          <a-step title="完成"> </a-step>
        </a-steps>
      </div>
      <div class="mt-5">
        <Step1 @next="handleStep1Next" v-show="current === 0" />
        <Step2
          @prev="handleStepPrev"
          @next="handleStep2Next"
          v-show="current === 1"
          v-if="initSetp2"
        />
        <Step3 v-show="current === 2" @redo="handleRedo" v-if="initSetp3" />
      </div>
  <PageWrapper
    title="分步表单"
    contentBackgrond
    content=" 将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"
  >
    <div class="step-form-form">
      <a-steps :current="current">
        <a-step title="填写转账信息"> </a-step>
        <a-step title="确认转账信息"> </a-step>
        <a-step title="完成"> </a-step>
      </a-steps>
    </div>
  </div>
    <div class="mt-5">
      <Step1 @next="handleStep1Next" v-show="current === 0" />
      <Step2
        @prev="handleStepPrev"
        @next="handleStep2Next"
        v-show="current === 1"
        v-if="initSetp2"
      />
      <Step3 v-show="current === 2" @redo="handleRedo" v-if="initSetp3" />
    </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref, reactive, toRefs } from 'vue';
  import Step1 from './Step1.vue';
  import Step2 from './Step2.vue';
  import Step3 from './Step3.vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Step1, Step2, Step3 },
    components: { Step1, Step2, Step3, PageWrapper },
    setup() {
      const current = ref(0);
src/views/demo/page/list/basic/index.vue
@@ -1,6 +1,5 @@
<template>
  <div :class="prefixCls">
    <a-page-header title="标准列表" :ghost="false" />
  <PageWrapper :class="prefixCls" title="标准列表">
    <div :class="`${prefixCls}__top`">
      <a-row :gutter="12">
        <a-col :span="8" :class="`${prefixCls}__top-col`">
@@ -47,16 +46,17 @@
        </template>
      </a-list>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { Progress } from 'ant-design-vue';
  import { defineComponent } from 'vue';
  import Icon from '/@/components/Icon/index';
  import { cardList } from './data';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Icon, Progress },
    components: { Icon, Progress, PageWrapper },
    setup() {
      return {
        prefixCls: 'list-basic',
@@ -73,7 +73,6 @@
  .list-basic {
    &__top {
      padding: 24px;
      margin: 24px 24px 0 24px;
      text-align: center;
      background: #fff;
@@ -100,7 +99,7 @@
    &__content {
      padding: 24px;
      margin: 12px 24px;
      margin-top: 12px;
      background: #fff;
      .list {
src/views/demo/page/list/card/data.tsx
@@ -3,7 +3,7 @@
  for (let i = 0; i < 12; i++) {
    result.push({
      title: 'Vben Admin',
      icon: 'logos:ant-design',
      icon: 'logos:vue',
      color: '#1890ff',
      active: '100',
      new: '1,799',
src/views/demo/page/list/card/index.vue
@@ -1,13 +1,13 @@
<template>
  <div :class="prefixCls">
    <a-page-header title="卡片列表" :ghost="false">
  <PageWrapper :class="prefixCls" title="卡片列表">
    <template #headerContent>
      基于Vue Next, TypeScript, Ant Design Vue实现的一套完整的企业级后台管理系统。
      <div :class="`${prefixCls}__link`">
        <a><Icon icon="bx:bx-paper-plane" color="#1890ff" /><span>开始</span></a>
        <a><Icon icon="carbon:warning" color="#1890ff" /><span>简介</span></a>
        <a><Icon icon="gg:loadbar-doc" color="#1890ff" /><span>文档</span></a>
      </div>
    </a-page-header>
    </template>
    <div :class="`${prefixCls}__content`">
      <a-list>
@@ -30,15 +30,16 @@
        </a-row>
      </a-list>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import Icon from '/@/components/Icon/index';
  import { cardList } from './data';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Icon },
    components: { Icon, PageWrapper },
    setup() {
      return {
        prefixCls: 'list-card',
@@ -60,11 +61,6 @@
      span {
        margin-left: 5px;
      }
    }
    &__content {
      padding: 12px 24px;
      // background: #fff;
    }
    &__card {
src/views/demo/page/list/search/index.vue
@@ -1,13 +1,13 @@
<template>
  <div :class="prefixCls">
    <a-page-header title="搜索列表" :ghost="false" :class="`${prefixCls}__header`">
  <PageWrapper :class="prefixCls" title="搜索列表">
    <template #headerContent>
      <BasicForm
        :class="`${prefixCls}__header-form`"
        :labelWidth="100"
        :schemas="schemas"
        :showActionButtonGroup="false"
      />
    </a-page-header>
    </template>
    <div :class="`${prefixCls}__container`">
      <a-list>
@@ -44,7 +44,7 @@
        </template>
      </a-list>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { Tag } from 'ant-design-vue';
@@ -52,9 +52,10 @@
  import Icon from '/@/components/Icon/index';
  import { BasicForm } from '/@/components/Form/index';
  import { actions, searchList, schemas } from './data';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Icon, Tag, BasicForm },
    components: { Icon, Tag, BasicForm, PageWrapper },
    setup() {
      return {
        prefixCls: 'list-search',
@@ -75,7 +76,6 @@
    &__container {
      padding: 12px;
      margin: 24px;
      background: #fff;
    }
src/views/demo/permission/back/Btn.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4 m-4 demo">
  <PageWrapper contentBackgrond title="按钮权限控制" contentClass="p-4">
    <Alert message="刷新后会还原" show-icon />
    <CurrentPermissionMode />
@@ -51,7 +51,7 @@
    <a-button v-auth="['1000', '2000']" color="error" class="mx-4">
      拥有code ['1000','2000']角色权限可见
    </a-button>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
@@ -62,8 +62,10 @@
  import { getPermCodeByUserId } from '/@/api/sys/user';
  import { permissionStore } from '/@/store/modules/permission';
  import { PermissionModeEnum } from '/@/enums/appEnum';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert, CurrentPermissionMode, Divider, Authority },
    components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority },
    setup() {
      const { hasPermission } = usePermission();
src/views/demo/permission/back/index.vue
@@ -1,9 +1,10 @@
<template>
  <div class="p-4 m-4 demo">
    <Alert
      message="目前mock了两组数据, id为1 和 2 具体返回的菜单可以在mock/sys/menu.ts内查看"
      show-icon
    />
  <PageWrapper
    title="后台权限示例"
    contentBackgrond
    contentClass="p-4"
    content="目前mock了两组数据, id为1 和 2 具体返回的菜单可以在mock/sys/menu.ts内查看"
  >
    <CurrentPermissionMode />
    <Alert class="mt-4" type="info" message="点击后请查看左侧菜单变化" show-icon />
@@ -15,17 +16,17 @@
        <a-button @click="changeMenu('2')"> 获取用户id为2的菜单 </a-button>
      </a-button-group>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { Alert } from 'ant-design-vue';
  import CurrentPermissionMode from '../CurrentPermissionMode.vue';
  import { RoleEnum } from '/@/enums/roleEnum';
  import { usePermission } from '/@/hooks/web/usePermission';
  import { PageWrapper } from '/@/components/Page';
  import { Alert } from 'ant-design-vue';
  export default defineComponent({
    components: { Alert, CurrentPermissionMode },
    components: { Alert, CurrentPermissionMode, PageWrapper },
    setup() {
      const { changeMenu } = usePermission();
      return {
src/views/demo/permission/front/Btn.vue
@@ -1,9 +1,10 @@
<template>
  <div class="demo p-4 m-4">
    <Alert
      message="由于刷新的时候会请求用户信息接口,会根据接口重置角色信息,所以刷新后界面会恢复原样,如果不需要,可以注释 src/layout/default/index内的获取用户信息接口"
      show-icon
    />
  <PageWrapper
    title="前端权限按钮示例"
    contentBackgrond
    contentClass="p-4"
    content="由于刷新的时候会请求用户信息接口,会根据接口重置角色信息,所以刷新后界面会恢复原样,如果不需要,可以注释 src/layout/default/index内的获取用户信息接口"
  >
    <CurrentPermissionMode />
    <p>
@@ -56,7 +57,7 @@
    <a-button v-auth="[RoleEnum.TEST, RoleEnum.SUPER]" color="error" class="mx-4">
      拥有[test,super]角色权限可见
    </a-button>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { computed, defineComponent } from 'vue';
@@ -66,9 +67,10 @@
  import { RoleEnum } from '/@/enums/roleEnum';
  import { usePermission } from '/@/hooks/web/usePermission';
  import { Authority } from '/@/components/Authority';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert, CurrentPermissionMode, Divider, Authority },
    components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority },
    setup() {
      const { changeRole, hasPermission } = usePermission();
      return {
src/views/demo/permission/front/index.vue
@@ -1,9 +1,10 @@
<template>
  <div class="p-4 m-4 demo">
    <Alert
      message="由于刷新的时候会请求用户信息接口,会根据接口重置角色信息,所以刷新后界面会恢复原样,如果不需要,可以注释 src/layout/default/index内的获取用户信息接口"
      show-icon
    />
  <PageWrapper
    title="前端权限示例"
    contentBackgrond
    contentClass="p-4"
    content="由于刷新的时候会请求用户信息接口,会根据接口重置角色信息,所以刷新后界面会恢复原样,如果不需要,可以注释 src/layout/default/index内的获取用户信息接口"
  >
    <CurrentPermissionMode />
    <p>
@@ -22,7 +23,7 @@
        </a-button>
      </a-button-group>
    </div>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { computed, defineComponent } from 'vue';
@@ -31,9 +32,10 @@
  import { userStore } from '/@/store/modules/user';
  import { RoleEnum } from '/@/enums/roleEnum';
  import { usePermission } from '/@/hooks/web/usePermission';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { Alert, CurrentPermissionMode },
    components: { Alert, CurrentPermissionMode, PageWrapper },
    setup() {
      const { changeRole } = usePermission();
      return {
src/views/demo/table/Basic.vue
@@ -31,9 +31,10 @@
  import { defineComponent, ref } from 'vue';
  import { BasicTable } from '/@/components/Table';
  import { getBasicColumns, getBasicData } from './tableData';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTable },
    components: { BasicTable, PageWrapper },
    setup() {
      const canResize = ref(false);
      const loading = ref(false);
src/views/demo/tree/ActionTree.vue
@@ -1,5 +1,5 @@
<template>
  <div class="p-4">
  <PageWrapper title="Tree函数操作示例" contentBackgrond contentClass="p-4">
    <div class="mb-4">
      <a-button @click="handleLevel(2)" class="mr-2">显示到第2级</a-button>
      <a-button @click="handleLevel(1)" class="mr-2">显示到第1级</a-button>
@@ -20,7 +20,7 @@
    <CollapseContainer title="函数操作" class="mr-4" :canExpan="false" :style="{ width: '33%' }">
      <BasicTree :treeData="treeData" ref="treeRef" :checkable="true" />
    </CollapseContainer>
  </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, ref, unref } from 'vue';
@@ -28,9 +28,10 @@
  import { treeData } from './data';
  import { CollapseContainer } from '/@/components/Container/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTree, CollapseContainer },
    components: { BasicTree, CollapseContainer, PageWrapper },
    setup() {
      const treeRef = ref<Nullable<TreeActionType>>(null);
      const { createMessage } = useMessage();
src/views/demo/tree/EditTree.vue
@@ -1,13 +1,15 @@
<template>
  <div class="flex p-4">
    <CollapseContainer title="右侧操作按钮" class="mr-4" :style="{ width: '33%' }">
      <BasicTree :treeData="treeData" :actionList="actionList" />
    </CollapseContainer>
  <PageWrapper title="Tree函数操作示例">
    <div class="flex">
      <CollapseContainer title="右侧操作按钮" class="mr-4" :style="{ width: '33%' }">
        <BasicTree :treeData="treeData" :actionList="actionList" />
      </CollapseContainer>
    <CollapseContainer title="右键菜单" class="mr-4" :style="{ width: '33%' }">
      <BasicTree :treeData="treeData" :beforeRightClick="getRightMenuList" />
    </CollapseContainer>
  </div>
      <CollapseContainer title="右键菜单" class="mr-4" :style="{ width: '33%' }">
        <BasicTree :treeData="treeData" :beforeRightClick="getRightMenuList" />
      </CollapseContainer>
    </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent, h } from 'vue';
@@ -15,8 +17,10 @@
  import { treeData } from './data';
  import { CollapseContainer } from '/@/components/Container/index';
  import { PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTree, CollapseContainer },
    components: { BasicTree, CollapseContainer, PageWrapper },
    setup() {
      function handlePlus(node: any) {
        console.log(node);
src/views/demo/tree/index.vue
@@ -1,31 +1,34 @@
<template>
  <div class="flex p-4">
    <CollapseContainer title="基础示例" :style="{ width: '33%' }" class="mr-4">
      <BasicTree :treeData="treeData" />
    </CollapseContainer>
  <PageWrapper title="Tree基础示例">
    <div class="flex">
      <CollapseContainer title="基础示例" :style="{ width: '33%' }" class="mr-4">
        <BasicTree :treeData="treeData" />
      </CollapseContainer>
    <CollapseContainer title="可勾选" class="mr-4" :style="{ width: '33%' }">
      <BasicTree :treeData="treeData" :checkable="true" />
    </CollapseContainer>
      <CollapseContainer title="可勾选" class="mr-4" :style="{ width: '33%' }">
        <BasicTree :treeData="treeData" :checkable="true" />
      </CollapseContainer>
    <CollapseContainer title="默认展开/勾选示例" :style="{ width: '33%' }">
      <BasicTree
        :treeData="treeData"
        :checkable="true"
        :expandedKeys="['0-0']"
        :checkedKeys="['0-0']"
      />
    </CollapseContainer>
  </div>
      <CollapseContainer title="默认展开/勾选示例" :style="{ width: '33%' }">
        <BasicTree
          :treeData="treeData"
          :checkable="true"
          :expandedKeys="['0-0']"
          :checkedKeys="['0-0']"
        />
      </CollapseContainer>
    </div>
  </PageWrapper>
</template>
<script lang="ts">
  import { defineComponent } from 'vue';
  import { BasicTree } from '/@/components/Tree/index';
  import { treeData } from './data';
  import { CollapseContainer } from '/@/components/Container/index';
  import { PageWrapper } from '/@/components/Page';
  export default defineComponent({
    components: { BasicTree, CollapseContainer },
    components: { BasicTree, CollapseContainer, PageWrapper },
    setup() {
      return { treeData };
    },