mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee
This commit is contained in:
		
						commit
						b9c1d8e351
					
				@ -1,3 +1,23 @@
 | 
				
			|||||||
 | 
					# 4.1.0 (2023-05-12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🎫 Feat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Add a `demo` example combined with `Form` for the functional pop-up box component
 | 
				
			||||||
 | 
					- wrapper `el-col` component of `element-plus`
 | 
				
			||||||
 | 
					- Add `beforeCancel` and `beforeSure` callbacks to the functional popup component, which can suspend the closing of the popup
 | 
				
			||||||
 | 
					- Improve `System Management-Department Management` page
 | 
				
			||||||
 | 
					- Optimize `PureTableBar` component, add drag and drop function for column display
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🐞 Bug fixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix the problem that the page cache still exists when you click the tab to reload after turning on `keepAlive`
 | 
				
			||||||
 | 
					- Fix the problem that the left menu will flicker after refreshing the tab in the mixed mode menu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🍏 Perf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Optimize home page layout
 | 
				
			||||||
 | 
					- Dependency update to `vue3.3+` and remove `unplugin-vue-define-options` plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 4.0.0 (2023-05-09)
 | 
					# 4.0.0 (2023-05-09)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[View 4.0.0 version optimization details](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
 | 
					[View 4.0.0 version optimization details](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@ -1,3 +1,23 @@
 | 
				
			|||||||
 | 
					# 4.1.0 (2023-05-12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🎫 Feat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Add a `demo` example combined with `Form` for the functional pop-up box component
 | 
				
			||||||
 | 
					- wrapper `el-col` component of `element-plus`
 | 
				
			||||||
 | 
					- Add `beforeCancel` and `beforeSure` callbacks to the functional popup component, which can suspend the closing of the popup
 | 
				
			||||||
 | 
					- Improve `System Management-Department Management` page
 | 
				
			||||||
 | 
					- Optimize `PureTableBar` component, add drag and drop function for column display
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🐞 Bug fixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix the problem that the page cache still exists when you click the tab to reload after turning on `keepAlive`
 | 
				
			||||||
 | 
					- Fix the problem that the left menu will flicker after refreshing the tab in the mixed mode menu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🍏 Perf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Optimize home page layout
 | 
				
			||||||
 | 
					- Dependency update to `vue3.3+` and remove `unplugin-vue-define-options` plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 4.0.0 (2023-05-09)
 | 
					# 4.0.0 (2023-05-09)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[View 4.0.0 version optimization details](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
 | 
					[View 4.0.0 version optimization details](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,23 @@
 | 
				
			|||||||
 | 
					# 4.1.0 (2023-05-12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🎫 Feat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 函数式弹框组件添加结合 `Form` 的 `demo` 示例
 | 
				
			||||||
 | 
					- 封装 `element-plus` 的 `el-col` 组件
 | 
				
			||||||
 | 
					- 函数式弹框组件添加 `beforeCancel` 和 `beforeSure` 回调,可暂停弹框的关闭
 | 
				
			||||||
 | 
					- 完善 `系统管理-部门管理` 页面
 | 
				
			||||||
 | 
					- 优化 `PureTableBar` 组件,列展示添加拖拽功能
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🐞 Bug fixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 修复开启 `keepAlive` 后点击标签页的重新加载,页面缓存还存在的问题
 | 
				
			||||||
 | 
					- 修复混合模式菜单下刷新页签后左侧菜单会闪烁一下的问题
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🍏 Perf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 优化首页布局
 | 
				
			||||||
 | 
					- 依赖更新到 `vue3.3+` 以及删除 `unplugin-vue-define-options` 插件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 4.0.0 (2023-05-09)
 | 
					# 4.0.0 (2023-05-09)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[查看 4.0.0 版本优化细节](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
 | 
					[查看 4.0.0 版本优化细节](https://github.com/pure-admin/vue-pure-admin/issues/428#issuecomment-1422191158)
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,7 @@ const include = [
 | 
				
			|||||||
  "element-resize-detector",
 | 
					  "element-resize-detector",
 | 
				
			||||||
  "@amap/amap-jsapi-loader",
 | 
					  "@amap/amap-jsapi-loader",
 | 
				
			||||||
  "el-table-infinite-scroll",
 | 
					  "el-table-infinite-scroll",
 | 
				
			||||||
 | 
					  "vue-waterfall-plugin-next",
 | 
				
			||||||
  "@wangeditor/editor-for-vue",
 | 
					  "@wangeditor/editor-for-vue",
 | 
				
			||||||
  "vuedraggable/src/vuedraggable"
 | 
					  "vuedraggable/src/vuedraggable"
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ menus:
 | 
				
			|||||||
  hsdialog: Dialog Components
 | 
					  hsdialog: Dialog Components
 | 
				
			||||||
  hsmessage: Message Tips Components
 | 
					  hsmessage: Message Tips Components
 | 
				
			||||||
  hsvideo: Video Components
 | 
					  hsvideo: Video Components
 | 
				
			||||||
 | 
					  hswaterfall: Waterfall Components
 | 
				
			||||||
  hsmap: Map Components
 | 
					  hsmap: Map Components
 | 
				
			||||||
  hsdraggable: Draggable Components
 | 
					  hsdraggable: Draggable Components
 | 
				
			||||||
  hssplitPane: Split Pane
 | 
					  hssplitPane: Split Pane
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,7 @@ menus:
 | 
				
			|||||||
  hsdialog: 函数式弹框组件
 | 
					  hsdialog: 函数式弹框组件
 | 
				
			||||||
  hsmessage: 消息提示组件
 | 
					  hsmessage: 消息提示组件
 | 
				
			||||||
  hsvideo: 视频组件
 | 
					  hsvideo: 视频组件
 | 
				
			||||||
 | 
					  hswaterfall: 瀑布流组件
 | 
				
			||||||
  hsmap: 地图组件
 | 
					  hsmap: 地图组件
 | 
				
			||||||
  hsdraggable: 拖拽组件
 | 
					  hsdraggable: 拖拽组件
 | 
				
			||||||
  hssplitPane: 切割面板
 | 
					  hssplitPane: 切割面板
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								package.json
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "vue-pure-admin",
 | 
					  "name": "vue-pure-admin",
 | 
				
			||||||
  "version": "4.0.0",
 | 
					  "version": "4.1.0",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
 | 
					    "dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
 | 
				
			||||||
@ -30,14 +30,14 @@
 | 
				
			|||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@amap/amap-jsapi-loader": "^1.0.1",
 | 
					    "@amap/amap-jsapi-loader": "^1.0.1",
 | 
				
			||||||
    "@howdyjs/mouse-menu": "^2.0.7",
 | 
					    "@howdyjs/mouse-menu": "^2.0.7",
 | 
				
			||||||
    "@logicflow/core": "^1.2.5",
 | 
					    "@logicflow/core": "^1.2.6",
 | 
				
			||||||
    "@logicflow/extension": "^1.2.5",
 | 
					    "@logicflow/extension": "^1.2.6",
 | 
				
			||||||
    "@pureadmin/descriptions": "^1.1.1",
 | 
					    "@pureadmin/descriptions": "^1.1.1",
 | 
				
			||||||
    "@pureadmin/table": "^2.1.0",
 | 
					    "@pureadmin/table": "^2.1.0",
 | 
				
			||||||
    "@pureadmin/utils": "^1.8.9",
 | 
					    "@pureadmin/utils": "^1.8.9",
 | 
				
			||||||
    "@vueuse/core": "^10.1.2",
 | 
					    "@vueuse/core": "^10.1.2",
 | 
				
			||||||
    "@vueuse/motion": "2.0.0-beta.12",
 | 
					    "@vueuse/motion": "2.0.0-beta.12",
 | 
				
			||||||
    "@wangeditor/editor": "^5.1.21",
 | 
					    "@wangeditor/editor": "^5.1.23",
 | 
				
			||||||
    "@wangeditor/editor-for-vue": "^5.1.12",
 | 
					    "@wangeditor/editor-for-vue": "^5.1.12",
 | 
				
			||||||
    "animate.css": "^4.1.1",
 | 
					    "animate.css": "^4.1.1",
 | 
				
			||||||
    "axios": "^1.4.0",
 | 
					    "axios": "^1.4.0",
 | 
				
			||||||
@ -61,16 +61,17 @@
 | 
				
			|||||||
    "qs": "^6.11.1",
 | 
					    "qs": "^6.11.1",
 | 
				
			||||||
    "responsive-storage": "^2.2.0",
 | 
					    "responsive-storage": "^2.2.0",
 | 
				
			||||||
    "sortablejs": "^1.15.0",
 | 
					    "sortablejs": "^1.15.0",
 | 
				
			||||||
    "swiper": "^9.3.0",
 | 
					    "swiper": "^9.3.1",
 | 
				
			||||||
    "typeit": "^8.7.1",
 | 
					    "typeit": "^8.7.1",
 | 
				
			||||||
    "v-contextmenu": "3.0.0",
 | 
					    "v-contextmenu": "3.0.0",
 | 
				
			||||||
    "vue": "^3.3.1",
 | 
					    "vue": "^3.3.2",
 | 
				
			||||||
    "vue-i18n": "^9.2.2",
 | 
					    "vue-i18n": "^9.2.2",
 | 
				
			||||||
    "vue-json-pretty": "^2.2.4",
 | 
					    "vue-json-pretty": "^2.2.4",
 | 
				
			||||||
    "vue-pdf-embed": "^1.1.6",
 | 
					    "vue-pdf-embed": "^1.1.6",
 | 
				
			||||||
    "vue-router": "^4.1.6",
 | 
					    "vue-router": "^4.2.0",
 | 
				
			||||||
    "vue-types": "^5.0.2",
 | 
					    "vue-types": "^5.0.2",
 | 
				
			||||||
    "vue-virtual-scroller": "2.0.0-beta.7",
 | 
					    "vue-virtual-scroller": "2.0.0-beta.7",
 | 
				
			||||||
 | 
					    "vue-waterfall-plugin-next": "^2.2.1",
 | 
				
			||||||
    "vue3-danmaku": "1.4.0-beta.1",
 | 
					    "vue3-danmaku": "1.4.0-beta.1",
 | 
				
			||||||
    "vuedraggable": "^4.1.0",
 | 
					    "vuedraggable": "^4.1.0",
 | 
				
			||||||
    "xgplayer": "^3.0.2",
 | 
					    "xgplayer": "^3.0.2",
 | 
				
			||||||
@ -95,7 +96,7 @@
 | 
				
			|||||||
    "@types/sortablejs": "^1.15.1",
 | 
					    "@types/sortablejs": "^1.15.1",
 | 
				
			||||||
    "@typescript-eslint/eslint-plugin": "^5.59.5",
 | 
					    "@typescript-eslint/eslint-plugin": "^5.59.5",
 | 
				
			||||||
    "@typescript-eslint/parser": "^5.59.5",
 | 
					    "@typescript-eslint/parser": "^5.59.5",
 | 
				
			||||||
    "@vitejs/plugin-vue": "^4.2.2",
 | 
					    "@vitejs/plugin-vue": "^4.2.3",
 | 
				
			||||||
    "@vitejs/plugin-vue-jsx": "^3.0.1",
 | 
					    "@vitejs/plugin-vue-jsx": "^3.0.1",
 | 
				
			||||||
    "@vue/eslint-config-prettier": "^7.1.0",
 | 
					    "@vue/eslint-config-prettier": "^7.1.0",
 | 
				
			||||||
    "@vue/eslint-config-typescript": "^11.0.3",
 | 
					    "@vue/eslint-config-typescript": "^11.0.3",
 | 
				
			||||||
@ -131,7 +132,7 @@
 | 
				
			|||||||
    "stylelint-scss": "^5.0.0",
 | 
					    "stylelint-scss": "^5.0.0",
 | 
				
			||||||
    "svgo": "^3.0.2",
 | 
					    "svgo": "^3.0.2",
 | 
				
			||||||
    "tailwindcss": "^3.3.2",
 | 
					    "tailwindcss": "^3.3.2",
 | 
				
			||||||
    "terser": "^5.17.1",
 | 
					    "terser": "^5.17.3",
 | 
				
			||||||
    "typescript": "^5.0.4",
 | 
					    "typescript": "^5.0.4",
 | 
				
			||||||
    "vite": "^4.3.5",
 | 
					    "vite": "^4.3.5",
 | 
				
			||||||
    "vite-plugin-cdn-import": "^0.3.5",
 | 
					    "vite-plugin-cdn-import": "^0.3.5",
 | 
				
			||||||
@ -139,8 +140,8 @@
 | 
				
			|||||||
    "vite-plugin-mock": "^2.9.6",
 | 
					    "vite-plugin-mock": "^2.9.6",
 | 
				
			||||||
    "vite-plugin-remove-console": "^2.1.1",
 | 
					    "vite-plugin-remove-console": "^2.1.1",
 | 
				
			||||||
    "vite-svg-loader": "^4.0.0",
 | 
					    "vite-svg-loader": "^4.0.0",
 | 
				
			||||||
    "vue-eslint-parser": "^9.2.1",
 | 
					    "vue-eslint-parser": "^9.3.0",
 | 
				
			||||||
    "vue-tsc": "^1.6.4"
 | 
					    "vue-tsc": "^1.6.5"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "pnpm": {
 | 
					  "pnpm": {
 | 
				
			||||||
    "peerDependencyRules": {
 | 
					    "peerDependencyRules": {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1121
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1121
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,5 +1,5 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "Version": "4.0.0",
 | 
					  "Version": "4.1.0",
 | 
				
			||||||
  "Title": "PureAdmin",
 | 
					  "Title": "PureAdmin",
 | 
				
			||||||
  "FixedHeader": true,
 | 
					  "FixedHeader": true,
 | 
				
			||||||
  "HiddenSideBar": false,
 | 
					  "HiddenSideBar": false,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,17 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { computed } from "vue";
 | 
					 | 
				
			||||||
import { isFunction } from "@pureadmin/utils";
 | 
					 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  type DialogOptions,
 | 
					  closeDialog,
 | 
				
			||||||
  type ButtonProps,
 | 
					 | 
				
			||||||
  type EventType,
 | 
					 | 
				
			||||||
  dialogStore,
 | 
					  dialogStore,
 | 
				
			||||||
  closeDialog
 | 
					  type EventType,
 | 
				
			||||||
 | 
					  type ButtonProps,
 | 
				
			||||||
 | 
					  type DialogOptions
 | 
				
			||||||
} from "./index";
 | 
					} from "./index";
 | 
				
			||||||
 | 
					import { ref, computed } from "vue";
 | 
				
			||||||
 | 
					import { isFunction } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
 | 
				
			||||||
 | 
					import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fullscreen = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const footerButtons = computed(() => {
 | 
					const footerButtons = computed(() => {
 | 
				
			||||||
  return (options: DialogOptions) => {
 | 
					  return (options: DialogOptions) => {
 | 
				
			||||||
@ -47,11 +51,22 @@ const footerButtons = computed(() => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fullscreenClass = computed(() => {
 | 
				
			||||||
 | 
					  return [
 | 
				
			||||||
 | 
					    "el-icon",
 | 
				
			||||||
 | 
					    "el-dialog__close",
 | 
				
			||||||
 | 
					    "-translate-x-2",
 | 
				
			||||||
 | 
					    "cursor-pointer",
 | 
				
			||||||
 | 
					    "hover:!text-[red]"
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function eventsCallBack(
 | 
					function eventsCallBack(
 | 
				
			||||||
  event: EventType,
 | 
					  event: EventType,
 | 
				
			||||||
  options: DialogOptions,
 | 
					  options: DialogOptions,
 | 
				
			||||||
  index: number
 | 
					  index: number
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
 | 
					  fullscreen.value = options?.fullscreen ?? false;
 | 
				
			||||||
  if (options?.[event] && isFunction(options?.[event])) {
 | 
					  if (options?.[event] && isFunction(options?.[event])) {
 | 
				
			||||||
    return options?.[event]({ options, index });
 | 
					    return options?.[event]({ options, index });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -69,25 +84,49 @@ function handleClose(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <el-dialog
 | 
					  <el-dialog
 | 
				
			||||||
 | 
					    class="pure-dialog"
 | 
				
			||||||
    v-for="(options, index) in dialogStore"
 | 
					    v-for="(options, index) in dialogStore"
 | 
				
			||||||
    :key="index"
 | 
					    :key="index"
 | 
				
			||||||
    v-bind="options"
 | 
					    v-bind="options"
 | 
				
			||||||
    v-model="options.visible"
 | 
					    v-model="options.visible"
 | 
				
			||||||
    @opened="eventsCallBack('open', options, index)"
 | 
					    :fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
 | 
				
			||||||
    @close="handleClose(options, index)"
 | 
					    @close="handleClose(options, index)"
 | 
				
			||||||
 | 
					    @opened="eventsCallBack('open', options, index)"
 | 
				
			||||||
    @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
 | 
					    @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
 | 
				
			||||||
    @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)"
 | 
					    @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <!-- header -->
 | 
					    <!-- header -->
 | 
				
			||||||
    <template
 | 
					    <template
 | 
				
			||||||
      v-if="options?.headerRenderer"
 | 
					      v-if="options?.fullscreenIcon || options?.headerRenderer"
 | 
				
			||||||
      #header="{ close, titleId, titleClass }"
 | 
					      #header="{ close, titleId, titleClass }"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        v-if="options?.fullscreenIcon"
 | 
				
			||||||
 | 
					        class="flex items-center justify-between"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <span :id="titleId" :class="titleClass">{{ options?.title }}</span>
 | 
				
			||||||
 | 
					        <i
 | 
				
			||||||
 | 
					          v-if="!options?.fullscreen"
 | 
				
			||||||
 | 
					          :class="fullscreenClass"
 | 
				
			||||||
 | 
					          @click="fullscreen = !fullscreen"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <IconifyIconOffline
 | 
				
			||||||
 | 
					            class="pure-dialog-svg"
 | 
				
			||||||
 | 
					            :icon="
 | 
				
			||||||
 | 
					              options?.fullscreen
 | 
				
			||||||
 | 
					                ? ExitFullscreen
 | 
				
			||||||
 | 
					                : fullscreen
 | 
				
			||||||
 | 
					                ? ExitFullscreen
 | 
				
			||||||
 | 
					                : Fullscreen
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </i>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <component
 | 
					      <component
 | 
				
			||||||
 | 
					        v-else
 | 
				
			||||||
        :is="options?.headerRenderer({ close, titleId, titleClass })"
 | 
					        :is="options?.headerRenderer({ close, titleId, titleClass })"
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </template>
 | 
					    </template>
 | 
				
			||||||
    <!-- default -->
 | 
					 | 
				
			||||||
    <component
 | 
					    <component
 | 
				
			||||||
      v-bind="options?.props"
 | 
					      v-bind="options?.props"
 | 
				
			||||||
      :is="options.contentRenderer({ options, index })"
 | 
					      :is="options.contentRenderer({ options, index })"
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,10 @@ type DialogProps = {
 | 
				
			|||||||
  title?: string;
 | 
					  title?: string;
 | 
				
			||||||
  /** `Dialog` 的宽度,默认 `50%` */
 | 
					  /** `Dialog` 的宽度,默认 `50%` */
 | 
				
			||||||
  width?: string | number;
 | 
					  width?: string | number;
 | 
				
			||||||
  /** 是否为全屏 `Dialog`,默认 `false` */
 | 
					  /** 是否为全屏 `Dialog`(会一直处于全屏状态,除非弹框关闭),默认 `false`,`fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
 | 
				
			||||||
  fullscreen?: boolean;
 | 
					  fullscreen?: boolean;
 | 
				
			||||||
 | 
					  /** 是否显示全屏操作图标,默认 `false`,`fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
 | 
				
			||||||
 | 
					  fullscreenIcon?: boolean;
 | 
				
			||||||
  /** `Dialog CSS` 中的 `margin-top` 值,默认 `15vh` */
 | 
					  /** `Dialog CSS` 中的 `margin-top` 值,默认 `15vh` */
 | 
				
			||||||
  top?: string;
 | 
					  top?: string;
 | 
				
			||||||
  /** 是否需要遮罩层,默认 `true` */
 | 
					  /** 是否需要遮罩层,默认 `true` */
 | 
				
			||||||
 | 
				
			|||||||
@ -525,7 +525,7 @@ onMounted(() => {
 | 
				
			|||||||
          :class="[
 | 
					          :class="[
 | 
				
			||||||
            'scroll-item is-closable',
 | 
					            'scroll-item is-closable',
 | 
				
			||||||
            linkIsActive(item),
 | 
					            linkIsActive(item),
 | 
				
			||||||
            $route.path === item.path && showModel === 'card'
 | 
					            route.path === item.path && showModel === 'card'
 | 
				
			||||||
              ? 'card-active'
 | 
					              ? 'card-active'
 | 
				
			||||||
              : ''
 | 
					              : ''
 | 
				
			||||||
          ]"
 | 
					          ]"
 | 
				
			||||||
 | 
				
			|||||||
@ -47,13 +47,13 @@ Object.keys(modules).forEach(key => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/** 导出处理后的静态路由(三级及以上的路由全部拍成二级) */
 | 
					/** 导出处理后的静态路由(三级及以上的路由全部拍成二级) */
 | 
				
			||||||
export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
 | 
					export const constantRoutes: Array<RouteRecordRaw> = formatTwoStageRoutes(
 | 
				
			||||||
  formatFlatteningRoutes(buildHierarchyTree(ascending(routes)))
 | 
					  formatFlatteningRoutes(buildHierarchyTree(ascending(routes.flat(Infinity))))
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 用于渲染菜单,保持原始层级 */
 | 
					/** 用于渲染菜单,保持原始层级 */
 | 
				
			||||||
export const constantMenus: Array<RouteComponent> = ascending(routes).concat(
 | 
					export const constantMenus: Array<RouteComponent> = ascending(
 | 
				
			||||||
  ...remainingRouter
 | 
					  routes.flat(Infinity)
 | 
				
			||||||
);
 | 
					).concat(...remainingRouter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 不参与菜单的路由 */
 | 
					/** 不参与菜单的路由 */
 | 
				
			||||||
export const remainingPaths = Object.keys(remainingRouter).map(v => {
 | 
					export const remainingPaths = Object.keys(remainingRouter).map(v => {
 | 
				
			||||||
@ -87,7 +87,9 @@ export function resetRouter() {
 | 
				
			|||||||
    if (name && router.hasRoute(name) && meta?.backstage) {
 | 
					    if (name && router.hasRoute(name) && meta?.backstage) {
 | 
				
			||||||
      router.removeRoute(name);
 | 
					      router.removeRoute(name);
 | 
				
			||||||
      router.options.routes = formatTwoStageRoutes(
 | 
					      router.options.routes = formatTwoStageRoutes(
 | 
				
			||||||
        formatFlatteningRoutes(buildHierarchyTree(ascending(routes)))
 | 
					        formatFlatteningRoutes(
 | 
				
			||||||
 | 
					          buildHierarchyTree(ascending(routes.flat(Infinity)))
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
				
			|||||||
@ -31,6 +31,15 @@ export default {
 | 
				
			|||||||
        title: $t("menus.hsmessage")
 | 
					        title: $t("menus.hsmessage")
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/components/waterfall",
 | 
				
			||||||
 | 
					      name: "Waterfall",
 | 
				
			||||||
 | 
					      component: () => import("@/views/components/waterfall/index.vue"),
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: $t("menus.hswaterfall"),
 | 
				
			||||||
 | 
					        extraIcon: "IF-pure-iconfont-new svg"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/components/video",
 | 
					      path: "/components/video",
 | 
				
			||||||
      name: "Video",
 | 
					      name: "Video",
 | 
				
			||||||
 | 
				
			|||||||
@ -110,6 +110,10 @@ html.dark {
 | 
				
			|||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        color: rgb(255 255 255 / 85%) !important;
 | 
					        color: rgb(255 255 255 / 85%) !important;
 | 
				
			||||||
        background-color: rgb(255 255 255 / 12%);
 | 
					        background-color: rgb(255 255 255 / 12%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .pure-dialog-svg {
 | 
				
			||||||
 | 
					          color: rgb(255 255 255 / 85%) !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -69,6 +69,19 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pure-dialog {
 | 
				
			||||||
 | 
					  .pure-dialog-svg {
 | 
				
			||||||
 | 
					    color: var(--el-color-info);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .el-dialog__headerbtn {
 | 
				
			||||||
 | 
					    top: 20px;
 | 
				
			||||||
 | 
					    right: 14px;
 | 
				
			||||||
 | 
					    width: 24px;
 | 
				
			||||||
 | 
					    height: 24px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 全局覆盖element-plus的el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标的样式,表现更鲜明 */
 | 
					/* 全局覆盖element-plus的el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标的样式,表现更鲜明 */
 | 
				
			||||||
.el-dialog__headerbtn,
 | 
					.el-dialog__headerbtn,
 | 
				
			||||||
.el-message-box__headerbtn {
 | 
					.el-message-box__headerbtn {
 | 
				
			||||||
@ -94,6 +107,10 @@
 | 
				
			|||||||
      color: rgb(0 0 0 / 88%) !important;
 | 
					      color: rgb(0 0 0 / 88%) !important;
 | 
				
			||||||
      text-decoration: none;
 | 
					      text-decoration: none;
 | 
				
			||||||
      background-color: rgb(0 0 0 / 6%);
 | 
					      background-color: rgb(0 0 0 / 6%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      .pure-dialog-svg {
 | 
				
			||||||
 | 
					        color: rgb(0 0 0 / 88%) !important;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -70,7 +70,7 @@ const activities = [
 | 
				
			|||||||
          placement="bottom"
 | 
					          placement="bottom"
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <div class="message">
 | 
					          <div class="message">
 | 
				
			||||||
            vue-pure-admin是基于Vue3.0+TypeScript+Vite2.0+Element-Plus编写的一套后台管理系统
 | 
					            vue-pure-admin是基于Vue3.0+TypeScript+Vite+Element-Plus编写的一套后台管理系统
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </el-timeline-item>
 | 
					        </el-timeline-item>
 | 
				
			||||||
      </el-timeline>
 | 
					      </el-timeline>
 | 
				
			||||||
 | 
				
			|||||||
@ -28,19 +28,19 @@ Object.keys(devDependencies).forEach(key => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div>
 | 
					  <div>
 | 
				
			||||||
    <el-card class="box-card mb-4" shadow="never">
 | 
					    <el-card class="mb-4 box-card" shadow="never">
 | 
				
			||||||
      <template #header>
 | 
					      <template #header>
 | 
				
			||||||
        <div class="card-header">
 | 
					        <div class="card-header">
 | 
				
			||||||
          <span class="font-medium">关于</span>
 | 
					          <span class="font-medium">关于</span>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
      <span style="font-size: 15px">
 | 
					      <span style="font-size: 15px">
 | 
				
			||||||
        Pure-Admin 是一个基于Vue3、Vite2、TypeScript、Element-Plus
 | 
					        Pure-Admin 是一个基于Vue3、Vite、TypeScript、Element-Plus
 | 
				
			||||||
        的中后台解决方案,它可以帮助您快速搭建企业级中后台,提供现成的开箱解决方案及丰富的示例。原则上不收取任何费用及版权,可以放心使用,不过如需二次开源(比如用此平台二次开发并开源)请联系作者获取许可!
 | 
					        的中后台解决方案,它可以帮助您快速搭建企业级中后台,提供现成的开箱解决方案及丰富的示例。原则上不收取任何费用及版权,可以放心使用,不过如需二次开源(比如用此平台二次开发并开源)请联系作者获取许可!
 | 
				
			||||||
      </span>
 | 
					      </span>
 | 
				
			||||||
    </el-card>
 | 
					    </el-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-card class="box-card m-4" shadow="never">
 | 
					    <el-card class="m-4 box-card" shadow="never">
 | 
				
			||||||
      <template #header>
 | 
					      <template #header>
 | 
				
			||||||
        <div class="card-header">
 | 
					        <div class="card-header">
 | 
				
			||||||
          <span class="font-medium">项目信息</span>
 | 
					          <span class="font-medium">项目信息</span>
 | 
				
			||||||
@ -49,7 +49,7 @@ Object.keys(devDependencies).forEach(key => {
 | 
				
			|||||||
      <PureDescriptions :columns="columns" border :column="3" align="left" />
 | 
					      <PureDescriptions :columns="columns" border :column="3" align="left" />
 | 
				
			||||||
    </el-card>
 | 
					    </el-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-card class="box-card m-4" shadow="never">
 | 
					    <el-card class="m-4 box-card" shadow="never">
 | 
				
			||||||
      <template #header>
 | 
					      <template #header>
 | 
				
			||||||
        <div class="card-header">
 | 
					        <div class="card-header">
 | 
				
			||||||
          <span class="font-medium">生产环境依赖</span>
 | 
					          <span class="font-medium">生产环境依赖</span>
 | 
				
			||||||
@ -73,7 +73,7 @@ Object.keys(devDependencies).forEach(key => {
 | 
				
			|||||||
      </el-descriptions>
 | 
					      </el-descriptions>
 | 
				
			||||||
    </el-card>
 | 
					    </el-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-card class="box-card m-4" shadow="never">
 | 
					    <el-card class="m-4 box-card" shadow="never">
 | 
				
			||||||
      <template #header>
 | 
					      <template #header>
 | 
				
			||||||
        <div class="card-header">
 | 
					        <div class="card-header">
 | 
				
			||||||
          <span class="font-medium">开发环境依赖</span>
 | 
					          <span class="font-medium">开发环境依赖</span>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
<script setup lang="tsx">
 | 
					<script setup lang="tsx">
 | 
				
			||||||
 | 
					import { useRouter } from "vue-router";
 | 
				
			||||||
import { h, createVNode, ref } from "vue";
 | 
					import { h, createVNode, ref } from "vue";
 | 
				
			||||||
import { message } from "@/utils/message";
 | 
					import { message } from "@/utils/message";
 | 
				
			||||||
import { cloneDeep } from "@pureadmin/utils";
 | 
					import { cloneDeep } from "@pureadmin/utils";
 | 
				
			||||||
@ -9,6 +10,8 @@ defineOptions({
 | 
				
			|||||||
  name: "Dialog"
 | 
					  name: "Dialog"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onBaseClick() {
 | 
					function onBaseClick() {
 | 
				
			||||||
  addDialog({
 | 
					  addDialog({
 | 
				
			||||||
    title: "基本使用",
 | 
					    title: "基本使用",
 | 
				
			||||||
@ -32,6 +35,14 @@ function onFullscreenClick() {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onFullscreenIconClick() {
 | 
				
			||||||
 | 
					  addDialog({
 | 
				
			||||||
 | 
					    title: "全屏按钮",
 | 
				
			||||||
 | 
					    fullscreenIcon: true,
 | 
				
			||||||
 | 
					    contentRenderer: () => <p>弹框内容-全屏按钮</p>
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onModalClick() {
 | 
					function onModalClick() {
 | 
				
			||||||
  addDialog({
 | 
					  addDialog({
 | 
				
			||||||
    title: "无背景遮罩层",
 | 
					    title: "无背景遮罩层",
 | 
				
			||||||
@ -380,7 +391,7 @@ function onBeforeSureClick() {
 | 
				
			|||||||
          ,采用函数式调用弹框组件(更多操作实例请参考
 | 
					          ,采用函数式调用弹框组件(更多操作实例请参考
 | 
				
			||||||
          <span
 | 
					          <span
 | 
				
			||||||
            class="cursor-pointer text-primary"
 | 
					            class="cursor-pointer text-primary"
 | 
				
			||||||
            @click="$router.push({ name: 'Dept' })"
 | 
					            @click="router.push({ name: 'Dept' })"
 | 
				
			||||||
            >系统管理页面</span
 | 
					            >系统管理页面</span
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
@ -391,6 +402,7 @@ function onBeforeSureClick() {
 | 
				
			|||||||
      <el-button @click="onBaseClick"> 基本使用 </el-button>
 | 
					      <el-button @click="onBaseClick"> 基本使用 </el-button>
 | 
				
			||||||
      <el-button @click="onDraggableClick"> 可拖拽 </el-button>
 | 
					      <el-button @click="onDraggableClick"> 可拖拽 </el-button>
 | 
				
			||||||
      <el-button @click="onFullscreenClick"> 全屏 </el-button>
 | 
					      <el-button @click="onFullscreenClick"> 全屏 </el-button>
 | 
				
			||||||
 | 
					      <el-button @click="onFullscreenIconClick"> 全屏按钮 </el-button>
 | 
				
			||||||
      <el-button @click="onModalClick"> 无背景遮罩层 </el-button>
 | 
					      <el-button @click="onModalClick"> 无背景遮罩层 </el-button>
 | 
				
			||||||
      <el-button @click="onStyleClick"> 自定义弹出位置 </el-button>
 | 
					      <el-button @click="onStyleClick"> 自定义弹出位置 </el-button>
 | 
				
			||||||
      <el-button @click="onoOpenDelayClick"> 延时2秒打开弹框 </el-button>
 | 
					      <el-button @click="onoOpenDelayClick"> 延时2秒打开弹框 </el-button>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								src/views/components/waterfall/api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/views/components/waterfall/api.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					export function randomID(length = 6) {
 | 
				
			||||||
 | 
					  return Number(
 | 
				
			||||||
 | 
					    Math.random().toString().substr(3, length) + Date.now()
 | 
				
			||||||
 | 
					  ).toString(36);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const COLORS = ["#409EFF", "#67C23A", "#E6A23C", "#F56C6C", "#909399"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getRandomNum(min: number, max: number) {
 | 
				
			||||||
 | 
					  return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function randomColor() {
 | 
				
			||||||
 | 
					  return COLORS[getRandomNum(0, 4)];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const website = "https://www.getphotoblanket.com";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getList = ({ page = 1, pageSize = 20 }) => {
 | 
				
			||||||
 | 
					  const url = `${website}/products.json?page=${page}&limit=${pageSize}`;
 | 
				
			||||||
 | 
					  return fetch(url)
 | 
				
			||||||
 | 
					    .then(res => res.json())
 | 
				
			||||||
 | 
					    .then(res => res.products)
 | 
				
			||||||
 | 
					    .then(res => {
 | 
				
			||||||
 | 
					      return res.map((item: any) => {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          id: randomID(),
 | 
				
			||||||
 | 
					          star: false,
 | 
				
			||||||
 | 
					          price: item.variants[0].price,
 | 
				
			||||||
 | 
					          src: {
 | 
				
			||||||
 | 
					            original: item.images[0].src
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          backgroundColor: randomColor(),
 | 
				
			||||||
 | 
					          name: item.title
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								src/views/components/waterfall/error.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/views/components/waterfall/error.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.5 KiB  | 
							
								
								
									
										151
									
								
								src/views/components/waterfall/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/views/components/waterfall/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { getList } from "./api";
 | 
				
			||||||
 | 
					import error from "./error.png";
 | 
				
			||||||
 | 
					import loading from "./loading.png";
 | 
				
			||||||
 | 
					import { onMounted, reactive, ref } from "vue";
 | 
				
			||||||
 | 
					import "vue-waterfall-plugin-next/dist/style.css";
 | 
				
			||||||
 | 
					import backTop from "@/assets/svg/back_top.svg?component";
 | 
				
			||||||
 | 
					import { LazyImg, Waterfall } from "vue-waterfall-plugin-next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const options = reactive({
 | 
				
			||||||
 | 
					  // 唯一key值
 | 
				
			||||||
 | 
					  rowKey: "id",
 | 
				
			||||||
 | 
					  // 卡片之间的间隙
 | 
				
			||||||
 | 
					  gutter: 10,
 | 
				
			||||||
 | 
					  // 是否有周围的gutter
 | 
				
			||||||
 | 
					  hasAroundGutter: true,
 | 
				
			||||||
 | 
					  // 卡片在PC上的宽度
 | 
				
			||||||
 | 
					  width: 320,
 | 
				
			||||||
 | 
					  // 自定义行显示个数,主要用于对移动端的适配
 | 
				
			||||||
 | 
					  breakpoints: {
 | 
				
			||||||
 | 
					    1200: {
 | 
				
			||||||
 | 
					      // 当屏幕宽度小于等于1200
 | 
				
			||||||
 | 
					      rowPerView: 4
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    800: {
 | 
				
			||||||
 | 
					      // 当屏幕宽度小于等于800
 | 
				
			||||||
 | 
					      rowPerView: 3
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    500: {
 | 
				
			||||||
 | 
					      // 当屏幕宽度小于等于500
 | 
				
			||||||
 | 
					      rowPerView: 2
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 动画效果
 | 
				
			||||||
 | 
					  animationEffect: "animate__fadeInUp",
 | 
				
			||||||
 | 
					  // 动画时间
 | 
				
			||||||
 | 
					  animationDuration: 1000,
 | 
				
			||||||
 | 
					  // 动画延迟
 | 
				
			||||||
 | 
					  animationDelay: 300,
 | 
				
			||||||
 | 
					  // 背景色
 | 
				
			||||||
 | 
					  // backgroundColor: "#2C2E3A",
 | 
				
			||||||
 | 
					  // 图片字段选择器,如果层级较深,使用 xxx.xxx.xxx 方式
 | 
				
			||||||
 | 
					  imgSelector: "src.original",
 | 
				
			||||||
 | 
					  // 加载配置
 | 
				
			||||||
 | 
					  loadProps: {
 | 
				
			||||||
 | 
					    loading,
 | 
				
			||||||
 | 
					    error
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 是否懒加载
 | 
				
			||||||
 | 
					  lazyload: true
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const page = ref(1);
 | 
				
			||||||
 | 
					const list = ref([]);
 | 
				
			||||||
 | 
					const pageSize = ref();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 加载更多 */
 | 
				
			||||||
 | 
					function handleLoadMore() {
 | 
				
			||||||
 | 
					  getList({
 | 
				
			||||||
 | 
					    page: page.value,
 | 
				
			||||||
 | 
					    pageSize: pageSize.value
 | 
				
			||||||
 | 
					  }).then(res => {
 | 
				
			||||||
 | 
					    list.value.push(...res);
 | 
				
			||||||
 | 
					    page.value += 1;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function handleDelete(item, index) {
 | 
				
			||||||
 | 
					  list.value.splice(index, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function handleClick(item) {
 | 
				
			||||||
 | 
					  console.log(item);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  handleLoadMore();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-card shadow="never" class="!h-[85vh]">
 | 
				
			||||||
 | 
					    <template #header>
 | 
				
			||||||
 | 
					      <div class="card-header">
 | 
				
			||||||
 | 
					        <span class="font-medium">
 | 
				
			||||||
 | 
					          瀑布流组件,采用开源的
 | 
				
			||||||
 | 
					          <el-link
 | 
				
			||||||
 | 
					            href="https://github.com/heikaimu/vue3-waterfall-plugin"
 | 
				
			||||||
 | 
					            target="_blank"
 | 
				
			||||||
 | 
					            style="margin: 0 4px 5px; font-size: 16px"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            vue-waterfall-plugin-next
 | 
				
			||||||
 | 
					          </el-link>
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <el-scrollbar height="78vh" class="content">
 | 
				
			||||||
 | 
					      <Waterfall :list="list" v-bind="options">
 | 
				
			||||||
 | 
					        <template #item="{ item, url, index }">
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            class="bg-gray-900 rounded-lg shadow-md overflow-hidden transition-all duration-300 ease-linear hover:shadow-lg hover:shadow-gray-600 group"
 | 
				
			||||||
 | 
					            @click="handleClick(item)"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <div class="overflow-hidden">
 | 
				
			||||||
 | 
					              <LazyImg
 | 
				
			||||||
 | 
					                :url="url"
 | 
				
			||||||
 | 
					                class="cursor-pointer transition-all duration-300 ease-linear group-hover:scale-105"
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="px-4 pt-2 pb-4 border-t border-t-gray-800">
 | 
				
			||||||
 | 
					              <h4 class="pb-4 text-gray-50 group-hover:text-yellow-300">
 | 
				
			||||||
 | 
					                {{ item.name }}
 | 
				
			||||||
 | 
					              </h4>
 | 
				
			||||||
 | 
					              <div
 | 
				
			||||||
 | 
					                class="pt-3 flex justify-between items-center border-t border-t-gray-600 border-opacity-50"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <div class="text-gray-50">$ {{ item.price }}</div>
 | 
				
			||||||
 | 
					                <div>
 | 
				
			||||||
 | 
					                  <button
 | 
				
			||||||
 | 
					                    class="px-3 h-7 rounded-full bg-red-500 text-sm text-white shadow-lg transition-all duration-300 hover:bg-red-600"
 | 
				
			||||||
 | 
					                    @click.stop="handleDelete(item, index)"
 | 
				
			||||||
 | 
					                  >
 | 
				
			||||||
 | 
					                    删除
 | 
				
			||||||
 | 
					                  </button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </template>
 | 
				
			||||||
 | 
					      </Waterfall>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="flex justify-center py-10">
 | 
				
			||||||
 | 
					        <button
 | 
				
			||||||
 | 
					          class="px-5 py-2 rounded-full bg-gray-700 text-md text-white cursor-pointer hover:bg-gray-800 transition-all duration-300"
 | 
				
			||||||
 | 
					          @click="handleLoadMore"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          加载更多
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <el-backtop
 | 
				
			||||||
 | 
					        title="回到顶部"
 | 
				
			||||||
 | 
					        :right="35"
 | 
				
			||||||
 | 
					        :visibility-height="400"
 | 
				
			||||||
 | 
					        target=".content .el-scrollbar__wrap"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <backTop />
 | 
				
			||||||
 | 
					      </el-backtop>
 | 
				
			||||||
 | 
					    </el-scrollbar>
 | 
				
			||||||
 | 
					  </el-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								src/views/components/waterfall/loading.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/views/components/waterfall/loading.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.3 KiB  | 
@ -1,16 +1,19 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useRouter } from "vue-router";
 | 
				
			||||||
import back from "@/assets/svg/back.svg?component";
 | 
					import back from "@/assets/svg/back.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "Empty"
 | 
					  name: "Empty"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="w-full h-full text-center">
 | 
					  <div class="w-full h-full text-center">
 | 
				
			||||||
    <h1>业务内容模块</h1>
 | 
					    <h1>业务内容模块</h1>
 | 
				
			||||||
    <p>使用场景:需要外嵌平台某个页面,不需要展示菜单导航以及额外模块</p>
 | 
					    <p>使用场景:需要外嵌平台某个页面,不需要展示菜单导航以及额外模块</p>
 | 
				
			||||||
    <div class="back" title="返回上一页" @click="$router.go(-1)">
 | 
					    <div class="back" title="返回上一页" @click="router.go(-1)">
 | 
				
			||||||
      <back class="w-[80px] h-[80px]" />
 | 
					      <back class="w-[80px] h-[80px]" />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,12 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useRouter } from "vue-router";
 | 
				
			||||||
import noAccess from "@/assets/status/403.svg?component";
 | 
					import noAccess from "@/assets/status/403.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "403"
 | 
					  name: "403"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@ -46,7 +49,7 @@ defineOptions({
 | 
				
			|||||||
      </p>
 | 
					      </p>
 | 
				
			||||||
      <el-button
 | 
					      <el-button
 | 
				
			||||||
        type="primary"
 | 
					        type="primary"
 | 
				
			||||||
        @click="$router.push('/')"
 | 
					        @click="router.push('/')"
 | 
				
			||||||
        v-motion
 | 
					        v-motion
 | 
				
			||||||
        :initial="{
 | 
					        :initial="{
 | 
				
			||||||
          opacity: 0,
 | 
					          opacity: 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,12 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useRouter } from "vue-router";
 | 
				
			||||||
import noExist from "@/assets/status/404.svg?component";
 | 
					import noExist from "@/assets/status/404.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "404"
 | 
					  name: "404"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@ -46,7 +49,7 @@ defineOptions({
 | 
				
			|||||||
      </p>
 | 
					      </p>
 | 
				
			||||||
      <el-button
 | 
					      <el-button
 | 
				
			||||||
        type="primary"
 | 
					        type="primary"
 | 
				
			||||||
        @click="$router.push('/')"
 | 
					        @click="router.push('/')"
 | 
				
			||||||
        v-motion
 | 
					        v-motion
 | 
				
			||||||
        :initial="{
 | 
					        :initial="{
 | 
				
			||||||
          opacity: 0,
 | 
					          opacity: 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,12 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useRouter } from "vue-router";
 | 
				
			||||||
import noServer from "@/assets/status/500.svg?component";
 | 
					import noServer from "@/assets/status/500.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "500"
 | 
					  name: "500"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@ -46,7 +49,7 @@ defineOptions({
 | 
				
			|||||||
      </p>
 | 
					      </p>
 | 
				
			||||||
      <el-button
 | 
					      <el-button
 | 
				
			||||||
        type="primary"
 | 
					        type="primary"
 | 
				
			||||||
        @click="$router.push('/')"
 | 
					        @click="router.push('/')"
 | 
				
			||||||
        v-motion
 | 
					        v-motion
 | 
				
			||||||
        :initial="{
 | 
					        :initial="{
 | 
				
			||||||
          opacity: 0,
 | 
					          opacity: 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -120,6 +120,7 @@ export function useDept() {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      width: "40%",
 | 
					      width: "40%",
 | 
				
			||||||
      draggable: true,
 | 
					      draggable: true,
 | 
				
			||||||
 | 
					      fullscreenIcon: true,
 | 
				
			||||||
      closeOnClickModal: false,
 | 
					      closeOnClickModal: false,
 | 
				
			||||||
      contentRenderer: () => h(editForm, { ref: formRef }),
 | 
					      contentRenderer: () => h(editForm, { ref: formRef }),
 | 
				
			||||||
      beforeSure: (done, { options }) => {
 | 
					      beforeSure: (done, { options }) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -101,14 +101,14 @@ function onCloseTags() {
 | 
				
			|||||||
    <el-button class="m-2" @click="onCloseTags">关闭标签</el-button>
 | 
					    <el-button class="m-2" @click="onCloseTags">关闭标签</el-button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-divider />
 | 
					    <el-divider />
 | 
				
			||||||
    <el-button @click="$router.push({ name: 'Menu1-2-2' })">
 | 
					    <el-button @click="router.push({ name: 'Menu1-2-2' })">
 | 
				
			||||||
      跳转页内菜单(传name对象,优先推荐)
 | 
					      跳转页内菜单(传name对象,优先推荐)
 | 
				
			||||||
    </el-button>
 | 
					    </el-button>
 | 
				
			||||||
    <el-button @click="$router.push('/nested/menu1/menu1-2/menu1-2-2')">
 | 
					    <el-button @click="router.push('/nested/menu1/menu1-2/menu1-2-2')">
 | 
				
			||||||
      跳转页内菜单(直接传要跳转的路径)
 | 
					      跳转页内菜单(直接传要跳转的路径)
 | 
				
			||||||
    </el-button>
 | 
					    </el-button>
 | 
				
			||||||
    <el-button
 | 
					    <el-button
 | 
				
			||||||
      @click="$router.push({ path: '/nested/menu1/menu1-2/menu1-2-2' })"
 | 
					      @click="router.push({ path: '/nested/menu1/menu1-2/menu1-2-2' })"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      跳转页内菜单(传path对象)
 | 
					      跳转页内菜单(传path对象)
 | 
				
			||||||
    </el-button>
 | 
					    </el-button>
 | 
				
			||||||
@ -116,7 +116,7 @@ function onCloseTags() {
 | 
				
			|||||||
    <el-divider />
 | 
					    <el-divider />
 | 
				
			||||||
    <el-button
 | 
					    <el-button
 | 
				
			||||||
      @click="
 | 
					      @click="
 | 
				
			||||||
        $router.push({
 | 
					        router.push({
 | 
				
			||||||
          name: 'Menu1-2-2',
 | 
					          name: 'Menu1-2-2',
 | 
				
			||||||
          query: { text: '传name对象,优先推荐' }
 | 
					          query: { text: '传name对象,优先推荐' }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
@ -126,7 +126,7 @@ function onCloseTags() {
 | 
				
			|||||||
    </el-button>
 | 
					    </el-button>
 | 
				
			||||||
    <el-button
 | 
					    <el-button
 | 
				
			||||||
      @click="
 | 
					      @click="
 | 
				
			||||||
        $router.push({
 | 
					        router.push({
 | 
				
			||||||
          path: '/nested/menu1/menu1-2/menu1-2-2',
 | 
					          path: '/nested/menu1/menu1-2/menu1-2-2',
 | 
				
			||||||
          query: { text: '传path对象' }
 | 
					          query: { text: '传path对象' }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
@ -143,7 +143,7 @@ function onCloseTags() {
 | 
				
			|||||||
    </el-link>
 | 
					    </el-link>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-divider />
 | 
					    <el-divider />
 | 
				
			||||||
    <el-button @click="$router.push({ name: 'Empty' })">
 | 
					    <el-button @click="router.push({ name: 'Empty' })">
 | 
				
			||||||
      跳转无Layout的空白页面
 | 
					      跳转无Layout的空白页面
 | 
				
			||||||
    </el-button>
 | 
					    </el-button>
 | 
				
			||||||
  </el-card>
 | 
					  </el-card>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							@ -41,6 +41,10 @@ type DeepPartial<T> = {
 | 
				
			|||||||
  [P in keyof T]?: DeepPartial<T[P]>;
 | 
					  [P in keyof T]?: DeepPartial<T[P]>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Exclusive<T, U> = (Without<T, U> & U) | (Without<U, T> & T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TimeoutHandle = ReturnType<typeof setTimeout>;
 | 
					type TimeoutHandle = ReturnType<typeof setTimeout>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type IntervalHandle = ReturnType<typeof setInterval>;
 | 
					type IntervalHandle = ReturnType<typeof setInterval>;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user