更新默认首页显示问题

This commit is contained in:
神仙都没用 2023-12-02 20:09:24 +08:00
parent 8d802a92a5
commit 89a9259c1c
15 changed files with 128 additions and 101 deletions

View File

@ -9,7 +9,7 @@
"lint:eslint": "eslint \"./src/**/*.{vue,ts,tsx}\" --fix" "lint:eslint": "eslint \"./src/**/*.{vue,ts,tsx}\" --fix"
}, },
"dependencies": { "dependencies": {
"@cool-vue/crud": "^7.0.7", "@cool-vue/crud": "^7.0.8",
"@element-plus/icons-vue": "^2.1.0", "@element-plus/icons-vue": "^2.1.0",
"@vueuse/core": "^10.4.0", "@vueuse/core": "^10.4.0",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",

View File

@ -1,6 +1,6 @@
{ {
"name": "@cool-vue/crud", "name": "@cool-vue/crud",
"version": "7.0.7", "version": "7.0.8",
"private": false, "private": false,
"main": "./dist/index.umd.min.js", "main": "./dist/index.umd.min.js",
"typings": "types/index.d.ts", "typings": "types/index.d.ts",

View File

@ -1,5 +1,5 @@
import { defineComponent, h, nextTick } from "vue"; import { defineComponent, h, nextTick } from "vue";
import { cloneDeep, isBoolean, isEmpty } from "lodash-es"; import { cloneDeep, isBoolean } from "lodash-es";
import { useAction, useForm, usePlugins, useTabs } from "./helper"; import { useAction, useForm, usePlugins, useTabs } from "./helper";
import { useBrowser, useConfig, useElApi, useRefs } from "../../hooks"; import { useBrowser, useConfig, useElApi, useRefs } from "../../hooks";
import { getValue, merge } from "../../utils"; import { getValue, merge } from "../../utils";

View File

@ -1,6 +1,6 @@
.cl-crud { .cl-crud {
height: 100%; height: 100%;
overflow: auto; overflow: hidden auto;
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
background-color: #fff; background-color: #fff;
@ -362,7 +362,9 @@
position: absolute; position: absolute;
bottom: -1px; bottom: -1px;
left: 0; left: 0;
transition: transform 0.3s ease-in-out, width 0.2s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1); transition:
transform 0.3s ease-in-out,
width 0.2s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
background-color: var(--el-color-primary); background-color: var(--el-color-primary);
} }

View File

@ -6,10 +6,10 @@
background-color="transparent" background-color="transparent"
@select="select" @select="select"
> >
<template v-for="(item, index) in menu.group" :key="index"> <template v-for="(item, index) in list" :key="item.id">
<el-menu-item :index="`${index}`" v-if="item.isShow"> <el-menu-item :index="`${index}`">
<cl-svg v-if="item.icon" :name="item.icon" :size="18" /> <cl-svg v-if="item.icon" :name="item.icon" :size="18" />
<span class="a-menu__name">{{ item.name }}</span> <span class="a-menu__name">{{ item.meta?.label }}</span>
</el-menu-item> </el-menu-item>
</template> </template>
</el-menu> </el-menu>
@ -17,52 +17,82 @@
</template> </template>
<script lang="ts" name="a-menu" setup> <script lang="ts" name="a-menu" setup>
import { ref, watch } from "vue"; import { computed, ref, watch } from "vue";
import { useBase, Menu } from "/$/base"; import { useBase, Menu } from "/$/base";
import { useCool } from "/@/cool"; import { useCool } from "/@/cool";
import { ElMessage } from "element-plus";
const { router, route } = useCool(); const { router, route } = useCool();
const { menu } = useBase(); const { menu } = useBase();
// //
const active = ref(""); const active = ref("0");
//
const list = computed(() => {
return menu.group.filter((e) => e.isShow);
});
// //
function select(index: any) { function select(index: any) {
menu.setMenu(index); if (String(index) == active.value) {
return false;
}
//
const item = list.value[index];
// //
const url = menu.getPath(menu.group[index]); const url = menu.getPath(item);
router.push(url);
if (url) {
//
menu.setMenu(index);
//
router.push(url);
} else {
ElMessage.warning(`${item.meta?.label}”下没有菜单,请先添加`);
}
} }
// //
function refresh() { function refresh() {
let index = 0;
function deep(e: Menu.Item, i: number) { function deep(e: Menu.Item, i: number) {
switch (e.type) { switch (e.type) {
case 0: case 0:
(e.children || []).forEach((e) => { if (e.children) {
deep(e, i); e.children.forEach((e) => {
}); deep(e, i);
});
}
break; break;
case 1: case 1:
if (route.path.includes(e.path)) { if (route.path.includes(e.path)) {
active.value = String(i); index = i;
menu.setMenu(i);
} }
break; break;
case 2:
default: default:
break; break;
} }
} }
menu.group.forEach(deep); //
list.value.forEach(deep);
//
active.value = String(index);
//
menu.setMenu(index);
} }
// //
watch( watch(
() => menu.group.length, () => [route.path, menu.group.length],
() => { () => {
refresh(); refresh();
}, },
@ -70,14 +100,6 @@ watch(
immediate: true immediate: true
} }
); );
//
watch(
() => route.path,
() => {
refresh();
}
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -33,7 +33,7 @@ export default defineComponent({
return ( return (
<div class="wrap"> <div class="wrap">
<cl-svg name={e.icon} /> <cl-svg name={e.icon} />
<span v-show={!app.isFold || index != 1}>{e.name}</span> <span v-show={!app.isFold || index != 1}>{e.meta?.label}</span>
</div> </div>
); );
}; };
@ -59,7 +59,12 @@ export default defineComponent({
html = h( html = h(
<el-menu-item />, <el-menu-item />,
{ {
index: e.path, index:
route.path == "/"
? e.meta?.isHome
? "/"
: e.path
: e.path,
key: e.id key: e.id
}, },
{ {

View File

@ -7,7 +7,7 @@
<li class="item" @click="toRefresh"> <li class="item" @click="toRefresh">
<i class="cl-iconfont cl-icon-refresh"></i> <i class="cl-iconfont cl-icon-refresh"></i>
</li> </li>
<li class="item" @click="router.push('/')"> <li class="item" @click="toHome">
<i class="cl-iconfont cl-icon-home"></i> <i class="cl-iconfont cl-icon-home"></i>
</li> </li>
</ul> </ul>
@ -50,6 +50,11 @@ function toRefresh() {
mitt.emit("view.refresh"); mitt.emit("view.refresh");
} }
//
function toHome() {
router.push("/");
}
// //
function toPath() { function toPath() {
const d = process.list.find((e) => e.active); const d = process.list.find((e) => e.active);

View File

@ -1,7 +1,7 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { ref } from "vue"; import { ref } from "vue";
import { deepTree, revDeepTree, storage } from "/@/cool/utils"; import { deepTree, revDeepTree, storage } from "/@/cool/utils";
import { isEmpty, orderBy } from "lodash-es"; import { cloneDeep, isArray, isEmpty, orderBy } from "lodash-es";
import { router, service } from "/@/cool"; import { router, service } from "/@/cool";
import { revisePath } from "../utils"; import { revisePath } from "../utils";
import { Menu } from "../types"; import { Menu } from "../types";
@ -17,9 +17,6 @@ export const useMenuStore = defineStore("menu", function () {
// 菜单组 // 菜单组
const group = ref<Menu.List>(data["base.menuGroup"] || []); const group = ref<Menu.List>(data["base.menuGroup"] || []);
// 顶部菜单序号
const index = ref(0);
// 左侧菜单列表 // 左侧菜单列表
const list = ref<Menu.List>([]); const list = ref<Menu.List>([]);
@ -27,15 +24,10 @@ export const useMenuStore = defineStore("menu", function () {
const perms = ref<any[]>(data["base.menuPerms"] || []); const perms = ref<any[]>(data["base.menuPerms"] || []);
// 设置左侧菜单 // 设置左侧菜单
function setMenu(i?: number) { function setMenu(i: number = 0) {
if (i === undefined) {
i = index.value;
}
// 显示分组显示菜单 // 显示分组显示菜单
if (config.app.menu.isGroup) { if (config.app.menu.isGroup) {
list.value = group.value[i]?.children || []; list.value = group.value.filter((e) => e.isShow)[i]?.children || [];
index.value = i;
} else { } else {
list.value = group.value; list.value = group.value;
} }
@ -71,30 +63,35 @@ export const useMenuStore = defineStore("menu", function () {
// 设置视图 // 设置视图
function setRoutes(list: Menu.List) { function setRoutes(list: Menu.List) {
// 默认第一个菜单为首页 // 获取第一个菜单路径
const fp = getPath(group.value[0]); const fp = getPath(group.value);
// 查找符合路由 // 查找符合路由
const route = list.find((e) => e.path == fp); const route = list.find((e) => (e.meta!.isHome = e.path == fp));
if (route) { if (route) {
// 判断是否已经注册 const home = router.getRoutes().find((e) => e.meta.isHome);
if (!router.getRoutes().find((e) => e.name == "home")) {
const newRoute = { // 判断是否存在
...route, if (!home) {
path: "/", router.append([
name: "home" {
}; ...route,
router.append([Object.assign({}, newRoute)]); path: "/",
name: "home"
}
]);
} else {
Object.assign(home.meta, route.meta);
} }
} }
routes.value = list; routes.value = list.filter((e) => e.type == 1);
} }
// 设置菜单组 // 设置菜单组
function setGroup(list: Menu.List) { function setGroup(list: Menu.List) {
group.value = orderBy(list, "orderNum"); group.value = orderBy(deepTree(list), "orderNum");
storage.set("base.menuGroup", group.value); storage.set("base.menuGroup", group.value);
} }
@ -113,9 +110,10 @@ export const useMenuStore = defineStore("menu", function () {
isShow, isShow,
meta: { meta: {
...e.meta, ...e.meta,
label: e.name, label: e.name, // 菜单名称的唯一标识
keepAlive: e.keepAlive || 0 keepAlive: e.keepAlive || 0
}, },
name: `${e.name}-${e.id}`, // 避免重复命名之前的冲突
children: [] children: []
}; };
}); });
@ -124,13 +122,13 @@ export const useMenuStore = defineStore("menu", function () {
setPerms(res.perms || []); setPerms(res.perms || []);
// 设置菜单组 // 设置菜单组
setGroup(deepTree(list)); setGroup(list);
// 设置视图路由 // 设置视图路由
setRoutes(list.filter((e) => e.type == 1)); setRoutes(list);
// 设置菜单 // 设置菜单
setMenu(index.value); setMenu();
return list; return list;
} }
@ -147,38 +145,34 @@ export const useMenuStore = defineStore("menu", function () {
} }
// 获取菜单路径 // 获取菜单路径
function getPath(item?: Menu.Item) { function getPath(data: Menu.Item | Menu.List) {
const list = isArray(data) ? data : [data];
let path = ""; let path = "";
switch (item?.type) { function deep(arr: Menu.List) {
case 0: arr.forEach((e: Menu.Item) => {
function deep(arr: Menu.List) { switch (e.type) {
arr.forEach((e: Menu.Item) => { case 0:
if (e.type == 1) { deep(e.children || []);
if (!path) { break;
path = e.path; case 1:
} if (!path) {
} else { path = e.path;
deep(e.children || []);
} }
}); break;
} }
});
deep(item.children || group.value || []);
break;
case 1:
path = item.path;
break;
} }
return path || "/"; deep(list);
return path;
} }
return { return {
routes, routes,
group, group,
index,
list, list,
perms, perms,
get, get,

View File

@ -11,7 +11,7 @@ export const useProcessStore = defineStore("process", function () {
e.active = false; e.active = false;
}); });
if (data.path != "/" && data.meta?.process !== false) { if (!data.meta?.isHome && data.meta?.process !== false) {
const index = list.value.findIndex((e) => e.path === data.path); const index = list.value.findIndex((e) => e.path === data.path);
if (index < 0) { if (index < 0) {

View File

@ -23,6 +23,8 @@ export declare namespace Menu {
label?: string; label?: string;
keepAlive?: number | boolean; keepAlive?: number | boolean;
iframeUrl?: string; iframeUrl?: string;
isHome?: boolean;
[key: string]: any;
}; };
children?: Item[]; children?: Item[];
component?: RouteComponent; component?: RouteComponent;

View File

@ -141,7 +141,7 @@ const Upsert = useUpsert({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
rows: 6, rows: 12,
type: "textarea" type: "textarea"
} }
} }

View File

@ -1,12 +1,12 @@
import { Merge, ModuleConfig } from "/@/cool"; import { Merge, ModuleConfig } from "/@/cool";
// npm // npm
import Crud, { locale } from "@cool-vue/crud"; // import Crud, { locale } from "@cool-vue/crud";
import "@cool-vue/crud/dist/index.css"; // import "@cool-vue/crud/dist/index.css";
// 调试、自定义crud // 调试、自定义crud
// import Crud, { locale } from "../../../packages/crud/src"; import Crud, { locale } from "../../../packages/crud/src";
// import "../../../packages/crud/src/static/index.scss"; import "../../../packages/crud/src/static/index.scss";
export default (): Merge<ModuleConfig, CrudOptions> => { export default (): Merge<ModuleConfig, CrudOptions> => {
return { return {

View File

@ -7,7 +7,7 @@
> >
</div> </div>
<cl-crud :padding="0"> <cl-crud padding="0">
<cl-table :data="data" :ref="setRefs('table')" :auto-height="false" /> <cl-table :data="data" :ref="setRefs('table')" :auto-height="false" />
<cl-row type="flex" align="middle" justify="end" :style="{ marginTop: '10px' }"> <cl-row type="flex" align="middle" justify="end" :style="{ marginTop: '10px' }">
@ -23,7 +23,7 @@
</div> </div>
<cl-dialog v-model="visible" width="1200px" title="选择用户"> <cl-dialog v-model="visible" width="1200px" title="选择用户">
<cl-crud ref="Crud"> <cl-crud ref="Crud" padding="0">
<cl-row> <cl-row>
<!-- 刷新按钮 --> <!-- 刷新按钮 -->
<cl-refresh-btn /> <cl-refresh-btn />
@ -187,7 +187,7 @@ const selection = ref<any[]>([]);
// //
const pager = reactive({ const pager = reactive({
page: 1, page: 1,
size: 2 size: 10
}); });
// //

View File

@ -88,11 +88,7 @@
</cl-row> </cl-row>
<!-- 新增编辑 --> <!-- 新增编辑 -->
<cl-upsert ref="Upsert"> <cl-upsert ref="Upsert" />
<template #slot-userIds="{ scope }">
<select-user v-model="scope.userIds" />
</template>
</cl-upsert>
<!-- 高级搜索 --> <!-- 高级搜索 -->
<cl-adv-search ref="AdvSearch" /> <cl-adv-search ref="AdvSearch" />
@ -261,8 +257,9 @@ const Upsert = useUpsert({
props: { props: {
labelWidth: "0px" labelWidth: "0px"
}, },
required: true,
component: { component: {
name: "slot-userIds" vm: SelectUser
} }
}, },

View File

@ -344,10 +344,10 @@
"@babel/helper-validator-identifier" "^7.22.20" "@babel/helper-validator-identifier" "^7.22.20"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@cool-vue/crud@^7.0.7": "@cool-vue/crud@^7.0.8":
version "7.0.7" version "7.0.8"
resolved "https://registry.yarnpkg.com/@cool-vue/crud/-/crud-7.0.7.tgz#26362fda216a29636bbe0fb9ff4b2e792eecd235" resolved "https://registry.yarnpkg.com/@cool-vue/crud/-/crud-7.0.8.tgz#14855d5a326b5f91bb35b5791954341e5a61db23"
integrity sha512-IttV+abWH4AcQmIwLeeK2SWo9NMQdodQaRdAvKaf7SgWLO7K7l99gPIspyZzlQUDOfNr3lVFrlDSjIbApJpP1w== integrity sha512-hI8cyoRnRrwPNsyoVtb6nVCKVFFbsqhFH6HR1B2/NVRqfn87wvDoQ2kkm76K7kafO/bZM9WJu8tetYuqkaSoOw==
dependencies: dependencies:
array.prototype.flat "^1.2.4" array.prototype.flat "^1.2.4"
core-js "^3.21.1" core-js "^3.21.1"