Menu.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <template>
  2. <div class="page-container">
  3. <div class="page-side">
  4. <el-scrollbar style="height:100%;padding:5px;box-sizing: border-box;">
  5. <el-tree :data="menus" :props="defaultProps" :highlight-current="true" class="tree" @node-click="nodeClickHandle">
  6. </el-tree>
  7. </el-scrollbar>
  8. </div>
  9. <div class="page-split"></div>
  10. <div class="page-main">
  11. <el-form :model="formModel" ref="formcomp" label-position="right" label-width="auto" :inline="false" :rules="rules" :inline-message="true">
  12. <el-form-item label="上级菜单">
  13. <el-tree-select v-model="formModel.fatherMenuId" :data="menus" :props="defaultProps" :render-after-expand="false" check-strictly class="edit-form-item"/>
  14. <!-- <el-input v-model="formModel.fatherMenuName" autocomplete="off" class="edit-form-item" :readonly="true"/> -->
  15. <el-button type="primary" plain size="default" @click="clearSuperHandle">清除</el-button>
  16. <span class="footnote">(为0或空表示顶级)</span>
  17. </el-form-item>
  18. <el-form-item label="菜单名" prop="menuName">
  19. <el-input v-model="formModel.menuName" autocomplete="off" placeholder="请输入菜单名" class="edit-form-item" clearable/>
  20. </el-form-item>
  21. <el-form-item label="链接地址">
  22. <el-input v-model="formModel.menuLink" autocomplete="off" placeholder="请输入链接地址" class="edit-form-item" clearable/>
  23. </el-form-item>
  24. <el-form-item label="图标">
  25. <el-input v-model="formModel.menuIcon" autocomplete="off" placeholder="请输入图标名" class="edit-form-item" clearable/>
  26. </el-form-item>
  27. <el-form-item label="显示序号">
  28. <el-input-number v-model="formModel.displayNum" :min="1" :max="10000"/>
  29. </el-form-item>
  30. <el-form-item label=" ">
  31. <el-button type="primary" @click="saveSubmit">保存</el-button>
  32. <el-button type="success" @click="addSubmit">新增</el-button>
  33. <el-button @click="delSubmit">删除</el-button>
  34. </el-form-item>
  35. </el-form>
  36. </div>
  37. </div>
  38. </template>
  39. <script setup>
  40. import {ref,reactive,toRefs,toRaw } from 'vue'
  41. import headerAPI from "../../api/header.js"
  42. import navmenuItem from "../../components/NavmenuItem.vue"
  43. import {ElMessageBox,ElMessage} from 'element-plus'
  44. import menuAPI from "../../api/menu.js"
  45. const formModel = reactive({
  46. fatherMenuName:null,
  47. fatherMenuId:'',
  48. menuId: '',
  49. menuName:'',
  50. menuLink:'',
  51. menuIcon:null,
  52. displayNum:1
  53. })
  54. const formcomp = ref(null);
  55. const rules =reactive({
  56. menuName:[
  57. {required:true,message:'菜单名还未填写',trigger:'blur'},
  58. { min: 2, max: 20, message: '菜单名长度应该为3-20', trigger: 'blur' }
  59. ]
  60. })
  61. const defaultProps = {
  62. children: 'subMenus',
  63. label: 'menuName',
  64. value:'menuId' //兼容treeSelect
  65. }
  66. const menus = ref([])
  67. const getData = () => {
  68. headerAPI.fetchData().then( resp => {
  69. //console.log(resp)
  70. if(resp.code===0){
  71. menus.value=headerAPI.processMenus(resp.data||[])
  72. }
  73. else{
  74. console.log(resp.msg)
  75. }
  76. });
  77. };
  78. getData();
  79. const nodeClickHandle = (item) =>{
  80. console.log(item)
  81. let {fatherMenuName,fatherMenuId,menuId,menuName,menuLink,menuIcon,displayNum}=item
  82. fatherMenuId=fatherMenuId=='0'?null:fatherMenuId
  83. Object.assign(formModel,{fatherMenuName,fatherMenuId,menuId,menuName,menuLink,menuIcon,displayNum})
  84. }
  85. const clearForm=()=>{
  86. let [fatherMenuName,fatherMenuId,menuId,menuName,menuLink,menuIcon,displayNum]=[null,null,null,null,null,null,1]
  87. Object.assign(formModel,{fatherMenuName,fatherMenuId,menuId,menuName,menuLink,menuIcon,displayNum})
  88. }
  89. const clearSuperHandle=()=>{
  90. formModel.fatherMenuName=''
  91. formModel.fatherMenuId=''
  92. }
  93. const saveSubmit=()=>{
  94. formcomp.value.validate((valid) => {
  95. if(!valid){
  96. ElMessage.error("请按要求填写数据");
  97. return
  98. }
  99. menuAPI.saveMenu(toRaw(formModel)).then(resp=>{
  100. if(resp.code!=0){
  101. ElMessage.error(resp.msg)
  102. return
  103. }
  104. ElMessage.success('操作成功')
  105. getData();
  106. }).catch(err=>{
  107. ElMessage.error(err||'操作失败')
  108. })
  109. })
  110. }
  111. const addSubmit=()=>{
  112. formcomp.value.validate((valid) => {
  113. if(!valid){
  114. ElMessage.error("请按要求填写数据");
  115. return
  116. }
  117. menuAPI.addMenu(toRaw(formModel)).then(resp=>{
  118. if(resp.code!=0){
  119. ElMessage.error(resp.msg)
  120. return
  121. }
  122. ElMessage.success('操作成功')
  123. clearForm()
  124. getData();
  125. }).catch(err=>{
  126. ElMessage.error(err||'操作失败')
  127. })
  128. })
  129. }
  130. const delSubmit=()=>{
  131. if(!formModel.menuId){
  132. ElMessage.error("请先选择一个菜单,再继续");
  133. return;
  134. }
  135. ElMessageBox.confirm(
  136. '确定要删除吗?',
  137. '操作确认',
  138. {
  139. confirmButtonText:'确定',
  140. cancelButtonText:'取消',
  141. type: 'warning'
  142. }
  143. ).then(()=>{
  144. menuAPI.delMenu({menuId:formModel.menuId}).then(resp=>{
  145. if(resp.code!=0){
  146. ElMessage.error(resp.msg)
  147. return
  148. }
  149. ElMessage.success('操作成功')
  150. clearForm()
  151. getData();
  152. }).catch(err=>{
  153. ElMessage.error(err||'操作失败')
  154. })
  155. }).catch(()=>{
  156. console.log('cancel del')
  157. })
  158. }
  159. </script>
  160. <style scoped>
  161. .page-container{
  162. padding: 5px 10px;
  163. box-sizing: border-box;
  164. height: 100%;
  165. display: flex;
  166. flex-flow: row nowrap;
  167. }
  168. .page-side{
  169. width:240px;
  170. height: 100%;
  171. }
  172. .page-split{
  173. width:5px;
  174. height: 100%;
  175. background-color: #f2f2f2;
  176. }
  177. .page-main{
  178. flex:1;
  179. padding:0 50px;
  180. }
  181. .el-form--inline.el-form--label-top{
  182. justify-content: space-between;
  183. }
  184. .edit-form-item{
  185. width:350px;
  186. }
  187. .footnote{
  188. font-size:12px;
  189. color:#999;
  190. }
  191. .page-side:deep(.el-menu){
  192. border-right: none;
  193. }
  194. .tree {
  195. /* background-color: #324157;
  196. color: #c2c2d2; */
  197. }
  198. </style>