columnsAside.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <template>
  2. <div class="layout-columns-aside">
  3. <el-scrollbar>
  4. <Logo />
  5. <ul>
  6. <li
  7. v-for="(v, k) in columnsAsideList"
  8. :key="k"
  9. @click="onColumnsAsideMenuClick(v)"
  10. ref="columnsAsideOffsetTopRefs"
  11. :class="{ 'layout-columns-active': v.k === liIndex }"
  12. :title="$t(v.title)"
  13. >
  14. <div :class="setColumnsAsidelayout" v-if="!v.isLink || (v.isLink && v.isIframe)">
  15. <Icon :type="v.icon" />
  16. <div class="font12">
  17. {{
  18. $t(v.title) && $t(v.title).length >= 4
  19. ? $t(v.title).substr(0, setColumnsAsidelayout === 'columns-vertical' ? 4 : 3)
  20. : $t(v.title)
  21. }}
  22. </div>
  23. </div>
  24. <div :class="setColumnsAsidelayout" v-else>
  25. <a :href="v.isLink" target="_blank">
  26. <Icon :type="v.icon" />
  27. <div class="font12">
  28. {{
  29. $t(v.title) && $t(v.title).length >= 4
  30. ? $t(v.title).substr(0, setColumnsAsidelayout === 'columns-vertical' ? 4 : 3)
  31. : $t(v.title)
  32. }}
  33. </div>
  34. </a>
  35. </div>
  36. </li>
  37. <div ref="columnsAsideActiveRef" :class="setColumnsAsideStyle"></div>
  38. </ul>
  39. </el-scrollbar>
  40. </div>
  41. </template>
  42. <script>
  43. import { getMenuSider, getHeaderName } from '@/libs/system';
  44. import Logo from '@/layout/logo/index.vue';
  45. export default {
  46. name: 'layoutColumnsAside',
  47. components: { Logo },
  48. data() {
  49. return {
  50. columnsAsideList: [],
  51. liIndex: 0,
  52. difference: 0,
  53. routeSplit: [],
  54. activePath: '',
  55. };
  56. },
  57. computed: {
  58. // 设置分栏高亮风格
  59. setColumnsAsideStyle() {
  60. return this.$store.state.themeConfig.themeConfig.columnsAsideStyle;
  61. },
  62. // 设置分栏布局风格
  63. setColumnsAsidelayout() {
  64. console.log(this.$store.state.themeConfig.themeConfig.columnsAsideLayout, '122311');
  65. return this.$store.state.themeConfig.themeConfig.columnsAsideLayout;
  66. },
  67. Layout() {
  68. console.log(this.$store.state.themeConfig.themeConfig.Layout, '122311444');
  69. return this.$store.state.themeConfig.themeConfig.Layout;
  70. },
  71. },
  72. mounted() {
  73. this.setFilterRoutes();
  74. },
  75. methods: {
  76. // 设置菜单高亮位置移动
  77. setColumnsAsideMove(k) {
  78. console.log(k);
  79. if (k === undefined) return false;
  80. const els = this.$refs.columnsAsideOffsetTopRefs;
  81. this.liIndex = k;
  82. this.$refs.columnsAsideActiveRef.style.top = `${els[k].offsetTop + this.difference}px`;
  83. },
  84. // 菜单高亮点击事件
  85. onColumnsAsideMenuClick(v) {
  86. // console.log(v, 'vvvv');
  87. let { path, redirect } = v;
  88. if (path) this.$router.push(path);
  89. else this.$router.push(path);
  90. // 一个路由设置自动收起菜单
  91. if (!v.children || v.children.length <= 1) this.$store.state.themeConfig.themeConfig.isCollapse = true;
  92. else if (v.children.length > 1) this.$store.state.themeConfig.themeConfig.isCollapse = false;
  93. // this.bus.$emit('setSendColumnsChildren', getMenuSider(this.columnsAsideList, path));
  94. },
  95. // 设置高亮动态位置
  96. onColumnsAsideDown(k) {
  97. this.$nextTick(() => {
  98. this.setColumnsAsideMove(k);
  99. });
  100. },
  101. // 设置/过滤路由(非静态路由/是否显示在菜单中)
  102. setFilterRoutes() {
  103. if (this.$store.state.routesList.routesList.length <= 0) return false;
  104. this.columnsAsideList = this.filterRoutesFun(this.$store.state.routesList.routesList);
  105. // const resData = getHeaderName(this.$route.path, this.columnsAsideList);
  106. const resData = this.setSendChildren(getHeaderName(this.$route, this.columnsAsideList));
  107. if (!resData.children) {
  108. this.bus.$emit('setSendColumnsChildren', []);
  109. this.$store.commit('menus/childMenuList', []);
  110. this.$store.state.themeConfig.themeConfig.isCollapse = true;
  111. return false;
  112. }
  113. this.bus.$emit('oneCatName', resData.item[0].title);
  114. this.onColumnsAsideDown(resData.item[0].k);
  115. // 刷新时,初始化一个路由设置自动收起菜单
  116. resData.children.length > 0
  117. ? (this.$store.state.themeConfig.themeConfig.isCollapse = false)
  118. : (this.$store.state.themeConfig.themeConfig.isCollapse = true);
  119. this.bus.$emit('setSendColumnsChildren', resData?.children || []);
  120. this.$store.commit('menus/childMenuList', resData?.children || []);
  121. },
  122. // 传送当前子级数据到菜单中
  123. setSendChildren(path) {
  124. const currentPathSplit = path.split('/');
  125. let currentData = {};
  126. this.columnsAsideList.map((v, k) => {
  127. if (v.path === path) {
  128. v['k'] = k;
  129. currentData['item'] = [{ ...v }];
  130. // currentData['children'] = [{ ...v }];
  131. if (v.children) currentData['children'] = v.children;
  132. }
  133. });
  134. return currentData;
  135. },
  136. // 路由过滤递归函数
  137. filterRoutesFun(arr) {
  138. return arr
  139. .filter((item) => item.path)
  140. .map((item) => {
  141. item = Object.assign({}, item);
  142. if (item.children) item.children = this.filterRoutesFun(item.children);
  143. return item;
  144. });
  145. },
  146. // tagsView 点击时,根据路由查找下标 columnsAsideList,实现左侧菜单高亮
  147. setColumnsMenuHighlight(path) {
  148. // this.routeSplit = path.split('/');
  149. // this.routeSplit.shift();
  150. // const routeFirst = `/${this.routeSplit[0]}`;
  151. console.log(path, this.columnsAsideList);
  152. const currentSplitRoute = this.columnsAsideList.find((v) => v.path === path);
  153. console.log(currentSplitRoute, 'currentSplitRoute');
  154. if (!currentSplitRoute) {
  155. // this.onColumnsAsideDown(0);
  156. return false;
  157. }
  158. // 延迟拿值,防止取不到
  159. setTimeout(() => {
  160. this.onColumnsAsideDown(currentSplitRoute.k);
  161. }, 0);
  162. },
  163. },
  164. watch: {
  165. // 监听 vuex 数据变化
  166. '$store.state': {
  167. handler(val) {
  168. console.log('变了变了');
  169. val.themeConfig.themeConfig.columnsAsideStyle === 'columnsRound'
  170. ? (this.difference = 3)
  171. : (this.difference = 0);
  172. if (val.routesList.routesList.length === this.columnsAsideList.length) return false;
  173. },
  174. deep: true,
  175. },
  176. // 监听路由的变化
  177. $route: {
  178. handler(to) {
  179. this.setColumnsMenuHighlight(to.path);
  180. // this.setColumnsAsideMove();
  181. let HeadName = getHeaderName(to, this.columnsAsideList);
  182. console.log(to, '1231');
  183. let asideList = getMenuSider(this.columnsAsideList, HeadName)[0]?.children;
  184. const resData = this.setSendChildren(HeadName);
  185. if (resData.length <= 0) return false;
  186. this.onColumnsAsideDown(resData.item[0].k);
  187. this.bus.$emit('oneCatName', resData.item[0].title);
  188. this.bus.$emit('setSendColumnsChildren', asideList || []);
  189. this.$store.commit('menus/childMenuList', asideList || []);
  190. },
  191. deep: true,
  192. },
  193. },
  194. };
  195. </script>
  196. <style scoped lang="scss">
  197. .layout-columns-aside {
  198. width: 70px;
  199. height: 100%;
  200. background: var(--prev-bg-columnsMenuBar);
  201. box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  202. ul {
  203. position: relative;
  204. li {
  205. color: var(--prev-bg-columnsMenuBarColor);
  206. width: 100%;
  207. height: 50px;
  208. text-align: center;
  209. display: flex;
  210. cursor: pointer;
  211. position: relative;
  212. z-index: 1;
  213. .columns-vertical {
  214. margin: auto;
  215. .columns-vertical-title {
  216. padding-top: 1px;
  217. }
  218. }
  219. .columns-horizontal {
  220. display: flex;
  221. height: 50px;
  222. width: 100%;
  223. align-items: center;
  224. justify-content: center;
  225. padding: 0 5px;
  226. i {
  227. margin-right: 3px;
  228. }
  229. a {
  230. display: flex;
  231. .columns-horizontal-title {
  232. padding-top: 1px;
  233. }
  234. }
  235. }
  236. a {
  237. text-decoration: none;
  238. color: var(--prev-bg-columnsMenuBarColor);
  239. }
  240. }
  241. .layout-columns-active,
  242. .layout-columns-active a {
  243. color: var(--prev-bg-columnsMenuActiveColor);
  244. transition: 0.3s ease-in-out;
  245. }
  246. .columns-round {
  247. background: var(--prev-color-primary);
  248. // color: var(--prev-color-text-white);
  249. position: absolute;
  250. left: 50%;
  251. top: 2px;
  252. height: 50px;
  253. width: 65px;
  254. transform: translateX(-50%);
  255. z-index: 0;
  256. transition: 0.3s ease-in-out;
  257. border-radius: 5px;
  258. }
  259. .columns-card {
  260. @extend .columns-round;
  261. top: 0;
  262. height: 50px;
  263. width: 100%;
  264. border-radius: 0;
  265. }
  266. }
  267. }
  268. </style>