達成するためのメニュー機能
メニューインタフェースパッケージ
一つのペア削除管理メニューメニューツリー構造変化の検索操作です。
メニューは、全体の歯メニューのツリー構造を照会するためのクエリインターフェイスを提供します。
HTTP /モジュール/ menu.js findMenuTreeインターフェイスを追加します。
Axiosインポート」../axios'から / * *メニュー管理モジュール * / //保存 エクスポート保存=一定(データ)=> { リターンAxios({ URL: '/ MENU /保存'、 メソッド'POST'、 データ }) } //削除 エクスポートbatchDelete =一定(データ)=> { リターンAxios({ '/ MENU /削除'、:URL 'POST'、:方法 データを }) } //ナビゲーションメニューツリーを見つける (= findNavTree constの輸出をparamsは)=> { リターンAxios({ URL: '/ MENU / findNavTree'、 方法: 'GET'、 paramsは }) } //ナビゲーションメニューツリーを探します findMenuTree =()constは輸出=> { 戻りaxios({ URL: '/メニュー/ findMenuTree'、 メソッド: '取得' }) }
メニュー管理インターフェース
コンポーネントディスプレイインタフェースパッケージ管理メニューツリー構造テーブルを使用してメニュー、およびCRUD機能を提供します。
Menu.vue
<テンプレート> の<divクラス= "コンテナ"スタイル= "幅:99%;マージントップ:-25px;"> <! -工具栏- > <divのクラス= "ツールバー"スタイル= "フロート:左;パディングトップ:10pxの;パディング左:15ピクセル; "> <EL-形式:インライン="真」:モデル= "フィルタ":サイズ= "サイズ"> <EL-フォーム項目> <EL-入力V-モデル= "filters.name"プレースホルダ= "名称"> </ EL-入力> </ EL-フォーム項目> <EL-フォーム項目> <KT-ボタン・ラベル= "查询"パーマ= "SYS:メニュー:ビュー」タイプ= "主" @クリック= "findTreeData(ヌル)" /> </ EL-フォーム項目> <EL-フォーム項目> <KT-ボタンのラベル= "新增"パーマ= "SYS:メニュー:アドオン"タイプ= "主" @クリック= "handleAdd" /> </ EL-フォーム項目> </ EL-フォーム> </ div> <! -表格树内容栏- > <EL-テーブル:データ= "tableTreeDdata"ストライプサイズ= "ミニ"スタイル= "幅:100%;" Vロード= "装填"要素ローディングテキスト= "拼命加载中"> <EL-テーブル列 プロパ= "ID"ヘッダALIGN = "中心" ALIGN = "中心"幅= "80"ラベル=」 ID "> </ EL-テーブル列> <表ツリーカラム プロップ="名前」ヘッダALIGN = "中心" treeKey = "ID"幅= "150"ラベル= "名称"> </テーブル、ツリー-column> <EL-テーブル列ヘッダALIGN = "中心" ALIGN = "中心"ラベル= "图标"> <EL-テーブルカラムプロップ= "タイプ"ヘッダ・ALIGN = "中心" ALIGN = "中心"ラベル= "类型"> <テンプレートスロットスコープ= "範囲"> <EL-タグV-IF = "スコープ。 row.type === 0"サイズ= "小">目录</ ELタグ> <EL-タグV-ELSE-IF = "scope.row.type === 1"サイズ= "小"タイプ=」成功">菜单</ EL-タグ> <EL-タグV-ELSE-IF =" scope.row.type === 2"サイズ= "小さな"タイプ= "情報">按钮</ EL-タグ> < /テンプレート> </ EL-テーブル列> <EL-テーブルカラム プロップ= "parentName"ヘッダ・ALIGN = "中心" ALIGN = "中心"幅= "120"ラベル=」上级菜单「> </エル・テーブルのカラム> <エル・テーブルのカラム プロパ=" URL」ヘッダALIGN = "中心" ALIGN = "中心"幅= "150" :ショーオーバーフロー-ツールチップ=」true」のラベル= 『菜单URL』> </エル・テーブルのカラム> <EL-テーブルカラム プロップ= "パーマ"ヘッダ・ALIGN = "中心" ALIGN = "中心"幅= "150" :ショーoverflow-ツールチップ= "true"のラベル= "授权标识"> </ EL-テーブル列> <EL-テーブルカラム プロップ= "orderNum"ヘッダALIGN = "中心" ALIGN = "中心"ラベル= "排序"> < / EL-テーブル列> <EL-テーブルカラム 固定= "右"ヘッダALIGN = "中心" ALIGN = "中心"幅= "150"ラベル= "操作"> <テンプレートスロットスコープ= "範囲" > <KT-ボタンのラベル= "修改"パーマ= "SYS:メニュー:編集"をクリックし@ = "handleEdit(scope.row)" /> <KT-ボタンのラベル= "删除"パーマ= "SYS:メニュー:削除"タイプ=クリック= "handleDelete(scope.row)" @ "危険" /> </テンプレート> </エル・テーブルのカラム> <EL-フォーム項目:LABEL = "menuTypeList [dataForm.type] + '名称'"小道具= "名前"> </ EL-表> <! -新しい編集インターフェイス- > <エル・ダイアログ:タイトル= "dataForm.id '新增':!? '修改'"幅= "40%":visible.sync = "dialogVisible":クローズオンクリックモーダル= "偽"> < EL-形式:モデル= "データ形式":ルール= "dataRule" REF = "データ形式" @ keyup.enter.native = "submitForm()" ラベル幅= "80px":サイズ= "サイズ"スタイル= "テキストベース整列:左; "> <EL-フォーム項目ラベル="菜单类型"プロップ= "タイプ"> <EL-無線-V族モデル= "dataForm.type"> <EL-無線V-ため="(タイプ、menuTypeListインデックス)」:ラベル= "インデックス":キー= "インデックス"> {{タイプ}} </ EL-ラジオ> </ EL-無線グループ> </ EL-フォーム項目> <EL-入力V-モデル= "dataForm.name":プレースホルダ= "menuTypeList [dataForm.type] + '名称'"> </ EL-入力> </ EL-フォーム項目> <エル・フォーム・アイテム・ラベル= "上级菜单"小道具= "parentName"> <ポップアップツリー入力 :データ= "popupTreeData":小道具= "popupTreeProps":?小道具= "dataForm.parentName == nullの"根节点「:dataForm.parentName」 :nodeKey = "'+ dataForm.parentId":currentChangeHandle = "handleTreeSelectChange"> </ポップアップツリー入力> </ EL-フォーム項目> <EL-フォーム項目V-IF = "dataForm.type === 1"ラベル= "菜单路由"プロップ= "URL"> <EL-入力V-モデル= "dataForm.url"プレースホルダ= "菜单路由"> </ EL-入力> </ EL -体項目> <EL-フォーム項目V-IF = "dataForm.type!== 0"ラベル= "授权标识"小道具=「パーマ」> <EL-入力Vモデル=」dataForm.perms」プレースホルダ= "如:SYS:ユーザー:追加、SYS:ユーザ編集、SYS:ユーザー:削除"> </ EL-入力> </ EL-フォーム項目> <EL-フォーム項目V-IF = "dataForm.type!== 2"ラベル= "排序编号"プロップ= "orderNum"> <EL-入力番号vモデル= "dataForm.orderNum"コントロール位置= "右":最小= "0"ラベル= "排序编号"> </ EL-入力番号> </ EL-フォーム項目> <EL-フォーム項目のV-IF = "dataForm.type == 2! "ラベル="菜单图标」小道具= "アイコン"> <EL-行> <EL-COL:スパン= "22"> <! - <EL-ポップオーバー REF = "iconListPopover" 配置= "ボトムスタート" トリガー= "クリック" ポッパークラスを= "MOD-menu__icon-ポップオーバー"> 「= <divのクラスをMOD-menu__iconリスト"> <EL-ボタン = V-のための" dataForm.iconListで(アイテム、インデックス)」 :キー= "インデックス" @クリック= "iconActiveHandle(アイテム)" :クラス= "{ 'である活性':アイテム=== dataForm.icon}"> <アイコンSVG :名= "アイテム"> </アイコン-SVG> </ EL-ボタン> </ div> </ EL-ポップオーバー> - > <EL-入力Vモデル= "dataForm.icon" V-ポップオーバー:iconListPopover :読み取り専用= "true"のプレースホルダ= "菜单图标名称(如:FA、FA-家庭FA-LG)"クラス= "アイコンlist__input"> </ EL-入力> </ EL-COL> <EL-COL:スパン= "2"クラス=」アイコンlist__tips "> <FA-アイコンのツールチップ/> </ EL-COL> </ EL-行> </ EL-フォーム項目> データ(){ </ EL-形態> <スパンスロット= "フッタ"クラス= "ダイアログ・フッタ"> <EL-ボタン:サイズ= "サイズ" @クリック= "dialogVisible =偽">取消</ EL-ボタン> <EL-ボタン:サイズ= "サイズ"タイプ=クリック= "submitForm()" @ "主">确定</ EL-ボタン> </ span>を </ EL-ダイアログ> </ div> </テンプレート> <スクリプト> 輸入KtButtonから"@ /ビュー/コア/ KtButton" 「からの輸入TableTreeColumn @ /ビュー/コア/ TableTreeColumn」 "@ /コンポーネント/ PopupTreeInput"からインポートPopupTreeInput "@ /コンポーネント/ FaIconTooltip"からインポートFaIconTooltip 輸出デフォルト{ {:コンポーネント PopupTreeInput、 KtButton、 TableTreeColumn、 FaIconTooltip }、 リターン{ サイズ: '小'、 ローディング:falseに、 フィルター:{ 名: '' }、 tableTreeDdata:[]、 dialogVisible:falseに、 menuTypeList:[ 'カタログ'、 'メニュー'、 'ボタン']、 データフォーム:{ ID:0、 タイプ:. 1 、 名前: ''、 PARENTID:0、 parentName: ''、 URL: ''、 PERMS: ''、 orderNum:0、 アイコン: ''、 iconList:[] }、 dataRule:{ 名:[ {必須:trueにメッセージ:、トリガー「メニュー名は空にすることはできません」: 'ブラー」} ]、 parentName:[ {必須:真、メッセージ: '上级菜单不能为空'、トリガー'変更'} ] }、 popupTreeData:[]、 popupTreeProps:{ ラベル: '名前'、 子供: '子供' } } }、 方法:{ //获取数据 findTreeData:機能(){ this.loading =真 この$ api.menu.findMenuTree()、その後((RES)=> {。。 this.tableTreeDdata = res.data this.popupTreeData =これ。 getParentMenuTree(res.data) this.loading = FALSE }) }、 //前のメニューツリーを取得します。 getParentMenuTree:機能(tableTreeDdata){ letの親= { PARENTID:-1、 名前: 'ルート'、 子供:tableTreeDdata } リターン[親] }、 //新しい表示画面 handleAdd:機能(){ this.dialogVisibleに真= = {this.dataForm ID:0、 タイプ1 :.、 typelistに:[ 'カタログ'、 'メニュー'、 'ボタン']、 名前: ''、 PARENTID:0、 parentName: ''、 URL: ''、 PERMS。 ''、 orderNum:0、 アイコン'」、 iconList:[] } }、 //編集画面表示 {関数(行):handleEdit 真=にthis.dialogVisibleを Object.assign(this.dataForm、行); } //削除 handleDelete(行){ この$確認(「削除を確認します。 ?選択されたレコードは、 ''プロンプト'{行う タイプ:'警告」を }。)その後、(()=> { のlet this.getDeleteIdsのparams =([]、行) この$のapi.menu.batchDelete(のparams)..その後、(RES => { this.findTreeData()は、 これは$メッセージ({メッセージ:。タイプで、 '正常に削除': '成功'}) }) }) }、 //取得削除されたIDリストは、サブメニューが含まれ getDeleteIdsを( IDS、行){ :ids.push({row.id ID}) (row.children = NULL!)なら、{ {(; I <lenのI ++ i = 0、LEN = row.children.lengthせて)ため this.getDeleteIds(IDS、 row.children [I]) } } 戻りIDS } //菜单树选中 handleTreeSelectChange(データノード){ this.dataForm.parentId = data.id this.dataForm.parentName = data.name } //图标选中 iconActiveHandle (iconName){ this.dataForm.icon = iconName } //表单提交 submitForm(){ この。$参考文献[ 'データ形式']。検証((有効)=> { IF(有効){ この。$確認( '确认提交吗?'、 '提示'、{})。その後、(()=> { this.dialogVisible = FALSE this.editLoading =真 せのparams = Object.assign({}、this.dataForm) 本。$ api.menu.save(paramsは).then((RES)=> { IF(res.code == 200){ この。$メッセージ({メッセージ: '操作成功'、タイプ'成功'}) }他{ 。この$メッセージ({メッセージ: '操作失败、' + res.msg、種類: 'エラー'}) } this.editLoading = falseを これ。 $レフリー[ 'データ形式']。resetFields() これ。findTreeData() }) }) } }) } }、 搭載(){ this.findTreeData() } } </ SCRIPT> <スタイルスコープ> </スタイル>
ここで、単純なツリーコンポーネントパッケージ用のテーブル。
ビュー/コア/ TableTreeColumn.vue
<テンプレート> <エル・テーブルのカラム:小道具= "小道具" V-バインド= "$ attrsに"> <テンプレートスロットスコープ= "スコープ"> <スパン@ click.prevent = "toggleHandle(スコープ$インデックス、スコープ。 .row)」:スタイル= "childStyles(scope.row)"> <I:クラス= "iconClasses(scope.row)"スタイル= "iconStyles(scope.row)"> </ I> {{scope.row 【プロパ]}} </スパン> </テンプレート> </ EL-テーブル列> </テンプレート> <スクリプト> 'lodash /でIsArray'からインポートでIsArray エクスポートデフォルト{ 名: 'テーブルツリー列'、 小道具:{ プロップ:{ タイプ:ストリング }、 treeKey:{ タイプ:文字列、 デフォルト: 'ID' }、 parentKey:{ タイプ:文字列、 デフォルト: 'PARENTID' }、 levelKey:{ タイプ:文字列 デフォルト: 'レベル' }、 childKey:{ タイプ:文字列、 デフォルト: '子供' } }、 メソッド:{ childStyles(行){ リターン{ 'パディング左':(行[this.levelKey] * 25)+ 'PX'} }、 iconClasses(行){ !リターン[row._expanded?'EL-アイコンキャレット右': 'EL-アイコンキャレット底'] }、 iconStyles(行){ リターン{ '可視':this.hasChild(行)?「目に見えます」: ' hasChild(行){ リターン(でIsArray(行[this.childKey])&&行[this.childKey] .LENGTH> = 1)|| 偽 } //切换处理 toggleHandle(インデックス、行){ IF(this.hasChild(行)){ VARデータ=この。$ parent.store.states.data.slice(0) データ[インデックス] ._拡張=!データ[インデックス] ._拡張 IF(データ[インデックス] ._拡張){ データ= data.splice(0、インデックス+ 1).concat(行[this.childKey])。連結(データ) }他{ データ=この。 removeChildNode(データ、行[this.treeKey]) } この。$ parent.store.commit( 'のsetData'、データ) この。$ nextTick(()=> { この。$ parent.doLayout() }) } } //移除子节点 } removeChildNode(データ、PARENTID){ VAR parentIds =でIsArray(PARENTID)?PARENTID:[PARENTID] IF(parentId.length <= 0){ 戻りデータ } VARのIDS = [] のための(VAR I = 0、I <data.length; I ++){ (parentIds.indexOf(データ[I] [もしthis.parentKey])!== -1 && parentIds.indexOf(データ[I] [this.treeKey])=== -1){ ids.push(data.splice(I、1)[0] [本。 treeKey]) i-- } 戻りthis.removeChildNode(データ、IDS) } } } </ SCRIPT>
テスト結果
最終的な試験結果を以下に示します。
ソースのダウンロード
バックエンド:https://gitee.com/liuge1988/kitty
フロントエンド:https://gitee.com/liuge1988/kitty-ui.git