index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <template>
  2. <span v-if="themeBar">
  3. <vab-icon
  4. title="主题配置"
  5. :icon="['fas', 'palette']"
  6. @click="handleOpenThemeBar"
  7. />
  8. <div class="theme-bar-setting">
  9. <div @click="handleOpenThemeBar">
  10. <vab-icon :icon="['fas', 'palette']" />
  11. <p>主题配置</p>
  12. </div>
  13. <div @click="handleGetCode">
  14. <vab-icon :icon="['fas', 'laptop-code']"></vab-icon>
  15. <p>拷贝源码</p>
  16. </div>
  17. </div>
  18. <el-drawer
  19. title="主题配置"
  20. :visible.sync="drawerVisible"
  21. direction="rtl"
  22. append-to-body
  23. size="470px"
  24. >
  25. <el-scrollbar style="height: 94vh; overflow: hidden">
  26. <div class="el-drawer__body">
  27. <el-form ref="form" :model="theme">
  28. <el-form-item label="主题">
  29. <el-radio-group v-model="theme.name">
  30. <el-radio-button label="default">默认</el-radio-button>
  31. <el-radio-button label="ocean">海洋之心</el-radio-button>
  32. <el-radio-button label="green">绿荫草场</el-radio-button>
  33. <el-radio-button label="glory">荣耀典藏</el-radio-button>
  34. <el-radio-button label="dark">暗黑之子</el-radio-button>
  35. </el-radio-group>
  36. </el-form-item>
  37. <el-form-item label="布局">
  38. <el-radio-group v-model="theme.layout">
  39. <el-radio-button label="vertical">纵向布局</el-radio-button>
  40. <el-radio-button label="horizontal">横向布局</el-radio-button>
  41. </el-radio-group>
  42. </el-form-item>
  43. <el-form-item label="头部">
  44. <el-radio-group v-model="theme.header">
  45. <el-radio-button label="fixed">固定头部</el-radio-button>
  46. <el-radio-button label="noFixed">不固定头部</el-radio-button>
  47. </el-radio-group>
  48. </el-form-item>
  49. <el-form-item label="多标签">
  50. <el-radio-group v-model="theme.tabsBar">
  51. <el-radio-button label="true">开启</el-radio-button>
  52. <el-radio-button label="false">不开启</el-radio-button>
  53. </el-radio-group>
  54. </el-form-item>
  55. <el-form-item>
  56. <el-button @click="handleSetDfaultTheme">恢复默认</el-button>
  57. <el-button type="primary" @click="handleSaveTheme">
  58. 保存
  59. </el-button>
  60. </el-form-item>
  61. </el-form>
  62. </div>
  63. </el-scrollbar>
  64. </el-drawer>
  65. </span>
  66. </template>
  67. <script>
  68. import variables from "@/styles/variables.scss";
  69. import { mapActions, mapGetters } from "vuex";
  70. import { layout as defaultLayout } from "@/config/settings";
  71. export default {
  72. name: "ThemeBar",
  73. data() {
  74. return {
  75. drawerVisible: false,
  76. theme: {
  77. name: "default",
  78. layout: "",
  79. header: "",
  80. tabsBar: "",
  81. },
  82. };
  83. },
  84. computed: {
  85. ...mapGetters({
  86. layout: "settings/layout",
  87. header: "settings/header",
  88. tabsBar: "settings/tabsBar",
  89. themeBar: "settings/themeBar",
  90. }),
  91. },
  92. created() {
  93. this.$baseEventBus.$on("theme", () => {
  94. this.handleOpenThemeBar();
  95. });
  96. const theme = localStorage.getItem("vue-admin-beautiful-theme");
  97. if (null !== theme) {
  98. this.theme = JSON.parse(theme);
  99. this.handleSetTheme();
  100. } else {
  101. this.theme.layout = this.layout;
  102. this.theme.header = this.header;
  103. this.theme.tabsBar = this.tabsBar;
  104. }
  105. },
  106. methods: {
  107. ...mapActions({
  108. changeLayout: "settings/changeLayout",
  109. changeHeader: "settings/changeHeader",
  110. changeTabsBar: "settings/changeTabsBar",
  111. }),
  112. handleIsMobile() {
  113. return document.body.getBoundingClientRect().width - 1 < 992;
  114. },
  115. handleOpenThemeBar() {
  116. this.drawerVisible = true;
  117. },
  118. handleSetTheme() {
  119. let { name, layout, header, tabsBar } = this.theme;
  120. localStorage.setItem(
  121. "vue-admin-beautiful-theme",
  122. `{
  123. "name":"${name}",
  124. "layout":"${layout}",
  125. "header":"${header}",
  126. "tabsBar":"${tabsBar}"
  127. }`
  128. );
  129. if (!this.handleIsMobile()) this.changeLayout(layout);
  130. this.changeHeader(header);
  131. this.changeTabsBar(tabsBar);
  132. document.getElementsByTagName(
  133. "body"
  134. )[0].className = `vue-admin-beautiful-theme-${name}`;
  135. this.drawerVisible = false;
  136. },
  137. handleSaveTheme() {
  138. this.handleSetTheme();
  139. },
  140. handleSetDfaultTheme() {
  141. let { name } = this.theme;
  142. document
  143. .getElementsByTagName("body")[0]
  144. .classList.remove(`vue-admin-beautiful-theme-${name}`);
  145. localStorage.removeItem("vue-admin-beautiful-theme");
  146. this.$refs["form"].resetFields();
  147. Object.assign(this.$data, this.$options.data());
  148. this.changeHeader(defaultLayout);
  149. this.theme.name = "default";
  150. this.theme.layout = this.layout;
  151. this.theme.header = this.header;
  152. this.theme.tabsBar = this.tabsBar;
  153. this.drawerVisible = false;
  154. },
  155. handleGetCode() {
  156. const url =
  157. "https://github.com/chuzhixin/vue-admin-beautiful/tree/master/src/views";
  158. let path = this.$route.path + "/index.vue";
  159. if (path === "/vab/menu1/menu1-1/menu1-1-1/index.vue") {
  160. path = "/vab/nested/menu1/menu1-1/menu1-1-1/index.vue";
  161. }
  162. if (path === "/vab/icon/awesomeIcon/index.vue") {
  163. path = "/vab/icon/index.vue";
  164. }
  165. if (path === "/vab/icon/remixIcon/index.vue") {
  166. path = "/vab/icon/remixIcon.vue";
  167. }
  168. if (path === "/vab/icon/colorfulIcon/index.vue") {
  169. path = "/vab/icon/colorfulIcon.vue";
  170. }
  171. if (path === "/vab/table/comprehensiveTable/index.vue") {
  172. path = "/vab/table/index.vue";
  173. }
  174. if (path === "/vab/table/inlineEditTable/index.vue") {
  175. path = "/vab/table/inlineEditTable.vue";
  176. }
  177. window.open(url + path);
  178. },
  179. },
  180. };
  181. </script>
  182. <style lang="scss" scoped>
  183. @mixin right-bar {
  184. position: fixed;
  185. right: 0;
  186. z-index: $base-z-index;
  187. width: 60px;
  188. min-height: 60px;
  189. text-align: center;
  190. cursor: pointer;
  191. background: $base-color-blue;
  192. border-radius: $base-border-radius;
  193. > div {
  194. padding-top: 10px;
  195. border-bottom: 0 !important;
  196. &:hover {
  197. opacity: 0.9;
  198. }
  199. & + div {
  200. border-top: 1px solid $base-color-white;
  201. }
  202. p {
  203. padding: 0;
  204. margin: 0;
  205. font-size: $base-font-size-small;
  206. line-height: 30px;
  207. color: $base-color-white;
  208. }
  209. }
  210. }
  211. .theme-bar-setting {
  212. @include right-bar;
  213. top: calc((100vh - 110px) / 2);
  214. ::v-deep {
  215. svg:not(:root).svg-inline--fa {
  216. display: block;
  217. margin-right: auto;
  218. margin-left: auto;
  219. color: $base-color-white;
  220. }
  221. .svg-icon {
  222. display: block;
  223. margin-right: auto;
  224. margin-left: auto;
  225. font-size: 20px;
  226. color: $base-color-white;
  227. fill: $base-color-white;
  228. }
  229. }
  230. }
  231. .el-drawer__body {
  232. padding: 20px;
  233. }
  234. </style>
  235. <style lang="scss">
  236. .el-drawer__wrapper {
  237. outline: none !important;
  238. * {
  239. outline: none !important;
  240. }
  241. }
  242. .vab-color-picker {
  243. .el-color-dropdown__link-btn {
  244. display: none;
  245. }
  246. }
  247. </style>