mirror of https://github.com/ElemeFE/element
				
				
				
			
		
			
				
	
	
		
			196 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Smarty
		
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Smarty
		
	
	
| <style lang="scss">
 | |
| .page-container.page-theme-preview {
 | |
|   padding-top: 30px;
 | |
|   .display {
 | |
|     width: 75%;
 | |
|     display: inline-block;
 | |
|     vertical-align: top;
 | |
|     h3 {
 | |
|       font-size: 28px;
 | |
|       margin: 30px 0 0 0;
 | |
|     }
 | |
|   }
 | |
|   .side {
 | |
|     display: inline-block;
 | |
|     width: 25%;
 | |
|     .editor {
 | |
|       overflow: hidden;
 | |
|       background: #f5f7fa;
 | |
|       border: 1px solid #ebeef5;
 | |
|       border-radius: 5px;
 | |
|       margin-bottom: 20px;
 | |
|       &.fixed {
 | |
|         position: fixed;
 | |
|         width: 285px;
 | |
|         box-sizing: border-box;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </style>
 | |
| <template>
 | |
|   <div class="page-container page-theme-preview" ref="themePreview">
 | |
|     <section class="display">
 | |
|       <el-button type="text" icon="el-icon-back" @click="navBack">
 | |
|         <%= 1 >
 | |
|       </el-button>
 | |
|       <h3>{{previewConfig.name}}</h3>
 | |
|       <basic-tokens-preview>
 | |
|       </basic-tokens-preview>
 | |
|       <components-preview>
 | |
|       </components-preview>
 | |
|     </section>
 | |
|     <aside class="side">
 | |
|       <section class="editor" :style="{top: `${editorTop}px`, height: `${editorHeight}px`}" :class="{'fixed': isFixed}">
 | |
|         <theme-configurator
 | |
|           :isOfficial="isOfficial"
 | |
|           :themeConfig="themeConfig"
 | |
|           :onUserConfigUpdate="onUserConfigUpdate"
 | |
|         >
 | |
|         </theme-configurator>
 | |
|       </section>
 | |
|     </aside>
 | |
|   </div>
 | |
| </template>
 | |
| <script>
 | |
| import bus from '../../bus.js';
 | |
| import ThemeConfigurator from '../../components/theme-configurator';
 | |
| import ComponentsPreview from '../../components/theme/components-preview';
 | |
| import BasicTokensPreview from '../../components/theme/basic-tokens-preview';
 | |
| import {
 | |
|   loadPreviewFromLocal,
 | |
|   loadUserThemeFromLocal,
 | |
|   saveUserThemeToLocal
 | |
| } from '../../components/theme/localstorage';
 | |
| import {
 | |
|   getThemeConfigObject
 | |
| } from '../../components/theme/utils';
 | |
| import {
 | |
|   ACTION_APPLY_THEME
 | |
| } from '../../components/theme/constant.js';
 | |
| import throttle from 'throttle-debounce/throttle';
 | |
| import { getActionDisplayName } from '../../components/theme-configurator/utils/utils';
 | |
| 
 | |
| const maxUserTheme = 8;
 | |
| 
 | |
| export default {
 | |
|   components: {
 | |
|     ThemeConfigurator,
 | |
|     BasicTokensPreview,
 | |
|     ComponentsPreview
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       previewConfig: {},
 | |
|       themeConfig: {},
 | |
|       userTheme: [],
 | |
|       editorTop: 0,
 | |
|       editorHeight: 1000,
 | |
|       isFixed: false
 | |
|     };
 | |
|   },
 | |
|   computed: {
 | |
|     isOfficial() {
 | |
|       return this.previewConfig.type === 'official';
 | |
|     }
 | |
|   },
 | |
|   created() {
 | |
|     this.throttledHandleScroll = throttle(10, true, index => {
 | |
|       this.handleScroll(index);
 | |
|     });
 | |
|   },
 | |
|   methods: {
 | |
|     navBack() {
 | |
|       this.$router.go(-1);
 | |
|       this.$nextTick(() => {
 | |
|         window.scrollTo(0, 0);
 | |
|       });
 | |
|     },
 | |
|     getNewUserThemeName(originName) {
 | |
|       let n = 1;
 | |
|       let name;
 | |
|       while (true) {
 | |
|         name = `${originName}-${n}`;
 | |
|         if (this.userTheme.filter(theme => (theme.name === name)).length === 0) {
 | |
|           break;
 | |
|         }
 | |
|         n += 1;
 | |
|       }
 | |
|       return name;
 | |
|     },
 | |
|     onUserConfigUpdate(userConfig) {
 | |
|       const themeConfig = JSON.stringify(userConfig);
 | |
|       const { type, name } = this.previewConfig;
 | |
|       if (this.isOfficial) {
 | |
|         if (this.userTheme.length >= maxUserTheme) {
 | |
|           this.$message.error(getActionDisplayName('max-user-theme'));
 | |
|           return;
 | |
|         }
 | |
|         const autoUserName = this.getNewUserThemeName(name);
 | |
|         this.previewConfig.name = autoUserName;
 | |
|         this.previewConfig.type = 'user';
 | |
|         this.userTheme.push({
 | |
|           update: Date.now(),
 | |
|           name: autoUserName,
 | |
|           theme: themeConfig
 | |
|         });
 | |
|         saveUserThemeToLocal(this.userTheme);
 | |
|         return;
 | |
|       }
 | |
|       if (type === 'user') {
 | |
|         this.userTheme.forEach((config) => {
 | |
|           if (config.name === name) {
 | |
|             config.update = Date.now();
 | |
|             config.theme = themeConfig;
 | |
|           }
 | |
|         });
 | |
|         saveUserThemeToLocal(this.userTheme);
 | |
|       }
 | |
|     },
 | |
|     handleScroll() {
 | |
|       const rect = this.$refs.themePreview.getBoundingClientRect();
 | |
|       let offsetTop = rect.top;
 | |
|       let offsetBottom = rect.bottom;
 | |
|       const calHeight = this.editorHeight + 30 + 20;
 | |
|       if (offsetTop < 0) {
 | |
|         this.isFixed = true;
 | |
|         if (offsetBottom < calHeight) {
 | |
|           this.editorTop = 30 - calHeight + offsetBottom;
 | |
|         } else {
 | |
|           this.editorTop = 30;
 | |
|         }
 | |
|       } else {
 | |
|         this.isFixed = false;
 | |
|         this.editorTop = 0;
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   beforeDestroy() {
 | |
|     window.removeEventListener('scroll', this.throttledHandleScroll);
 | |
|   },
 | |
|   mounted() {
 | |
|     this.editorHeight = window.innerHeight - 40 - 5;
 | |
|     window.addEventListener('scroll', this.throttledHandleScroll);
 | |
|     this.userTheme = loadUserThemeFromLocal();
 | |
|     const previewConfig = loadPreviewFromLocal();
 | |
|     const pageRefer = this.$route.params.refer;
 | |
|     if (!previewConfig || !pageRefer) {
 | |
|       this.$alert(getActionDisplayName('no-preview-config'), getActionDisplayName('notice'), {
 | |
|         confirmButtonText: getActionDisplayName('confirm'),
 | |
|         callback: action => {
 | |
|           const newPath = this.$route.path.replace('/preview', '');
 | |
|           this.$router.replace(newPath);
 | |
|         }
 | |
|       });
 | |
|       return;
 | |
|     }
 | |
|     this.previewConfig = previewConfig;
 | |
|     const themeConfig = getThemeConfigObject(previewConfig.theme);
 | |
|     if (themeConfig) {
 | |
|       this.themeConfig = themeConfig;
 | |
|       bus.$emit(ACTION_APPLY_THEME, themeConfig);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| </script>
 |