Parcourir la source

feat: [菜单管理]支持修改菜的名称

louhangfei il y a 1 an
Parent
commit
b96c444874
1 fichiers modifiés avec 50 ajouts et 47 suppressions
  1. 50 47
      src/views/system/menu/MenuForm.vue

+ 50 - 47
src/views/system/menu/MenuForm.vue

@@ -21,18 +21,15 @@
     </el-form-item>
 
     <el-form-item label="菜单名称" required>
-      <el-tree-select
-        v-if="isCreating"
-        rowKey="key"
-        :data="routeViewList"
+      <el-autocomplete
+        value-key="label"
+        v-model="formParams.menuName"
         clearable
-        check-strictly
-        v-model="routeViewValue"
+        @select="handleSelectMenu"
+        :fetch-suggestions="querySearchMenu"
       />
-      <el-input v-else v-model="formParams.menuName" disabled />
     </el-form-item>
 
-
     <el-row :gutter="24">
       <el-col :span="12">
         <el-form-item prop="routeUrl">
@@ -80,8 +77,8 @@
                   <QuestionCircleOutlined />
                 </el-icon>
                 <template #content>
-                  访问的组件路径,如:`/system/menu/menu`,默认在`views`目录下,默认 `LAYOUT`
-                  如果是多级菜单 `ParentLayout`
+                  访问的组件路径,如:`/system/menu/menu`,默认在`views`目录下,默认 `LAYOUT` 如果是多级菜单
+                  `ParentLayout`
                 </template>
               </el-tooltip>
               <span>组件路径</span>
@@ -119,9 +116,7 @@
                 <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
                   <QuestionCircleOutlined />
                 </el-icon>
-                <template #content>
-                  默认跳转路由地址,如:`/system/menu/menu` 多级路由情况下适用
-                </template>
+                <template #content> 默认跳转路由地址,如:`/system/menu/menu` 多级路由情况下适用 </template>
               </el-tooltip>
               <span>默认路由</span>
             </div>
@@ -131,8 +126,6 @@
       </el-col>
     </el-row>
 
-
-
     <el-row :gutter="24">
       <el-col :span="12">
         <el-form-item label="菜单编码">
@@ -146,8 +139,6 @@
       </el-col>
     </el-row>
 
-
-
     <el-divider border-style="dashed" class="mb-10">功能设置</el-divider>
 
     <el-row :gutter="24">
@@ -216,9 +207,7 @@
                 <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
                   <QuestionCircleOutlined />
                 </el-icon>
-                <template #content
-                  >选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致</template
-                >
+                <template #content>选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致</template>
               </el-tooltip>
               <span>是否缓存</span>
             </div>
@@ -226,7 +215,7 @@
           <el-radio-group v-model="formParams.isCache" name="isCacheGroup">
             <el-radio-button label="不缓存" :value="0" />
             <el-radio-button label="缓存" :value="1" />
-          </el-radio-group>  
+          </el-radio-group>
         </el-form-item>
       </el-col>
     </el-row>
@@ -260,8 +249,7 @@
                   <QuestionCircleOutlined />
                 </el-icon>
                 <template #content
-                  >取消自动计算根路由模式
-                  开启之后,当菜单子菜单只有1个的时候,会直接显示子菜单</template
+                  >取消自动计算根路由模式 开启之后,当菜单子菜单只有1个的时候,会直接显示子菜单</template
                 >
               </el-tooltip>
               <span>简化路由</span>
@@ -287,7 +275,7 @@
 
 <script lang="ts" setup>
   import { ref, computed, watch, shallowRef } from 'vue';
-  import { ElMessage, FormInstance, FormRules } from 'element-plus';
+  import { ElMessage, FormInstance, FormRules, ElAutocomplete } from 'element-plus';
   import { addMenu, editMenu } from '@/api/system/menu';
   import { QuestionCircleOutlined } from '@vicons/antd';
   import { replaceParams } from '@/utils/helper/treeHelper';
@@ -338,7 +326,6 @@
     },
   };
 
-
   const subLoading = ref(false);
 
   const defaultFormParams: MenuDetailItem = {
@@ -360,7 +347,7 @@
     isCache: 0,
     isFrame: 0,
     frameSrc: '',
-    openType: 1, 
+    openType: 1,
     query: '',
     activeMenu: '',
   };
@@ -371,7 +358,7 @@
     return [
       {
         label: '顶级目录',
-        value: -1, // 约定顶级目录值是 -1. 
+        value: -1, // 约定顶级目录值是 -1.
         children: replaceParams(cloneDeep(props.parentMenuTree || []), 'label', 'id'),
       },
     ];
@@ -381,25 +368,33 @@
   const routeViewValue = ref('');
   const routeViewList = shallowRef<_RouteViewItem[]>([]);
 
-
   // 根据 "上级菜单",生成可选的"当前菜单"
   watch(
     () => formParams.value.parentId,
     (newVal) => {
       // 编辑模式下,只是展示,不需要计算数据。
       if (isEditing.value) return;
+      // 切换上级菜单的时候,子菜单的所有信息要清空
+      formParams.value.routeName = '';
+      formParams.value.routeUrl = '';
+      formParams.value.component = '';
+      formParams.value.icon = '';
+      formParams.value.menuName = '';
+      formParams.value.menuCode = '';
+      formParams.value.redirect = '';
+      formParams.value.activeMenu = '';
 
       // 若清除选项
       if (newVal == null) {
         routeViewList.value = [];
         return;
-      } 
+      }
 
       // 若选择顶级目录, 返回路由表的 leve1 列表
       if (newVal === -1) {
         routeViewList.value = getChildRoutesView(null);
         return;
-      } 
+      }
 
       // 否则展示 parent 下的 子路由
       const { routeName } = getTreeItem(props.parentMenuTree!, newVal, 'id') as Menu;
@@ -408,25 +403,9 @@
       } else {
         ElMessage.error('无法获取可用路由列表');
       }
-    }
+    },
   );
 
-  // 根据 routeViewValue,即 routeName,将菜单其余信息补充
-  watch(routeViewValue, (val) => {
-    if (!val) {
-      handleReset();
-      return;
-    }
-
-    const currentRoute = getRouteByName(val);
-    formParams.value.routeName = currentRoute.name;
-    formParams.value.routeUrl = currentRoute.path;
-    formParams.value.component = currentRoute.component;
-    formParams.value.icon = currentRoute.meta.icon as string;
-    formParams.value.menuName = currentRoute.meta.title as string;
-    formParams.value.activeMenu = currentRoute.meta.activeMenu as string || '';
-  });
-
   function setData(data: MenuDetailItem) {
     formParams.value = data;
     formRef.value?.resetFields();
@@ -472,6 +451,30 @@
     routeViewValue.value = '';
   }
 
+  // 选中菜单的下拉框
+  const handleSelectMenu = (e) => {
+    const currentRoute = getRouteByName(e.value);
+    formParams.value.routeName = currentRoute.name;
+    formParams.value.routeUrl = currentRoute.path;
+    formParams.value.component = currentRoute.component;
+    formParams.value.icon = currentRoute.meta.icon as string;
+    formParams.value.activeMenu = (currentRoute.meta.activeMenu as string) || '';
+  };
+
+  const createFilter = (queryString: string) => {
+    return (routerItem: _RouteViewItem) => {
+      const str = queryString.toLowerCase();
+      return routerItem.label.toLowerCase().includes(str) || routerItem.value.toLowerCase().includes(str);
+    };
+  };
+
+  // 根据输入的值,过滤出符合条件的路由
+  const querySearchMenu = (queryString: string, cb) => {
+    if (!queryString.trim()) return routeViewList.value;
+    const filterList = routeViewList.value.filter(createFilter(queryString));
+    cb(filterList);
+  };
+
   defineExpose({
     formSubmit,
     handleReset,