| | |
| | | }, |
| | | "dependencies": { |
| | | "@antv/data-set": "^0.11.4", |
| | | "animate.css": "^4.1.0", |
| | | "ant-design-vue": "^1.6.2", |
| | | "axios": "^0.19.2", |
| | | "clipboard": "^2.0.6", |
| | |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | :global{ |
| | | //拖拽控件全局样式 |
| | | .dragable-ghost{ |
| | | border: 1px dashed #aaaaaa; |
| | | opacity: 0.65; |
| | | } |
| | | .dragable-chose{ |
| | | border: 1px dashed #aaaaaa; |
| | | opacity: 0.65; |
| | | } |
| | | .dragable-drag{ |
| | | border: 1px dashed #aaaaaa; |
| | | opacity: 0.65; |
| | | } |
| | | //页面切换动画 |
| | | .page-toggle-enter-active{ |
| | | transition: all 0.2s ease-in 0.25s; |
| | | } |
| | | .page-toggle-leave-active{ |
| | | transition: all 0.2s ease-out 0s; |
| | | } |
| | | .page-toggle-enter, .page-toggle-leave-to{ |
| | | opacity: 0; |
| | | padding: 0px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | required: true |
| | | }, |
| | | value: { |
| | | type: String, |
| | | type: [String, Number], |
| | | required: true |
| | | }, |
| | | checked: { |
| | |
| | | .contextmenu{ |
| | | position: fixed; |
| | | z-index: 1; |
| | | border: 1px solid #9e9e9e; |
| | | |
| | | border-radius: 4px; |
| | | box-shadow: 2px 2px 10px #aaaaaa !important; |
| | | box-shadow: -4px 4px 16px 1px #e6e6e6 !important; |
| | | } |
| | | </style> |
| | |
| | | </img-checkbox-group> |
| | | </setting-item> |
| | | <setting-item title="主题色"> |
| | | <color-checkbox-group @change="onColorChange" :defaultValues="['6']" :multiple="false"> |
| | | <color-checkbox color="#f5222d" value="1" /> |
| | | <color-checkbox color="#fa541c" value="2" /> |
| | | <color-checkbox color="#faad14" value="3" /> |
| | | <color-checkbox color="#13c2c2" value="4" /> |
| | | <color-checkbox color="#52c41a" value="5" /> |
| | | <color-checkbox color="#1d92ff" value="6" /> |
| | | <color-checkbox color="#2f54eb" value="7" /> |
| | | <color-checkbox color="#722ed1" value="8" /> |
| | | <color-checkbox-group @change="onColorChange" :defaultValues="[0]" :multiple="false"> |
| | | <color-checkbox v-for="(color, index) in colors" :key="index" :color="color" :value="index" /> |
| | | </color-checkbox-group> |
| | | </setting-item> |
| | | <a-divider/> |
| | |
| | | </a-list> |
| | | </setting-item> |
| | | <a-divider /> |
| | | <setting-item title="页面切换动画"> |
| | | <a-list :split="false"> |
| | | <a-list-item> |
| | | 动画效果 |
| | | <a-select v-model="animate" @change="setAnimate" class="select-item" size="small" slot="actions"> |
| | | <a-select-option :key="index" :value="index" v-for="(item, index) in animates">{{item.alias}}</a-select-option> |
| | | </a-select> |
| | | </a-list-item> |
| | | <a-list-item> |
| | | 动画方向 |
| | | <a-select v-model="direction" @change="setAnimate" class="select-item" size="small" slot="actions"> |
| | | <a-select-option :key="index" :value="index" v-for="(item, index) in animateCfg.directions">{{item}}</a-select-option> |
| | | </a-select> |
| | | </a-list-item> |
| | | </a-list> |
| | | </setting-item> |
| | | <a-button id="copyBtn" data-clipboard-text="Sorry, you have copied nothing O(∩_∩)O~" @click="copyCode" style="width: 100%" icon="copy" >拷贝代码</a-button> |
| | | </a-layout-sider> |
| | | </template> |
| | |
| | | import ImgCheckbox from '../checkbox/ImgCheckbox' |
| | | import Clipboard from 'clipboard' |
| | | import themeUtil from '../../utils/themeUtil'; |
| | | import { mapState } from 'vuex' |
| | | |
| | | const ColorCheckboxGroup = ColorCheckbox.Group |
| | | const ImgCheckboxGroup = ImgCheckbox.Group |
| | |
| | | export default { |
| | | name: 'Setting', |
| | | components: {ImgCheckboxGroup, ImgCheckbox, ColorCheckboxGroup, ColorCheckbox, SettingItem}, |
| | | computed: { |
| | | multiPage () { |
| | | return this.$store.state.setting.multiPage |
| | | data() { |
| | | return { |
| | | animate: 0, |
| | | direction: 0, |
| | | colors: ['#f5222d', '#fa541c', '#faad14', '#13c2c2', '#52c41a', '#1d92ff', '#2f54eb', '#722ed1'], |
| | | } |
| | | }, |
| | | computed: { |
| | | animateCfg() { |
| | | return this.animates[this.animate] |
| | | }, |
| | | ...mapState('setting', ['animates', 'multiPage']) |
| | | }, |
| | | methods: { |
| | | onColorChange (values, colors) { |
| | |
| | | }, |
| | | setMultiPage (checked) { |
| | | this.$store.commit('setting/setMultiPage', checked) |
| | | }, |
| | | setAnimate() { |
| | | let animation = this.animates[this.animate] |
| | | let animate = { |
| | | name: animation.name, |
| | | direction: animation.directions[this.direction] |
| | | } |
| | | this.$store.commit('setting/setAnimate', animate) |
| | | } |
| | | } |
| | | } |
| | |
| | | .flex{ |
| | | display: flex; |
| | | } |
| | | .select-item{ |
| | | width: 80px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <transition |
| | | :enter-active-class="`animated ${enterAnimate} page-toggle-enter-active`" |
| | | :leave-active-class="`animated ${leaveAnimate} page-toggle-leave-active`" |
| | | > |
| | | <slot></slot> |
| | | </transition> |
| | | </template> |
| | | |
| | | <script> |
| | | import {animates} from '@/config' |
| | | |
| | | export default { |
| | | name: 'PageToggleTransition', |
| | | props: { |
| | | animate: { |
| | | type: String, |
| | | validator(value) { |
| | | return animates.find(item => item.name == value) != -1 |
| | | }, |
| | | default: 'bounce' |
| | | }, |
| | | direction: { |
| | | type: String, |
| | | validator(value) { |
| | | return ['x', 'y', 'left', 'right', 'up', 'down', 'downLeft', 'upRight', 'downRight', 'upLeft', 'downBig', |
| | | 'upBig', 'downLeft', 'downRight', 'topRight', 'bottomLeft', 'topLeft', 'bottomRight', 'default'].indexOf(value) > -1 |
| | | } |
| | | }, |
| | | reverse: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | computed: { |
| | | enterAnimate() { |
| | | return this.activeClass(false) |
| | | }, |
| | | leaveAnimate() { |
| | | return this.activeClass(true) |
| | | } |
| | | }, |
| | | methods: { |
| | | activeClass(isLeave) { |
| | | let animate = animates.find(item => this.animate == item.name) |
| | | if (animate == undefined) { |
| | | return '' |
| | | } |
| | | let direction = '' |
| | | if (this.direction == undefined) { |
| | | direction = animate.directions[0] |
| | | } else { |
| | | direction = animate.directions.find(item => item == this.direction) |
| | | direction = (direction == undefined || direction === 'default') ? '' : direction |
| | | } |
| | | window.console.log(direction) |
| | | if (direction != '') { |
| | | direction = isLeave && this.reverse ? this.reversePosition(direction, animate.directions) : direction |
| | | direction = direction[0].toUpperCase() + direction.substring(1) |
| | | } |
| | | let t = isLeave ? 'Out' : 'In' |
| | | return animate.name + t + direction |
| | | }, |
| | | reversePosition(direction, directions) { |
| | | if(direction.length == 0 || direction == 'x' || direction == 'y') { |
| | | return direction |
| | | } |
| | | let index = directions.indexOf(direction) |
| | | index = (index % 2 == 1) ? index - 1 : index + 1 |
| | | return directions[index] |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | .page-toggle-enter-active{ |
| | | position: absolute !important; |
| | | animation-duration: 0.6s !important; |
| | | width: calc(100% - 48px); |
| | | } |
| | | .page-toggle-leave-active{ |
| | | position: absolute !important; |
| | | animation-duration: 0.6s !important; |
| | | width: calc(100% - 48px); |
| | | } |
| | | .page-toggle-enter{ |
| | | } |
| | | .page-toggle-leave-to{ |
| | | } |
| | | </style> |
New file |
| | |
| | | const direct_s = ['left', 'right'] |
| | | const direct_1 = ['down', 'up', 'left', 'right'] |
| | | const direct_1_b = ['downBig', 'upBig', 'leftBig', 'rightBig'] |
| | | const direct_2 = ['topLeft', 'bottomRight', 'topRight', 'bottomLeft'] |
| | | const direct_3 = ['downLeft', 'upRight', 'downRight', 'upLeft'] |
| | | |
| | | module.exports = [ |
| | | {name: 'back', alias: '后位', directions: direct_1}, |
| | | {name: 'bounce', alias: '弹跳', directions: direct_1.concat('default')}, |
| | | {name: 'fade', alias: '淡化', directions: direct_1.concat(direct_1_b).concat(direct_2).concat('default')}, |
| | | {name: 'flip', alias: '翻转', directions: ['x', 'y', 'default']}, |
| | | {name: 'lightSpeed', alias: '光速', directions: direct_s}, |
| | | {name: 'rotate', alias: '旋转', directions: direct_3.concat('default')}, |
| | | {name: 'roll', alias: '翻滚', directions: ['default']}, |
| | | {name: 'zoom', alias: '缩放', directions: direct_1.concat('default')}, |
| | | {name: 'slide', alias: '滑动', directions: direct_1}, |
| | | ] |
New file |
| | |
| | | // 系统配置 |
| | | module.exports = { |
| | | themeColor: '#1890ff', |
| | | animates: require('./animates'), |
| | | footerLinks: [ |
| | | {link: 'https://pro.ant.design', name: 'Pro首页'}, |
| | | {link: 'https://github.com/iczer/vue-antd-admin', icon: 'github'}, |
| | | {link: 'https://ant.design', name: 'Ant Design'} |
| | | ], |
| | | |
| | | } |
| | |
| | | </drawer> |
| | | <a-layout> |
| | | <global-header :menuData="menuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/> |
| | | <a-layout-content :style="{minHeight: minHeight, margin: '24px 24px 0'}"> |
| | | <a-layout-content :style="{minHeight: minHeight, padding: '24px 24px 0', position: 'relative'}"> |
| | | <slot></slot> |
| | | </a-layout-content> |
| | | <a-layout-footer style="padding: 0px"> |
| | |
| | | type="editable-card" |
| | | @change="changePage" |
| | | @edit="editPage"> |
| | | <a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList"> |
| | | <a-tab-pane :key="page.fullPath" v-for="page in pageList"> |
| | | <span slot="tab" :pagekey="page.fullPath">{{page.name}}</span> |
| | | </a-tab-pane> |
| | | </a-tabs> |
| | | <transition name="page-toggle"> |
| | | <page-toggle-transition :animate="animate.name" :direction="animate.direction"> |
| | | <keep-alive v-if="multiPage"> |
| | | <router-view /> |
| | | </keep-alive> |
| | | <router-view v-else /> |
| | | </transition> |
| | | </page-toggle-transition> |
| | | </global-layout> |
| | | </template> |
| | | |
| | | <script> |
| | | import GlobalLayout from './GlobalLayout' |
| | | import Contextmenu from '../components/menu/Contextmenu' |
| | | import PageToggleTransition from '../components/transition/PageToggleTransition' |
| | | import {mapState} from 'vuex' |
| | | |
| | | export default { |
| | | name: 'MenuView', |
| | | components: {Contextmenu, GlobalLayout}, |
| | | components: {PageToggleTransition, Contextmenu, GlobalLayout}, |
| | | data () { |
| | | return { |
| | | pageList: [], |
| | |
| | | } |
| | | }, |
| | | computed: { |
| | | multiPage () { |
| | | return this.$store.state.setting.multiPage |
| | | } |
| | | ...mapState('setting', ['multiPage', 'animate']) |
| | | }, |
| | | created () { |
| | | this.pageList.push(this.$route) |
| | |
| | | this.pageList.push(newRoute) |
| | | } |
| | | }, |
| | | 'activePage': function () { |
| | | // this.$router.push(key) |
| | | 'activePage': function (key) { |
| | | this.$router.push(key) |
| | | }, |
| | | 'multiPage': function (newVal) { |
| | | if (!newVal) { |
| | |
| | | <slot v-if="this.$refs.extra" slot="extra" name="extra"></slot> |
| | | </page-header> |
| | | <div ref="page" :class="['page-content', layout]" > |
| | | <slot ></slot> |
| | | <slot></slot> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | } |
| | | } |
| | | .page-content{ |
| | | position: relative; |
| | | &.side{ |
| | | margin: 24px 24px 0px; |
| | | padding: 24px 24px 0; |
| | | } |
| | | &.head{ |
| | | margin: 24px auto 0; |
| | | padding: 24px 0 0; |
| | | max-width: 1400px; |
| | | } |
| | | } |
| | |
| | | <div slot="extra" class="extraImg"> |
| | | <img :src="extraImage"/> |
| | | </div> |
| | | <transition name="page-toggle"> |
| | | <page-toggle-transition :animate="animate.name" :direction="animate.direction"> |
| | | <keep-alive v-if="multiPage"> |
| | | <router-view ref="page" /> |
| | | </keep-alive> |
| | | <router-view ref="page" v-else /> |
| | | </transition> |
| | | </page-toggle-transition> |
| | | </page-layout> |
| | | </template> |
| | | |
| | | <script> |
| | | import PageLayout from './PageLayout' |
| | | import PageToggleTransition from '../components/transition/PageToggleTransition'; |
| | | import {mapState} from 'vuex' |
| | | |
| | | export default { |
| | | name: 'PageView', |
| | | components: {PageLayout}, |
| | | components: {PageToggleTransition, PageLayout}, |
| | | data () { |
| | | return { |
| | | title: '', |
| | |
| | | } |
| | | }, |
| | | computed: { |
| | | multiPage () { |
| | | return this.$store.state.setting.multiPage |
| | | } |
| | | ...mapState('setting', ['multiPage', 'animate']) |
| | | }, |
| | | mounted () { |
| | | this.getPageHeaderInfo() |
| | |
| | | <template> |
| | | <transition name="page-toggle"> |
| | | <page-toggle-transition :animate="animate.name" :direction="animate.direction"> |
| | | <keep-alive v-if="multiPage"> |
| | | <router-view /> |
| | | </keep-alive> |
| | | <router-view v-else /> |
| | | </transition> |
| | | </page-toggle-transition> |
| | | </template> |
| | | |
| | | <script> |
| | | import PageToggleTransition from '../components/transition/PageToggleTransition'; |
| | | import {mapState} from 'vuex' |
| | | |
| | | export default { |
| | | name: 'RouteView', |
| | | components: {PageToggleTransition}, |
| | | computed: { |
| | | multiPage () { |
| | | return this.$store.state.setting.multiPage |
| | | } |
| | | ...mapState('setting', ['multiPage', 'animate']) |
| | | } |
| | | } |
| | | </script> |
| | |
| | | import '@/mock' |
| | | import store from './store' |
| | | import PouchDB from 'pouchdb' |
| | | import 'animate.css/source/animate.css' |
| | | |
| | | Vue.prototype.$axios = axios |
| | | Vue.config.productionTip = false |
| | |
| | | .task-group{ |
| | | margin: 0 48px; |
| | | } |
| | | .dragable-ghost{ |
| | | border: 1px dashed red; |
| | | opacity: 1; |
| | | } |
| | | .dragable-chose{ |
| | | border: 1px dashed red; |
| | | opacity: 0.8; |
| | | } |
| | | .dragable-drag{ |
| | | border: 1px dashed red; |
| | | opacity: 1; |
| | | } |
| | | </style> |
| | |
| | | import {footerLinks, animates} from '@/config' |
| | | export default { |
| | | namespaced: true, |
| | | state: { |
| | |
| | | layout: 'side', |
| | | systemName: 'Vue Antd Admin', |
| | | copyright: '2018 ICZER 工作室出品', |
| | | footerLinks: [ |
| | | {link: 'https://pro.ant.design', name: 'Pro首页'}, |
| | | {link: 'https://github.com/iczer/vue-antd-admin', icon: 'github'}, |
| | | {link: 'https://ant.design', name: 'Ant Design'} |
| | | ], |
| | | multiPage: true |
| | | footerLinks: footerLinks, |
| | | multiPage: true, |
| | | animates: animates, |
| | | animate: { |
| | | name: 'back', |
| | | direction: 'left' |
| | | } |
| | | }, |
| | | mutations: { |
| | | setDevice (state, isMobile) { |
| | |
| | | }, |
| | | setMultiPage (state, multiPage) { |
| | | state.multiPage = multiPage |
| | | }, |
| | | setAnimate (state, animate) { |
| | | state.animate = animate |
| | | } |
| | | } |
| | | } |
| | |
| | | const ThemeColorReplacer = require('webpack-theme-color-replacer') |
| | | const client = require('webpack-theme-color-replacer/client') |
| | | const generate = require('@ant-design/colors/lib/generate').default |
| | | const themeColor = require('../config').themeColor |
| | | |
| | | module.exports = { |
| | | primaryColor: '#1890ff', |
| | | primaryColor: themeColor, |
| | | getThemeColors(color) { |
| | | const lightens = new Array(9).fill().map((t, i) => { |
| | | return ThemeColorReplacer.varyColor.lighten(color, i / 10) |
| | |
| | | // let path = require('path') |
| | | const ThemeColorReplacer = require('webpack-theme-color-replacer') |
| | | const getThemeColors = require('./src/utils/themeUtil').getThemeColors |
| | | const themeColor = require('./src/config').themeColor |
| | | |
| | | module.exports = { |
| | | pluginOptions: { |
| | |
| | | config.plugins.push( |
| | | new ThemeColorReplacer({ |
| | | fileName: 'css/theme-colors.css', |
| | | matchColors: getThemeColors('#1890ff') |
| | | matchColors: getThemeColors(themeColor) |
| | | }) |
| | | ) |
| | | }, |
| | |
| | | resolved "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" |
| | | integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= |
| | | |
| | | animate.css@^4.1.0: |
| | | version "4.1.0" |
| | | resolved "https://registry.npm.taobao.org/animate.css/download/animate.css-4.1.0.tgz#dec2aabe4babfc6f6777f9a5cccd132838729b50" |
| | | integrity sha1-3sKqvkur/G9nd/mlzM0TKDhym1A= |
| | | |
| | | ansi-colors@^3.0.0: |
| | | version "3.2.4" |
| | | resolved "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" |