index.vue 7.4 KB

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