index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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.tagsBar">
  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 { 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. tagsBar: "",
  81. },
  82. };
  83. },
  84. computed: {
  85. ...mapGetters({
  86. layout: "settings/layout",
  87. header: "settings/header",
  88. tagsBar: "settings/tagsBar",
  89. themeBar: "settings/themeBar",
  90. }),
  91. },
  92. mounted() {},
  93. created() {
  94. this.$baseEventBus.$on("theme", () => {
  95. this.handleOpenThemeBar();
  96. });
  97. const theme = localStorage.getItem("vue-admin-beautiful-theme");
  98. if (null !== theme) {
  99. this.theme = JSON.parse(theme);
  100. this.handleSetTheme();
  101. } else {
  102. this.theme.layout = this.layout;
  103. this.theme.header = this.header;
  104. this.theme.tagsBar = this.tagsBar;
  105. }
  106. },
  107. methods: {
  108. handleIsMobile() {
  109. return document.body.getBoundingClientRect().width - 1 < 992;
  110. },
  111. handleOpenThemeBar() {
  112. this.drawerVisible = true;
  113. },
  114. handleSetTheme() {
  115. let { name, layout, header, tagsBar } = this.theme;
  116. localStorage.setItem(
  117. "vue-admin-beautiful-theme",
  118. `{
  119. "name":"${name}",
  120. "layout":"${layout}",
  121. "header":"${header}",
  122. "tagsBar":"${tagsBar}"
  123. }`
  124. );
  125. if (!this.handleIsMobile()) {
  126. this.$store.dispatch("settings/changeLayout", layout);
  127. }
  128. this.$store.dispatch("settings/changeHeader", header);
  129. this.$store.dispatch("settings/changeTagsBar", tagsBar);
  130. document.getElementsByTagName(
  131. "body"
  132. )[0].className = `vue-admin-beautiful-theme-${name}`;
  133. this.drawerVisible = false;
  134. },
  135. handleSaveTheme() {
  136. this.handleSetTheme();
  137. },
  138. handleSetDfaultTheme() {
  139. let { name } = this.theme;
  140. document
  141. .getElementsByTagName("body")[0]
  142. .classList.remove(`vue-admin-beautiful-theme-${name}`);
  143. localStorage.removeItem("vue-admin-beautiful-theme");
  144. this.$refs["form"].resetFields();
  145. Object.assign(this.$data, this.$options.data());
  146. this.$store.dispatch("settings/changeLayout", defaultLayout);
  147. this.theme.name = "default";
  148. this.theme.layout = this.layout;
  149. this.theme.header = this.header;
  150. this.theme.tagsBar = this.tagsBar;
  151. this.drawerVisible = false;
  152. },
  153. handleGetCode() {
  154. const url =
  155. "https://github.com/chuzhixin/vue-admin-beautiful/tree/master/src/views";
  156. let path = this.$route.path + "/index.vue";
  157. if (path === "/vab/menu1/menu1-1/menu1-1-1/index.vue") {
  158. path = "/vab/nested/menu1/menu1-1/menu1-1-1/index.vue";
  159. }
  160. if (path === "/vab/icon/awesomeIcon/index.vue") {
  161. path = "/vab/icon/index.vue";
  162. }
  163. if (path === "/vab/icon/remixIcon/index.vue") {
  164. path = "/vab/icon/remixIcon.vue";
  165. }
  166. if (path === "/vab/icon/colorfulIcon/index.vue") {
  167. path = "/vab/icon/colorfulIcon.vue";
  168. }
  169. if (path === "/vab/table/comprehensiveTable/index.vue") {
  170. path = "/vab/table/index.vue";
  171. }
  172. if (path === "/vab/table/inlineEditTable/index.vue") {
  173. path = "/vab/table/inlineEditTable.vue";
  174. }
  175. window.open(url + path);
  176. },
  177. },
  178. };
  179. </script>
  180. <style lang="scss" scoped>
  181. @mixin right-bar {
  182. position: fixed;
  183. right: 0;
  184. z-index: $base-z-index;
  185. width: 60px;
  186. min-height: 60px;
  187. text-align: center;
  188. cursor: pointer;
  189. background: $base-color-blue;
  190. border-radius: $base-border-radius;
  191. > div {
  192. padding-top: 10px;
  193. border-bottom: 0 !important;
  194. &:hover {
  195. opacity: 0.9;
  196. }
  197. & + div {
  198. border-top: 1px solid $base-color-white;
  199. }
  200. p {
  201. padding: 0;
  202. margin: 0;
  203. font-size: $base-font-size-small;
  204. line-height: 30px;
  205. color: $base-color-white;
  206. }
  207. }
  208. }
  209. .theme-bar-setting {
  210. @include right-bar;
  211. top: calc((100vh - 110px) / 2);
  212. ::v-deep {
  213. svg:not(:root).svg-inline--fa {
  214. display: block;
  215. margin-right: auto;
  216. margin-left: auto;
  217. color: $base-color-white;
  218. }
  219. .svg-icon {
  220. display: block;
  221. margin-right: auto;
  222. margin-left: auto;
  223. font-size: 20px;
  224. color: $base-color-white;
  225. fill: $base-color-white;
  226. }
  227. }
  228. }
  229. .el-drawer__body {
  230. padding: 20px;
  231. }
  232. </style>
  233. <style lang="scss">
  234. .el-drawer__wrapper {
  235. outline: none !important;
  236. * {
  237. outline: none !important;
  238. }
  239. }
  240. .vab-color-picker {
  241. .el-color-dropdown__link-btn {
  242. display: none;
  243. }
  244. }
  245. </style>