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" label-position="top">
  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="green">绿荫草场</el-radio-button>
  32. <el-radio-button label="glory">荣耀典藏</el-radio-button>
  33. <!-- <el-radio-button label="orean">海洋之心</el-radio-button>
  34. <el-radio-button label="red">月上重火</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 type="primary" @click="handleSaveTheme">
  57. 保存
  58. </el-button>
  59. </el-form-item>
  60. </el-form>
  61. </div>
  62. </el-scrollbar>
  63. </el-drawer>
  64. </span>
  65. </template>
  66. <script>
  67. import variables from '@/styles/variables.scss'
  68. import { mapActions, mapGetters } from 'vuex'
  69. import { layout as defaultLayout } from '@/config'
  70. export default {
  71. name: 'VabThemeBar',
  72. data() {
  73. return {
  74. drawerVisible: false,
  75. theme: {
  76. name: 'default',
  77. layout: '',
  78. header: 'fixed',
  79. tabsBar: '',
  80. },
  81. }
  82. },
  83. computed: {
  84. ...mapGetters({
  85. layout: 'settings/layout',
  86. header: 'settings/header',
  87. tabsBar: 'settings/tabsBar',
  88. themeBar: 'settings/themeBar',
  89. }),
  90. },
  91. created() {
  92. this.$baseEventBus.$on('theme', () => {
  93. this.handleOpenThemeBar()
  94. })
  95. const theme = localStorage.getItem('vue-admin-beautiful-theme')
  96. if (null !== theme) {
  97. this.theme = JSON.parse(theme)
  98. this.handleSetTheme()
  99. } else {
  100. this.theme.layout = this.layout
  101. this.theme.header = this.header
  102. this.theme.tabsBar = this.tabsBar
  103. }
  104. },
  105. methods: {
  106. ...mapActions({
  107. changeLayout: 'settings/changeLayout',
  108. changeHeader: 'settings/changeHeader',
  109. changeTabsBar: 'settings/changeTabsBar',
  110. }),
  111. handleIsMobile() {
  112. return document.body.getBoundingClientRect().width - 1 < 992
  113. },
  114. handleOpenThemeBar() {
  115. this.drawerVisible = true
  116. },
  117. handleSetTheme() {
  118. let { name, layout, header, tabsBar } = this.theme
  119. localStorage.setItem(
  120. 'vue-admin-beautiful-theme',
  121. `{
  122. "name":"${name}",
  123. "layout":"${layout}",
  124. "header":"${header}",
  125. "tabsBar":"${tabsBar}"
  126. }`
  127. )
  128. if (!this.handleIsMobile()) this.changeLayout(layout)
  129. this.changeHeader(header)
  130. this.changeTabsBar(tabsBar)
  131. document.getElementsByTagName(
  132. 'body'
  133. )[0].className = `vue-admin-beautiful-theme-${name}`
  134. this.drawerVisible = false
  135. },
  136. handleSaveTheme() {
  137. this.handleSetTheme()
  138. },
  139. handleSetDfaultTheme() {
  140. let { name } = this.theme
  141. document
  142. .getElementsByTagName('body')[0]
  143. .classList.remove(`vue-admin-beautiful-theme-${name}`)
  144. localStorage.removeItem('vue-admin-beautiful-theme')
  145. this.$refs['form'].resetFields()
  146. Object.assign(this.$data, this.$options.data())
  147. this.changeHeader(defaultLayout)
  148. this.theme.name = 'default'
  149. this.theme.layout = this.layout
  150. this.theme.header = this.header
  151. this.theme.tabsBar = this.tabsBar
  152. this.drawerVisible = false
  153. location.reload()
  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>