SettingDrawer.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <div class="setting-drawer" ref="settingDrawer">
  3. <a-drawer
  4. width="300"
  5. placement="right"
  6. @close="onClose"
  7. :closable="false"
  8. :visible="visible"
  9. :handle="handle"
  10. wrapClassName="setting-drawer-content"
  11. >
  12. <div class="setting-drawer-index-content">
  13. <div :style="{ marginBottom: '24px' }">
  14. <h3 class="setting-drawer-index-title">整体风格设置</h3>
  15. <div class="setting-drawer-index-blockChecbox">
  16. <a-tooltip>
  17. <template slot="title">
  18. 暗色菜单风格
  19. </template>
  20. <div class="setting-drawer-index-item" @click="handleMenuTheme('dark')">
  21. <img src="https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg" alt="dark">
  22. <div class="setting-drawer-index-selectIcon" v-if="navTheme === 'dark'">
  23. <a-icon type="check"/>
  24. </div>
  25. </div>
  26. </a-tooltip>
  27. <a-tooltip>
  28. <template slot="title">
  29. 亮色菜单风格
  30. </template>
  31. <div class="setting-drawer-index-item" @click="handleMenuTheme('light')">
  32. <img src="https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg" alt="light">
  33. <div class="setting-drawer-index-selectIcon" v-if="navTheme !== 'dark'">
  34. <a-icon type="check"/>
  35. </div>
  36. </div>
  37. </a-tooltip>
  38. </div>
  39. </div>
  40. <div :style="{ marginBottom: '24px' }">
  41. <h3 class="setting-drawer-index-title">主题色</h3>
  42. <div style="height: 20px">
  43. <a-tooltip class="setting-drawer-theme-color-colorBlock" v-for="(item, index) in colorList" :key="index">
  44. <template slot="title">
  45. {{ item.key }}
  46. </template>
  47. <a-tag :color="item.color" @click="changeColor(item.color)">
  48. <a-icon type="check" v-if="item.color === primaryColor"></a-icon>
  49. </a-tag>
  50. </a-tooltip>
  51. </div>
  52. </div>
  53. <a-divider />
  54. <div :style="{ marginBottom: '24px' }">
  55. <h3 class="setting-drawer-index-title">导航模式</h3>
  56. <div class="setting-drawer-index-blockChecbox">
  57. <a-tooltip>
  58. <template slot="title">
  59. 侧边栏导航
  60. </template>
  61. <div class="setting-drawer-index-item" @click="handleLayout('sidemenu')">
  62. <img src="https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg" alt="sidemenu">
  63. <div class="setting-drawer-index-selectIcon" v-if="layoutMode === 'sidemenu'">
  64. <a-icon type="check"/>
  65. </div>
  66. </div>
  67. </a-tooltip>
  68. <a-tooltip>
  69. <template slot="title">
  70. 顶部栏导航
  71. </template>
  72. <div class="setting-drawer-index-item" @click="handleLayout('topmenu')">
  73. <img src="https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg" alt="topmenu">
  74. <div class="setting-drawer-index-selectIcon" v-if="layoutMode !== 'sidemenu'">
  75. <a-icon type="check"/>
  76. </div>
  77. </div>
  78. </a-tooltip>
  79. </div>
  80. <div :style="{ marginTop: '24px' }">
  81. <a-list :split="false">
  82. <a-list-item>
  83. <a-tooltip slot="actions">
  84. <template slot="title">
  85. 该设定仅 [顶部栏导航] 时有效
  86. </template>
  87. <a-select size="small" style="width: 80px;" :defaultValue="contentWidth" @change="handleContentWidthChange">
  88. <a-select-option value="Fixed">固定</a-select-option>
  89. <a-select-option value="Fluid" v-if="layoutMode !== 'sidemenu'">流式</a-select-option>
  90. </a-select>
  91. </a-tooltip>
  92. <a-list-item-meta>
  93. <div slot="title">内容区域宽度</div>
  94. </a-list-item-meta>
  95. </a-list-item>
  96. <a-list-item>
  97. <a-switch slot="actions" size="small" :defaultChecked="fixedHeader" @change="handleFixedHeader" />
  98. <a-list-item-meta>
  99. <div slot="title">固定 Header</div>
  100. </a-list-item-meta>
  101. </a-list-item>
  102. <a-list-item>
  103. <a-switch slot="actions" size="small" :disabled="!fixedHeader" :defaultChecked="autoHideHeader" @change="handleFixedHeaderHidden" />
  104. <a-list-item-meta>
  105. <a-tooltip slot="title" placement="left">
  106. <template slot="title">固定 Header 时可配置</template>
  107. <div :style="{ opacity: !fixedHeader ? '0.5' : '1' }">下滑时隐藏 Header</div>
  108. </a-tooltip>
  109. </a-list-item-meta>
  110. </a-list-item>
  111. <a-list-item >
  112. <a-switch slot="actions" size="small" :disabled="(layoutMode === 'topmenu')" :defaultChecked="fixSiderbar" @change="handleFixSiderbar" />
  113. <a-list-item-meta>
  114. <div slot="title" :style="{ textDecoration: layoutMode === 'topmenu' ? 'line-through' : 'unset' }">固定侧边菜单</div>
  115. </a-list-item-meta>
  116. </a-list-item>
  117. </a-list>
  118. </div>
  119. </div>
  120. <a-divider />
  121. <div :style="{ marginBottom: '24px' }">
  122. <h3 class="setting-drawer-index-title">其他设置</h3>
  123. <div>
  124. <a-list :split="false">
  125. <a-list-item>
  126. <a-switch slot="actions" size="small" :defaultChecked="colorWeak" @change="onColorWeak" />
  127. <a-list-item-meta>
  128. <div slot="title">色弱模式</div>
  129. </a-list-item-meta>
  130. </a-list-item>
  131. <a-list-item>
  132. <a-switch slot="actions" size="small" :defaultChecked="multiTab" @change="onMultiTab" />
  133. <a-list-item-meta>
  134. <div slot="title">多页签模式</div>
  135. </a-list-item-meta>
  136. </a-list-item>
  137. </a-list>
  138. </div>
  139. </div>
  140. <a-divider />
  141. <div :style="{ marginBottom: '24px' }">
  142. <a-button
  143. @click="doCopy"
  144. icon="copy"
  145. block
  146. >拷贝设置</a-button>
  147. <a-alert type="warning" :style="{ marginTop: '24px' }">
  148. <span slot="message">
  149. 配置栏只在开发环境用于预览,生产环境不会展现,请手动修改配置文件
  150. <a href="https://github.com/sendya/ant-design-pro-vue/blob/master/src/config/defaultSettings.js" target="_blank">src/config/defaultSettings.js</a>
  151. </span>
  152. </a-alert>
  153. </div>
  154. </div>
  155. <div class="setting-drawer-index-handle" @click="toggle">
  156. <a-icon type="setting" v-if="!visible"/>
  157. <a-icon type="close" v-else/>
  158. </div>
  159. </a-drawer>
  160. </div>
  161. </template>
  162. <script>
  163. import { DetailList } from '@/components'
  164. import SettingItem from './SettingItem'
  165. import config from '@/config/defaultSettings'
  166. import { updateTheme, updateColorWeak, colorList } from './settingConfig'
  167. import { mixin, mixinDevice } from '@/utils/mixin'
  168. export default {
  169. components: {
  170. DetailList,
  171. SettingItem
  172. },
  173. mixins: [mixin, mixinDevice],
  174. data () {
  175. return {
  176. visible: false,
  177. colorList,
  178. handle: <div/>
  179. }
  180. },
  181. watch: {
  182. },
  183. mounted () {
  184. updateTheme(this.primaryColor)
  185. if (this.colorWeak !== config.colorWeak) {
  186. updateColorWeak(this.colorWeak)
  187. }
  188. },
  189. methods: {
  190. showDrawer () {
  191. this.visible = true
  192. },
  193. onClose () {
  194. this.visible = false
  195. },
  196. toggle () {
  197. this.visible = !this.visible
  198. },
  199. onColorWeak (checked) {
  200. this.$store.dispatch('ToggleWeak', checked)
  201. updateColorWeak(checked)
  202. },
  203. onMultiTab (checked) {
  204. this.$store.dispatch('ToggleMultiTab', checked)
  205. },
  206. handleMenuTheme (theme) {
  207. this.$store.dispatch('ToggleTheme', theme)
  208. },
  209. doCopy () {
  210. // get current settings from mixin or this.$store.state.app, pay attention to the property name
  211. const text = `export default {
  212. primaryColor: '${this.primaryColor}', // primary color of ant design
  213. navTheme: '${this.navTheme}', // theme for nav menu
  214. layout: '${this.layoutMode}', // nav menu position: sidemenu or topmenu
  215. contentWidth: '${this.contentWidth}', // layout of content: Fluid or Fixed, only works when layout is topmenu
  216. fixedHeader: ${this.fixedHeader}, // sticky header
  217. fixSiderbar: ${this.fixSiderbar}, // sticky siderbar
  218. autoHideHeader: ${this.autoHideHeader}, // auto hide header
  219. colorWeak: ${this.colorWeak},
  220. multiTab: ${this.multiTab},
  221. production: process.env.NODE_ENV === 'production' && process.env.VUE_APP_PREVIEW !== 'true',
  222. // vue-ls options
  223. storageOptions: {
  224. namespace: 'pro__',
  225. name: 'ls',
  226. storage: 'local',
  227. }
  228. }`
  229. this.$copyText(text).then(message => {
  230. console.log('copy', message)
  231. this.$message.success('复制完毕')
  232. }).catch(err => {
  233. console.log('copy.err', err)
  234. this.$message.error('复制失败')
  235. })
  236. },
  237. handleLayout (mode) {
  238. this.$store.dispatch('ToggleLayoutMode', mode)
  239. // 因为顶部菜单不能固定左侧菜单栏,所以强制关闭
  240. this.handleFixSiderbar(false)
  241. },
  242. handleContentWidthChange (type) {
  243. this.$store.dispatch('ToggleContentWidth', type)
  244. },
  245. changeColor (color) {
  246. if (this.primaryColor !== color) {
  247. this.$store.dispatch('ToggleColor', color)
  248. updateTheme(color)
  249. }
  250. },
  251. handleFixedHeader (fixed) {
  252. this.$store.dispatch('ToggleFixedHeader', fixed)
  253. },
  254. handleFixedHeaderHidden (autoHidden) {
  255. this.$store.dispatch('ToggleFixedHeaderHidden', autoHidden)
  256. },
  257. handleFixSiderbar (fixed) {
  258. if (this.layoutMode === 'topmenu') {
  259. this.$store.dispatch('ToggleFixSiderbar', false)
  260. return
  261. }
  262. this.$store.dispatch('ToggleFixSiderbar', fixed)
  263. }
  264. }
  265. }
  266. </script>
  267. <style lang="less" scoped>
  268. .setting-drawer-index-content {
  269. .setting-drawer-index-blockChecbox {
  270. display: flex;
  271. .setting-drawer-index-item {
  272. margin-right: 16px;
  273. position: relative;
  274. border-radius: 4px;
  275. cursor: pointer;
  276. img {
  277. width: 48px;
  278. }
  279. .setting-drawer-index-selectIcon {
  280. position: absolute;
  281. top: 0;
  282. right: 0;
  283. width: 100%;
  284. padding-top: 15px;
  285. padding-left: 24px;
  286. height: 100%;
  287. color: #1890ff;
  288. font-size: 14px;
  289. font-weight: 700;
  290. }
  291. }
  292. }
  293. .setting-drawer-theme-color-colorBlock {
  294. width: 20px;
  295. height: 20px;
  296. border-radius: 2px;
  297. float: left;
  298. cursor: pointer;
  299. margin-right: 8px;
  300. padding-left: 0px;
  301. padding-right: 0px;
  302. text-align: center;
  303. color: #fff;
  304. font-weight: 700;
  305. i {
  306. font-size: 14px;
  307. }
  308. }
  309. }
  310. .setting-drawer-index-handle {
  311. position: absolute;
  312. top: 240px;
  313. background: #1890ff;
  314. width: 48px;
  315. height: 48px;
  316. right: 300px;
  317. display: flex;
  318. justify-content: center;
  319. align-items: center;
  320. cursor: pointer;
  321. pointer-events: auto;
  322. z-index: 1001;
  323. text-align: center;
  324. font-size: 16px;
  325. border-radius: 4px 0 0 4px;
  326. i {
  327. color: rgb(255, 255, 255);
  328. font-size: 20px;
  329. }
  330. }
  331. </style>