Merge branch 'hotfix/from1.4.8'

Former-commit-id: a3f063630e5c8094dc5579c42e0137a769c109e8
This commit is contained in:
liyang
2018-09-20 14:37:30 +08:00
42 changed files with 2174 additions and 11050 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# 所有环境
# 所有环境默认
# 页面 title 前缀
VUE_APP_TITLE=D2Admin
+10
View File
@@ -0,0 +1,10 @@
# travis
# 页面 title 前缀
VUE_APP_TITLE=D2Admin Preview
# 页面 指定使用的模式
NODE_ENV=production
# 标记当前编译版本
VUE_APP_TRAVIS=TRUE
+1 -1
View File
@@ -9,7 +9,7 @@ branches:
- master
script:
- npm run build
- npm run build:travis
deploy:
provider: pages
+1196 -1176
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,16 +1,18 @@
{
"name": "d2-admin",
"version": "1.3.0",
"version": "1.4.8",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --open",
"start": "vue-cli-service serve --open",
"dev": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"build:travis": "vue-cli-service build --mode travis",
"lint": "vue-cli-service lint --fix",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"@d2-projects/d2-crud": "^1.2.0",
"axios": "^0.17.1",
"babel-polyfill": "^6.26.0",
"better-scroll": "^1.12.1",
@@ -23,6 +25,7 @@
"lodash": "^4.17.10",
"lowdb": "^1.0.0",
"mockjs": "^1.0.1-beta3",
"nprogress": "^0.2.0",
"particles.js": "^2.0.0",
"screenfull": "^3.3.2",
"ua-parser-js": "^0.7.18",
@@ -48,9 +51,6 @@
"text-loader": "0.0.1",
"vue-template-compiler": "^2.5.17"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.js": [
"vue-cli-service lint",
+3 -2
View File
@@ -146,8 +146,9 @@
s.parentNode.insertBefore(hm, s);
})();
</script>
<script src="./script/ua-parser.min.js"></script>
<script src="./script/ua.js"></script>
<!-- ua -->
<script src="<%= BASE_URL %>script/ua-parser.min.js"></script>
<script src="<%= BASE_URL %>script/ua.js"></script>
</head>
<body>
<noscript>
+8
View File
@@ -0,0 +1,8 @@
#nprogress {
.bar {
background: $color-primary !important;
}
.peg {
box-shadow: 0 0 10px $color-primary, 0 0 5px $color-primary !important;
}
}
+2
View File
@@ -4,6 +4,8 @@
@import '~@/assets/style/fixed/base.scss';
// 补丁 element
@import '~@/assets/style/fixed/element.scss';
// 补丁 n-progress
@import '~@/assets/style/fixed/n-progress.scss';
// 动画
@import '~@/assets/style/animate/vue-transition.scss';
+44 -10
View File
@@ -26,9 +26,51 @@
// 内容层
.d2-layout-header-aside-content {
@extend %full;
$d2-theme-header-height: 60px;
.d2-theme-header {
height: $d2-theme-header-height;
height: 60px;
.d2-theme-header-menu {
overflow: hidden;
&.is-scrollable {
position: relative;
padding: 0 20px;
.d2-theme-header-menu__prev, .d2-theme-header-menu__next {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
}
.d2-theme-header-menu__content {
overflow: hidden;
.d2-theme-header-menu__scroll {
white-space: nowrap;
position: relative;
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
transition: transform .3s,-webkit-transform .3s;
float: left;
}
}
.d2-theme-header-menu__prev, .d2-theme-header-menu__next {
height: 60px;
position: absolute;
top: 0;
font-size: 20px;
cursor: pointer;
display: none;
}
.d2-theme-header-menu__prev {
left: 0;
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
.d2-theme-header-menu__next {
right: 0;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
}
}
.d2-theme-container {
.d2-theme-container-aside {
@@ -58,13 +100,6 @@
}
}
// 主题公用
.d2-layout-header-aside-group {
&.grayMode {
@@ -135,7 +170,6 @@
padding: 14px 12px;
border-radius: 4px;
margin: 0px !important;
margin-left: 10px !important;
}
.el-dropdown {
@extend %unable-select;
+11
View File
@@ -63,6 +63,17 @@
// 顶栏
.d2-theme-header {
// 顶栏菜单空间不足时显示的滚动控件
.d2-theme-header-menu {
.d2-theme-header-menu__prev, .d2-theme-header-menu__next {
color: $theme-header-item-color;
background: $theme-header-item-background-color;
&:hover {
color: $theme-header-item-color-hover;
background: $theme-header-item-background-color-hover;
}
}
}
// 切换按钮
.toggle-aside-btn {
i {
@@ -1,9 +1,6 @@
<template>
<el-menu-item :index="menu.path || uniqueId">
<i v-if="menu.icon" :class="`fa fa-${menu.icon}`"></i>
<!-- <i v-else-if="menu.iconSvg">
<d2-icon-svg :name="menu.iconSvg"/>
</i> -->
<d2-icon-svg v-else-if="menu.iconSvg" :name="menu.iconSvg"/>
<i v-else class="fa fa-file-o"></i>
<span slot="title">{{menu.title || '未命名菜单'}}</span>
@@ -2,9 +2,6 @@
<el-submenu :index="menu.path || uniqueId">
<template slot="title">
<i v-if="menu.icon" :class="`fa fa-${menu.icon}`"></i>
<!-- <i v-else-if="menu.iconSvg">
<d2-icon-svg :name="menu.iconSvg"/>
</i> -->
<d2-icon-svg v-else-if="menu.iconSvg" :name="menu.iconSvg"/>
<i v-else class="fa fa-folder-o"></i>
<span slot="title">{{menu.title}}</span>
@@ -11,7 +11,7 @@
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState('d2admin/fullscreen', [
@@ -19,7 +19,7 @@ export default {
])
},
methods: {
...mapMutations('d2admin/fullscreen', [
...mapActions('d2admin/fullscreen', [
'toggle'
])
}
@@ -0,0 +1,67 @@
<template>
<el-dropdown placement="bottom" size="small" @command="handleChange">
<el-button class="d2-mr btn-text can-hover" type="text">
<d2-icon name="font" style="font-size: 16px;"/>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="default">
<d2-icon :name="iconName('default')" class="d2-mr-5"/>默认
</el-dropdown-item>
<el-dropdown-item command="medium">
<d2-icon :name="iconName('medium')" class="d2-mr-5"/>中
</el-dropdown-item>
<el-dropdown-item command="small">
<d2-icon :name="iconName('small')" class="d2-mr-5"/>小
</el-dropdown-item>
<el-dropdown-item command="mini">
<d2-icon :name="iconName('mini')" class="d2-mr-5"/>最小
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
name: 'd2-header-size',
computed: {
...mapState('d2admin/size', [
'value'
])
},
watch: {
// 注意 这里是关键
// 因为需要访问 this.$ELEMENT 所以只能在这里使用这种方式
value: {
handler (val) {
if (this.$ELEMENT.size !== val) {
// 设置 element 全局尺寸
this.$ELEMENT.size = val
// 清空缓存设置
this.pageKeepAliveClean()
// 刷新此页面
const { path, query } = this.$route
this.$router.replace({
path: '/redirect/' + JSON.stringify({ path, query })
})
}
},
immediate: true
}
},
methods: {
...mapMutations({
pageKeepAliveClean: 'd2admin/page/keepAliveClean'
}),
...mapActions({
sizeSet: 'd2admin/size/set'
}),
handleChange (value) {
this.sizeSet(value)
},
iconName (name) {
return name === this.value ? 'dot-circle-o' : 'circle-o'
}
}
}
</script>
@@ -18,7 +18,7 @@
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import { mapState, mapActions } from 'vuex'
export default {
name: 'd2-theme-list',
data () {
@@ -36,7 +36,7 @@ export default {
])
},
methods: {
...mapMutations('d2admin/theme', [
...mapActions('d2admin/theme', [
'set'
]),
handleSelectTheme (name) {
@@ -1,5 +1,5 @@
<template>
<el-dropdown class="d2-mr">
<el-dropdown size="small" class="d2-mr">
<span class="btn-text">你好 {{info.name}}</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="logOff">
@@ -1,13 +1,26 @@
<template>
<div class="d2-theme-header-menu" ref="page" :class="{'is-scrollable': isScroll}" flex="cross:center">
<div class="d2-theme-header-menu__content" ref="content" flex-box="1" flex>
<div class="d2-theme-header-menu__scroll" ref="scroll" flex-box="0" :style="'transform: translateX(' + currentTranslateX + 'px);'">
<el-menu mode="horizontal" :default-active="active" @select="handleMenuSelect">
<template v-for="(menu, menuIndex) in header">
<d2-layout-header-aside-menu-item v-if="menu.children === undefined" :menu="menu" :key="menuIndex"/>
<d2-layout-header-aside-menu-sub v-else :menu="menu" :key="menuIndex"/>
</template>
</el-menu>
</div>
</div>
<div v-if="isScroll" class="d2-theme-header-menu__prev" flex-box="0" @click="scroll('left')" flex="main:center cross:center">
<i class="el-icon-arrow-left"></i>
</div>
<div v-if="isScroll" class="d2-theme-header-menu__next" flex-box="0" @click="scroll('right')" flex="cross:center">
<i class="el-icon-arrow-right"></i>
</div>
</div>
</template>
<script>
import { throttle } from 'lodash'
import { mapState } from 'vuex'
import menuMixin from '../mixin/menu'
import d2LayoutMainMenuItem from '../components/menu-item/index.vue'
@@ -28,7 +41,12 @@ export default {
},
data () {
return {
active: ''
active: '',
isScroll: false,
scrollWidth: 0,
contentWidth: 0,
currentTranslateX: 0,
throttledCheckScroll: null
}
},
watch: {
@@ -38,6 +56,67 @@ export default {
},
immediate: true
}
},
methods: {
scroll (direction) {
if (direction === 'left') {
// 向右滚动
this.currentTranslateX = 0
} else {
// 向左滚动
if (this.contentWidth * 2 - this.currentTranslateX <= this.scrollWidth) {
this.currentTranslateX -= this.contentWidth
} else {
this.currentTranslateX = this.contentWidth - this.scrollWidth
}
}
},
checkScroll () {
let contentWidth = this.$refs.content.clientWidth
let scrollWidth = this.$refs.scroll.clientWidth
if (this.isScroll) {
// 页面依旧允许滚动的情况,需要更新width
if (this.contentWidth - this.scrollWidth === this.currentTranslateX) {
// currentTranslateX 也需要相应变化【在右端到头的情况时】
this.currentTranslateX = contentWidth - scrollWidth
// 快速的滑动依旧存在判断和计算时对应的contentWidth变成正数,所以需要限制一下
if (this.currentTranslateX > 0) {
this.currentTranslateX = 0
}
}
// 更新元素数据
this.contentWidth = contentWidth
this.scrollWidth = scrollWidth
// 判断何时滚动消失: 当page > content + btns(40)
if (contentWidth > scrollWidth + 40) {
this.isScroll = false
}
}
// 判断何时滚动出现: 当page < content
if (!this.isScroll && contentWidth < scrollWidth) {
this.isScroll = true
// 注意,当isScroll变为true,对应的元素盒子大小会发生变化
this.$nextTick(() => {
contentWidth = this.$refs.content.clientWidth
scrollWidth = this.$refs.scroll.clientWidth
this.contentWidth = contentWidth
this.scrollWidth = scrollWidth
this.currentTranslateX = 0
})
}
}
},
mounted () {
// 初始化判断
// 默认判断父元素和子元素的大小,以确定初始情况是否显示滚动
this.checkScroll()
// 全局窗口变化监听,判断父元素和子元素的大小,从而控制isScroll的开关
this.throttledCheckScroll = throttle(this.checkScroll, 300)
window.addEventListener('resize', this.throttledCheckScroll)
},
beforeDestroy () {
// 取消监听
window.removeEventListener('resize', this.throttledCheckScroll)
}
}
</script>
@@ -1,6 +1,12 @@
<template>
<div class="panel-search" flex="dir:top">
<div class="panel-search__input-group" flex-box="0" flex="dir:top main:center cross:center">
<div
class="panel-search"
flex="dir:top">
<div
class="panel-search__input-group"
flex-box="0"
flex="dir:top main:center cross:center"
@click.self="handlePanelClick">
<d2-icon-svg
class="panel-search__logo"
name="d2-admin-text"/>
@@ -15,7 +21,9 @@
:clearable="true"
@keydown.esc.native="handleEsc"
@select="handleSelect">
<d2-panel-search-item slot-scope="{ item }" :item="item"/>
<d2-panel-search-item
slot-scope="{ item }"
:item="item"/>
</el-autocomplete>
<div class="panel-search__tip">
您可以使用快捷键
@@ -155,6 +163,12 @@ export default {
this.$refs.input.activated = false
}
},
/**
* @augments 接收用户点击空白区域的关闭
*/
handlePanelClick () {
this.handleEsc()
},
/**
* @augments 接收用户触发的关闭
*/
@@ -30,6 +30,7 @@
class="d2-multiple-page-control-btn"
flex-box="0">
<el-dropdown
size="default"
split-button
@click="handleControlBtnClick"
@command="command => handleControlItemClick(command)">
@@ -58,7 +59,7 @@
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import { mapState, mapActions } from 'vuex'
export default {
components: {
D2Contextmenu: () => import('../contextmenu'),
@@ -88,7 +89,7 @@ export default {
])
},
methods: {
...mapMutations('d2admin/page', [
...mapActions('d2admin/page', [
'close',
'closeLeft',
'closeRight',
@@ -100,7 +101,6 @@ export default {
*/
handleContextmenu (event) {
let target = event.target
// 解决 https://github.com/d2-projects/d2-admin/issues/54
let flag = false
if (target.className.indexOf('el-tabs__item') > -1) flag = true
@@ -108,7 +108,6 @@ export default {
target = target.parentNode
flag = true
}
if (flag) {
event.preventDefault()
event.stopPropagation()
+16 -13
View File
@@ -11,24 +11,26 @@
<div
class="d2-theme-header"
:style="{
opacity: this.searchActive ? 0.3 : 1
opacity: this.searchActive ? 0.5 : 1
}"
flex-box="0">
<div class="logo-group" :style="{width: asideCollapse ? asideWidthCollapse : asideWidth}">
flex-box="0"
flex>
<div class="logo-group" :style="{width: asideCollapse ? asideWidthCollapse : asideWidth}" flex-box="0">
<img v-if="asideCollapse" :src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/icon-only.png`">
<img v-else :src="`${$baseUrl}image/theme/${themeActiveSetting.name}/logo/all.png`">
</div>
<div class="toggle-aside-btn" @click="handleToggleAside">
<div class="toggle-aside-btn" @click="handleToggleAside" flex-box="0">
<d2-icon name="bars"/>
</div>
<d2-menu-header/>
<d2-menu-header flex-box="1"/>
<!-- 顶栏右侧 -->
<div class="d2-header-right">
<div class="d2-header-right" flex-box="0">
<!-- 如果你只想在开发环境显示这个按钮请添加 v-if="$env === 'development'" -->
<d2-header-search @click="handleSearchClick"/>
<d2-header-error-log/>
<d2-header-fullscreen/>
<d2-header-theme/>
<d2-header-size/>
<d2-header-user/>
</div>
</div>
@@ -41,7 +43,7 @@
class="d2-theme-container-aside"
:style="{
width: asideCollapse ? asideWidthCollapse : asideWidth,
opacity: this.searchActive ? 0.3 : 1
opacity: this.searchActive ? 0.5 : 1
}">
<d2-menu-side/>
</div>
@@ -79,7 +81,7 @@
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
import { mapState, mapGetters, mapActions } from 'vuex'
import mixinSearch from './mixins/search'
export default {
name: 'd2-layout-header-aside',
@@ -92,6 +94,7 @@ export default {
'd2-tabs': () => import('./components/tabs'),
'd2-header-fullscreen': () => import('./components/header-fullscreen'),
'd2-header-search': () => import('./components/header-search'),
'd2-header-size': () => import('./components/header-size'),
'd2-header-theme': () => import('./components/header-theme'),
'd2-header-user': () => import('./components/header-user'),
'd2-header-error-log': () => import('./components/header-error-log')
@@ -106,12 +109,12 @@ export default {
},
computed: {
...mapState('d2admin', {
keepAlive: state => state.page.keepAlive,
grayActive: state => state.gray.active,
transitionActive: state => state.transition.active,
asideCollapse: state => state.menu.asideCollapse
}),
...mapGetters('d2admin', {
keepAlive: 'page/keepAlive',
themeActiveSetting: 'theme/activeSetting'
}),
/**
@@ -126,14 +129,14 @@ export default {
}
},
methods: {
...mapMutations({
menuAsideCollapseToggle: 'd2admin/menu/asideCollapseToggle'
}),
...mapActions('d2admin/menu', [
'asideCollapseToggle'
]),
/**
* 接收点击切换侧边栏的按钮
*/
handleToggleAside () {
this.menuAsideCollapseToggle()
this.asideCollapseToggle()
}
}
}
+8 -4
View File
@@ -12,6 +12,9 @@ import i18n from './i18n'
// 核心插件
import d2Admin from '@/plugin/d2admin'
// [ 可选插件组件 ]D2-Crud
import D2Crud from '@d2-projects/d2-crud'
// 菜单和路由设置
import router from './router'
import menuHeader from '@/menu/header'
@@ -21,6 +24,9 @@ import { frameInRoutes } from '@/router/routes'
// 核心插件
Vue.use(d2Admin)
// 可选插件组件
Vue.use(D2Crud)
new Vue({
router,
store,
@@ -39,13 +45,11 @@ new Vue({
mounted () {
// 展示系统信息
this.$store.commit('d2admin/releases/versionShow')
// 检查最新版本
this.$store.dispatch('d2admin/releases/checkUpdate')
// 用户登录后从数据库加载一系列的设置
this.$store.commit('d2admin/account/load')
this.$store.dispatch('d2admin/account/load')
// 获取并记录用户 UA
this.$store.commit('d2admin/ua/get')
// 初始化全屏监听
this.$store.commit('d2admin/fullscreen/listen')
this.$store.dispatch('d2admin/fullscreen/listen')
}
}).$mount('#app')
Executable → Regular
View File
Executable → Regular
View File
@@ -0,0 +1,36 @@
<template>
<div class="d2-badge">
<p align="center">
<a><img src="https://img.shields.io/github/release/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/github/forks/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/github/stars/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/github/issues/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/github/issues-closed/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/github/issues-pr/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/github/issues-pr-closed/d2-projects/d2-admin.svg"/></a>
</p>
<p align="center">
<a><img src="https://img.shields.io/npm/v/@d2-admin/ice-scaffold.svg"/></a>
<a href="https://www.travis-ci.org/d2-projects/d2-admin"><img src="https://www.travis-ci.org/d2-projects/d2-admin.svg?branch=master"/></a>
<a><img src="https://img.shields.io/github/last-commit/d2-projects/d2-admin.svg"/></a>
<a><img src="https://img.shields.io/badge/code_style-standard-brightgreen.svg"/></a>
</p>
</div>
</template>
<style lang="scss" scoped>
.d2-badge {
margin-bottom: 20px;
p {
margin: 0px;
margin-bottom: 2px;
:nth-last-child() {
margin-bottom: 0px;
}
a {
display: inline-block;
margin: 0px 2px;
}
}
}
</style>
+7 -2
View File
@@ -27,7 +27,8 @@
</p>
</el-popover>
</div>
<d2-help-btn class="d2-mt"/>
<d2-badge/>
<d2-help-btn/>
</template>
</d2-page-cover>
</d2-container>
@@ -35,9 +36,11 @@
<script>
import D2HelpBtn from './components/d2-help-btn'
import D2Badge from './components/d2-badge'
export default {
components: {
D2HelpBtn
D2HelpBtn,
D2Badge
}
}
</script>
@@ -48,6 +51,8 @@ export default {
.page__btn-group {
color: $color-text-placehoder;
font-size: 12px;
margin-top: -10px;
margin-bottom: 20px;
span {
color: $color-text-sub;
&:hover {
+3 -3
View File
@@ -9,7 +9,7 @@
<!-- 表单部分 -->
<div class="form-group">
<el-card>
<el-form ref="loginForm" label-position="top" :rules="rules" :model="formLogin">
<el-form ref="loginForm" label-position="top" :rules="rules" :model="formLogin" size="default">
<el-form-item prop="username">
<el-input type="text" v-model="formLogin.username" placeholder="用户名">
<i slot="prepend" class="fa fa-user-circle-o"></i>
@@ -28,12 +28,12 @@
</template>
</el-input>
</el-form-item>
<el-button @click="submit" type="primary" class="button-login">登录</el-button>
<el-button size="default" @click="submit" type="primary" class="button-login">登录</el-button>
</el-form>
</el-card>
</div>
<!-- 快速登录按钮 -->
<el-button type="info" class="button-help" @click="dialogVisible = true">
<el-button size="default" type="info" class="button-help" @click="dialogVisible = true">
快速选择用户(测试功能)
</el-button>
</div>
+12
View File
@@ -0,0 +1,12 @@
<script>
// 跳板页面
export default {
beforeCreate () {
const path = this.$route.params.path
this.$router.replace(JSON.parse(path))
},
render: function (h) {
return h()
}
}
</script>
+13 -2
View File
@@ -3,6 +3,8 @@ import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
// flex 布局库
import 'flex.css'
// store
import store from '@/store/index'
// 组件
import '@/components'
// svg 图标
@@ -13,9 +15,18 @@ import pluginLog from '@/plugin/log'
import pluginOpen from '@/plugin/open'
export default {
install (Vue, options) {
async install (Vue, options) {
// 获得用户设置的全局尺寸
const size = await store.dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'size.value',
defaultValue: '',
user: true
})
// Element
Vue.use(ElementUI)
Vue.use(ElementUI, {
size
})
// 插件
Vue.use(pluginError)
Vue.use(pluginLog)
+9 -1
View File
@@ -1,6 +1,10 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
// 进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store/index'
import util from '@/libs/util.js'
@@ -20,6 +24,8 @@ const router = new VueRouter({
* 权限验证
*/
router.beforeEach((to, from, next) => {
// 进度条
NProgress.start()
// 关闭搜索面板
store.commit('d2admin/search/set', false)
// 验证当前路由所有的匹配中是否需要有登录验证的
@@ -45,11 +51,13 @@ router.beforeEach((to, from, next) => {
})
router.afterEach(to => {
// 进度条
NProgress.done()
// 需要的信息
const app = router.app
const { name, params, query } = to
// 多页控制 打开新的页面
app.$store.commit('d2admin/page/open', { name, params, query })
app.$store.dispatch('d2admin/page/open', { name, params, query })
// 更改标题
util.title(to.meta.title)
})
+6 -1
View File
@@ -44,7 +44,12 @@ const frameIn = [
* 在主框架之外显示
*/
const frameOut = [
// 登陆
// 页面重定向使用 必须保留
{
path: '/redirect/:path*',
component: () => import('@/pages/redirect')
},
// 登录
{
path: '/login',
name: 'login',
+3 -1
View File
@@ -11,6 +11,7 @@ import gray from './modules/gray'
import page from './modules/page'
import transition from './modules/transition'
import search from './modules/search'
import size from './modules/size'
export default {
namespaced: true,
@@ -27,6 +28,7 @@ export default {
gray,
page,
transition,
search
search,
size
}
}
+17 -17
View File
@@ -12,9 +12,7 @@ export default {
* @param {Object} param password {String} 密码
* @param {Object} param route {Object} 登录成功后定向的路由对象
*/
login ({
commit
}, {
login ({ dispatch }, {
vm,
username,
password,
@@ -27,7 +25,7 @@ export default {
username,
password
})
.then(res => {
.then(async res => {
// 设置 cookie 一定要存 uuid 和 token 两个 cookie
// 整个系统依赖这两个数据进行校验和存储
// uuid 是用户身份唯一标识 用户注册的时候确定 并且不可改变 不可重复
@@ -36,11 +34,11 @@ export default {
util.cookies.set('uuid', res.uuid)
util.cookies.set('token', res.token)
// 设置 vuex 用户信息
commit('d2admin/user/set', {
await dispatch('d2admin/user/set', {
name: res.name
}, { root: true })
// 用户登录后从持久化数据加载一系列的设置
commit('load')
await dispatch('load')
// 更新路由 尝试去获取 cookie 里保存的需要重定向的页面完整地址
const path = util.cookies.get('redirect')
// 根据是否存有重定向页面判断如何重定向
@@ -49,9 +47,7 @@ export default {
util.cookies.remove('redirect')
})
.catch(err => {
console.group('登录结果')
console.log('err: ', err)
console.groupEnd()
})
},
/**
@@ -92,24 +88,28 @@ export default {
} else {
logout()
}
}
},
mutations: {
/**
* @description 用户登录后从持久化数据加载一系列的设置
* @param {Object} state vuex state
*/
load (state) {
load ({ commit, dispatch }) {
return new Promise(async resolve => {
// DB -> store 加载用户名
this.commit('d2admin/user/load')
await dispatch('d2admin/user/load', null, { root: true })
// DB -> store 加载主题
this.commit('d2admin/theme/load')
await dispatch('d2admin/theme/load', null, { root: true })
// DB -> store 加载页面过渡效果设置
this.commit('d2admin/transition/load')
await dispatch('d2admin/transition/load', null, { root: true })
// DB -> store 持久化数据加载上次退出时的多页列表
this.commit('d2admin/page/openedLoad')
// DB -> store 持久化数据加载这个用户之前设置的侧边栏折叠状态
this.commit('d2admin/menu/asideCollapseLoad')
await dispatch('d2admin/page/openedLoad', null, { root: true })
// DB -> store 持久化数据加载侧边栏折叠状态
await dispatch('d2admin/menu/asideCollapseLoad', null, { root: true })
// DB -> store 持久化数据加载全局尺寸
await dispatch('d2admin/size/load', null, { root: true })
// end
resolve()
})
}
}
}
@@ -6,31 +6,42 @@ export default {
// 全屏激活
active: false
},
mutations: {
actions: {
/**
* @description 初始化监听
*/
listen () {
listen ({ commit }) {
return new Promise(resolve => {
if (screenfull.enabled) {
screenfull.on('change', () => {
console.log('1')
if (!screenfull.isFullscreen) {
this.commit('d2admin/fullscreen/set', false)
commit('set', false)
}
})
}
// end
resolve()
})
},
/**
* @description 切换全屏
*/
toggle () {
toggle ({ commit }) {
return new Promise(resolve => {
if (screenfull.isFullscreen) {
screenfull.exit()
this.commit('d2admin/fullscreen/set', false)
commit('set', false)
} else {
screenfull.request()
this.commit('d2admin/fullscreen/set', true)
commit('set', true)
}
// end
resolve()
})
}
},
mutations: {
/**
* @description 设置 store 里的全屏状态
* @param {Object} state vuex state
+10 -10
View File
@@ -24,16 +24,6 @@ export default {
return state.list.filter(l => l.type === 'error').length
}
},
mutations: {
/**
* @description 清空日志
* @param {Object} state vuex state
*/
clean (state) {
// store 赋值
state.list = []
}
},
actions: {
/**
* @description 添加一个日志
@@ -70,5 +60,15 @@ export default {
info: toString(info)
}))
}
},
mutations: {
/**
* @description 清空日志
* @param {Object} state vuex state
*/
clean (state) {
// store 赋值
state.list = []
}
}
}
+58 -44
View File
@@ -11,6 +11,64 @@ export default {
// 侧边栏收缩
asideCollapse: setting.menu.asideCollapse
},
actions: {
/**
* 设置侧边栏展开或者收缩
* @param {Object} state vuex state
* @param {Boolean} collapse is collapse
*/
asideCollapseSet ({ state, dispatch }, collapse) {
return new Promise(async resolve => {
// store 赋值
state.asideCollapse = collapse
// 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideCollapse',
value: state.asideCollapse,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* 切换侧边栏展开和收缩
* @param {Object} state vuex state
*/
asideCollapseToggle ({ state, dispatch }) {
return new Promise(async resolve => {
// store 赋值
state.asideCollapse = !state.asideCollapse
// 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideCollapse',
value: state.asideCollapse,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* 从持久化数据读取侧边栏展开或者收缩
* @param {Object} state vuex state
*/
asideCollapseLoad ({ state, dispatch }) {
return new Promise(async resolve => {
// store 赋值
state.asideCollapse = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'menu.asideCollapse',
defaultValue: setting.menu.asideCollapse,
user: true
}, { root: true })
// end
resolve()
})
}
},
mutations: {
/**
* @description 设置顶栏菜单
@@ -29,50 +87,6 @@ export default {
asideSet (state, menu) {
// store 赋值
state.aside = menu
},
/**
* 设置侧边栏展开或者收缩
* @param {Object} state vuex state
* @param {Boolean} collapse is collapse
*/
asideCollapseSet (state, collapse) {
// store 赋值
state.asideCollapse = collapse
// 持久化
this.dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideCollapse',
value: state.asideCollapse,
user: true
})
},
/**
* 切换侧边栏展开和收缩
* @param {Object} state vuex state
*/
asideCollapseToggle (state) {
// store 赋值
state.asideCollapse = !state.asideCollapse
// 持久化
this.dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'menu.asideCollapse',
value: state.asideCollapse,
user: true
})
},
/**
* 从持久化数据读取侧边栏展开或者收缩
* @param {Object} state vuex state
*/
async asideCollapseLoad (state) {
// store 赋值
state.asideCollapse = await this.dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'menu.asideCollapse',
defaultValue: setting.menu.asideCollapse,
user: true
})
}
}
}
+203 -111
View File
@@ -1,3 +1,5 @@
import { remove, get } from 'lodash'
// 设置文件
import setting from '@/setting.js'
@@ -9,110 +11,25 @@ export default {
// 当前显示的多页面列表
opened: setting.page.opened,
// 当前页面
current: ''
},
getters: {
/**
* @description 从当前所有打开的多标签页里返回需要缓存的页面 name
* @param {*} state vuex state
*/
keepAlive (state) {
return state.opened.filter(item => {
if (item.meta) {
if (item.meta.notCache) {
return false
}
}
return true
}).map(e => e.name)
}
},
mutations: {
/**
* @class current
* @description 打开一个新的页面
* @param {Object} state vuex state
* @param {Object} param { name, params, query } 路由信息
*/
open (state, { name, params, query }) {
// 已经打开的页面
let opened = state.opened
// 判断此页面是否已经打开 并且记录位置
let pageOpendIndex = 0
const pageOpend = opened.find((page, index) => {
const same = page.name === name
pageOpendIndex = same ? index : pageOpendIndex
return same
})
if (pageOpend) {
// 页面以前打开过 但是新的页面可能 name 一样,参数不一样
this.commit('d2admin/page/openedUpdate', {
index: pageOpendIndex,
params,
query
})
} else {
// 页面以前没有打开过
let page = state.pool.find(t => t.name === name)
if (page) {
this.commit('d2admin/page/add', {
tag: page,
params,
query
})
}
}
this.commit('d2admin/page/currentSet', name)
},
/**
* @class current
* @description 设置当前激活的页面 name
* @param {Object} state vuex state
* @param {String} name new name
*/
currentSet (state, name) {
state.current = name
},
/**
* @class opened
* @description 更新页面列表上的某一项
* @param {Object} state vuex state
* @param {Object} param { index, params, query } 路由信息
*/
openedUpdate (state, { index, params, query }) {
// 更新页面列表某一项
let page = state.opened[index]
page.params = params || page.params
page.query = query || page.query
state.opened.splice(index, 1, page)
// 持久化
this.commit('d2admin/page/opend2db')
},
/**
* 将 opened 属性赋值并持久化 在这之前请先确保已经更新了 state.opened
* @param {Object} state vuex state
*/
opend2db (state) {
this.dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'page.opened',
value: state.opened,
user: true
})
current: '',
// 需要缓存的页面 name
keepAlive: []
},
actions: {
/**
* @class opened
* @description 从持久化数据载入分页列表
* @param {Object} state vuex state
*/
async openedLoad (state) {
openedLoad ({ state, commit, dispatch }) {
return new Promise(async resolve => {
// store 赋值
const value = await this.dispatch('d2admin/db/get', {
const value = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'page.opened',
defaultValue: setting.page.opened,
user: true
})
}, { root: true })
// 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签
// 以 name 字段为准
// 如果页面过多的话可能需要优化算法
@@ -133,6 +50,49 @@ export default {
// 新的数据中一般不会携带 params 和 query, 所以旧的参数会留存
return Object.assign({}, opened, find)
}).filter((opened, index) => valid[index] === 1)
// 根据 opened 数据生成缓存设置
commit('keepAliveRefresh')
// end
resolve()
})
},
/**
* 将 opened 属性赋值并持久化 在这之前请先确保已经更新了 state.opened
* @param {Object} state vuex state
*/
opend2db ({ state, dispatch }) {
return new Promise(async resolve => {
// 设置数据
dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'page.opened',
value: state.opened,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* @class opened
* @description 更新页面列表上的某一项
* @param {Object} state vuex state
* @param {Object} param { index, params, query } 路由信息
*/
openedUpdate ({ state, commit, dispatch }, { index, params, query }) {
return new Promise(async resolve => {
// 更新页面列表某一项
let page = state.opened[index]
page.params = params || page.params
page.query = query || page.query
state.opened.splice(index, 1, page)
// 增加缓存设置
commit('keepAlivePush', page.name)
// 持久化
await dispatch('opend2db')
// end
resolve()
})
},
/**
* @class opened
@@ -140,15 +100,63 @@ export default {
* @param {Object} state vuex state
* @param {Object} param new tag info
*/
add (state, { tag, params, query }) {
add ({ state, commit, dispatch }, { tag, params, query }) {
return new Promise(async resolve => {
// 设置新的 tag 在新打开一个以前没打开过的页面时使用
let newTag = tag
newTag.params = params || newTag.params
newTag.query = query || newTag.query
// 添加进当前显示的页面数组
state.opened.push(newTag)
// 如果这个页面需要缓存 将其添加到缓存设置
if (get(newTag, 'meta.requiresAuth', false)) {
commit('keepAlivePush', tag.name)
}
// 持久化
this.commit('d2admin/page/opend2db')
await dispatch('opend2db')
// end
resolve()
})
},
/**
* @class current
* @description 打开一个新的页面
* @param {Object} state vuex state
* @param {Object} param { name, params, query } 路由信息
*/
open ({ state, commit, dispatch }, { name, params, query }) {
return new Promise(async resolve => {
// 已经打开的页面
let opened = state.opened
// 判断此页面是否已经打开 并且记录位置
let pageOpendIndex = 0
const pageOpend = opened.find((page, index) => {
const same = page.name === name
pageOpendIndex = same ? index : pageOpendIndex
return same
})
if (pageOpend) {
// 页面以前打开过 但是新的页面可能 name 一样,参数不一样
await dispatch('openedUpdate', {
index: pageOpendIndex,
params,
query
})
} else {
// 页面以前没有打开过
let page = state.pool.find(t => t.name === name)
if (page) {
await dispatch('add', {
tag: page,
params,
query
})
}
}
commit('currentSet', name)
// end
resolve()
})
},
/**
* @class opened
@@ -156,7 +164,8 @@ export default {
* @param {Object} state vuex state
* @param {Object} param { tagName: 要关闭的标签名字, vm: vue }
*/
close (state, { tagName, vm }) {
close ({ state, commit, dispatch }, { tagName, vm }) {
return new Promise(async resolve => {
// 下个新的页面
let newPage = state.opened[0]
const isCurrent = state.current === tagName
@@ -178,10 +187,13 @@ export default {
// 找到这个页面在已经打开的数据里是第几个
const index = state.opened.findIndex(page => page.name === tagName)
if (index >= 0) {
// 更新数据 删除关闭的页面
state.opened.splice(index, 1)
// 如果这个页面是缓存的页面 将其在缓存设置中删除
commit('keepAliveRemove', tagName)
}
// 持久化
this.commit('d2admin/page/opend2db')
await dispatch('opend2db')
// 最后需要判断是否需要跳到首页
if (isCurrent) {
const { name = '', params = {}, query = {} } = newPage
@@ -192,6 +204,9 @@ export default {
}
vm.$router.push(routerObj)
}
// end
resolve()
})
},
/**
* @class opened
@@ -199,7 +214,8 @@ export default {
* @param {Object} state vuex state
* @param {Object} param { pageSelect: 当前选中的tagName, vm: vue }
*/
closeLeft (state, { pageSelect, vm } = {}) {
closeLeft ({ state, commit, dispatch }, { pageSelect, vm } = {}) {
return new Promise(async resolve => {
const pageAim = pageSelect || state.current
let currentIndex = 0
state.opened.forEach((page, index) => {
@@ -208,7 +224,8 @@ export default {
}
})
if (currentIndex > 0) {
state.opened.splice(1, currentIndex - 1)
// 删除打开的页面 并在缓存设置中删除
state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name))
}
state.current = pageAim
if (vm && vm.$route.name !== pageAim) {
@@ -217,7 +234,10 @@ export default {
})
}
// 持久化
this.commit('d2admin/page/opend2db')
await dispatch('opend2db')
// end
resolve()
})
},
/**
* @class opened
@@ -225,7 +245,8 @@ export default {
* @param {Object} state vuex state
* @param {Object} param { pageSelect: 当前选中的tagName, vm: vue }
*/
closeRight (state, { pageSelect, vm } = {}) {
closeRight ({ state, commit, dispatch }, { pageSelect, vm } = {}) {
return new Promise(async resolve => {
const pageAim = pageSelect || state.current
let currentIndex = 0
state.opened.forEach((page, index) => {
@@ -233,7 +254,9 @@ export default {
currentIndex = index
}
})
state.opened.splice(currentIndex + 1)
// 删除打开的页面 并在缓存设置中删除
state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name))
// 设置当前的页面
state.current = pageAim
if (vm && vm.$route.name !== pageAim) {
vm.$router.push({
@@ -241,7 +264,10 @@ export default {
})
}
// 持久化
this.commit('d2admin/page/opend2db')
await dispatch('opend2db')
// end
resolve()
})
},
/**
* @class opened
@@ -249,7 +275,8 @@ export default {
* @param {Object} state vuex state
* @param {Object} param { pageSelect: 当前选中的tagName, vm: vue }
*/
closeOther (state, { pageSelect, vm } = {}) {
closeOther ({ state, commit, dispatch }, { pageSelect, vm } = {}) {
return new Promise(async resolve => {
const pageAim = pageSelect || state.current
let currentIndex = 0
state.opened.forEach((page, index) => {
@@ -257,12 +284,14 @@ export default {
currentIndex = index
}
})
// 删除打开的页面数据 并更新缓存设置
if (currentIndex === 0) {
state.opened.splice(1)
state.opened.splice(1).forEach(({ name }) => commit('keepAliveRemove', name))
} else {
state.opened.splice(currentIndex + 1)
state.opened.splice(1, currentIndex - 1)
state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name))
state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name))
}
// 设置新的页面
state.current = pageAim
if (vm && vm.$route.name !== pageAim) {
vm.$router.push({
@@ -270,7 +299,10 @@ export default {
})
}
// 持久化
this.commit('d2admin/page/opend2db')
await dispatch('opend2db')
// end
resolve()
})
},
/**
* @class opened
@@ -278,16 +310,74 @@ export default {
* @param {Object} state vuex state
* @param {Object} vm vue
*/
closeAll (state, vm) {
state.opened.splice(1)
closeAll ({ state, commit, dispatch }, vm) {
return new Promise(async resolve => {
// 删除打开的页面 并在缓存设置中删除
state.opened.splice(1).forEach(({ name }) => commit('keepAliveRemove', name))
// 持久化
this.commit('d2admin/page/opend2db')
await dispatch('opend2db')
// 关闭所有的标签页后需要判断一次现在是不是在首页
if (vm.$route.name !== 'index') {
vm.$router.push({
name: 'index'
})
}
// end
resolve()
})
}
},
mutations: {
/**
* @class keepAlive
* @description 从已经打开的页面记录中更新需要缓存的页面记录
* @param {Object} state vuex state
*/
keepAliveRefresh (state) {
state.keepAlive = state.opened.filter(item => {
if (item.meta) {
if (item.meta.notCache) {
return false
}
}
return true
}).map(e => e.name)
},
/**
* @description 删除一个页面的缓存设置
* @param {Object} state vuex state
* @param {String} name name
*/
keepAliveRemove (state, name) {
const list = [ ...state.keepAlive ]
remove(list, item => item === name)
state.keepAlive = list
},
/**
* @description 增加一个页面的缓存设置
* @param {Object} state vuex state
* @param {String} name name
*/
keepAlivePush (state, name) {
const keep = [ ...state.keepAlive ]
keep.push(name)
state.keepAlive = Array.from(new Set(keep))
},
/**
* @description 清空页面缓存设置
* @param {Object} state vuex state
*/
keepAliveClean (state) {
state.keepAlive = []
},
/**
* @class current
* @description 设置当前激活的页面 name
* @param {Object} state vuex state
* @param {String} name new name
*/
currentSet (state, name) {
state.current = name
},
/**
* @class pool
@@ -302,9 +392,11 @@ export default {
if (route.children) {
push(route.children)
} else {
if (!route.hidden) {
const { meta, name, path } = route
pool.push({ meta, name, path })
}
}
})
}
push(routes)
+46
View File
@@ -0,0 +1,46 @@
export default {
namespaced: true,
state: {
// 尺寸
value: '' // medium small mini
},
actions: {
/**
* @description 设置尺寸
* @param {Object} state vuex state
* @param {String} size 尺寸
*/
set ({ state, dispatch }, size) {
return new Promise(async resolve => {
// store 赋值
state.value = size
// 持久化
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'size.value',
value: state.value,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* @description 从持久化数据读取尺寸设置
* @param {Object} state vuex state
*/
load ({ state, dispatch }) {
return new Promise(async resolve => {
// store 赋值
state.value = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'size.value',
defaultValue: 'default',
user: true
}, { root: true })
// end
resolve()
})
}
}
}
+18 -8
View File
@@ -18,40 +18,50 @@ export default {
return state.list.find(theme => theme.name === state.activeName)
}
},
mutations: {
actions: {
/**
* @description 激活一个主题
* @param {Object} state vuex state
* @param {String} themeValue 需要激活的主题名称
*/
set (state, themeName) {
set ({ state, commit, dispatch }, themeName) {
return new Promise(async resolve => {
// 检查这个主题在主题列表里是否存在
state.activeName = state.list.find(e => e.name === themeName) ? themeName : state.list[0].name
// 将 vuex 中的主题应用到 dom
this.commit('d2admin/theme/dom')
commit('dom')
// 持久化
this.dispatch('d2admin/db/set', {
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'theme.activeName',
value: state.activeName,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* @description 从持久化数据加载主题设置
* @param {Object} state vuex state
*/
async load (state) {
load ({ state, commit, dispatch }) {
return new Promise(async resolve => {
// store 赋值
state.activeName = await this.dispatch('d2admin/db/get', {
state.activeName = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'theme.activeName',
defaultValue: state.list[0].name,
user: true
}, { root: true })
// 将 vuex 中的主题应用到 dom
commit('dom')
// end
resolve()
})
// 更新到页面
this.commit('d2admin/theme/dom')
}
},
mutations: {
/**
* @description 将 vuex 中的主题应用到 dom
* @param {Object} state vuex state
@@ -7,34 +7,42 @@ export default {
// 是否开启页面过度动画
active: setting.transition.active
},
mutations: {
actions: {
/**
* @description 设置开启状态
* @param {Object} state vuex state
* @param {Boolean} active 新的状态
*/
set (state, active) {
set ({ state, dispatch }, active) {
return new Promise(async resolve => {
// store 赋值
state.active = active
// 持久化
this.dispatch('d2admin/db/set', {
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'transition.active',
value: state.active,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* 从数据库读取页面过渡动画设置
* @param {Object} state vuex state
*/
async load (state) {
load ({ state, dispatch }) {
return new Promise(async resolve => {
// store 赋值
state.active = await this.dispatch('d2admin/db/get', {
state.active = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'transition.active',
defaultValue: setting.transition.active,
user: true
}, { root: true })
// end
resolve()
})
}
}
+13 -5
View File
@@ -7,34 +7,42 @@ export default {
// 用户信息
info: setting.user.info
},
mutations: {
actions: {
/**
* @description 设置用户数据
* @param {Object} state vuex state
* @param {*} info info
*/
set (state, info) {
set ({ state, dispatch }, info) {
return new Promise(async resolve => {
// store 赋值
state.info = info
// 持久化
this.dispatch('d2admin/db/set', {
await dispatch('d2admin/db/set', {
dbName: 'sys',
path: 'user.info',
value: info,
user: true
}, { root: true })
// end
resolve()
})
},
/**
* @description 从数据库取用户数据
* @param {Object} state vuex state
*/
async load (state) {
load ({ state, dispatch }) {
return new Promise(async resolve => {
// store 赋值
state.info = await this.dispatch('d2admin/db/get', {
state.info = await dispatch('d2admin/db/get', {
dbName: 'sys',
path: 'user.info',
defaultValue: setting.user.info,
user: true
}, { root: true })
// end
resolve()
})
}
}
+6 -2
View File
@@ -6,7 +6,9 @@ function resolve (dir) {
}
// 基础路径 注意发布之前要先修改这里
const baseUrl = '/d2-admin-start-kit/'
let baseUrl = '/'
// 演示项目自动构建使用
if (process.env.VUE_APP_TRAVIS === 'TRUE') baseUrl = '/d2-admin-start-kit/'
module.exports = {
baseUrl: baseUrl, // 根据你的实际情况更改这里
@@ -14,9 +16,11 @@ module.exports = {
devServer: {
publicPath: baseUrl // 和 baseUrl 保持一致
},
// webpack 设置
// 默认设置: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js
chainWebpack: config => {
// 解决 cli3 热更新失效 https://github.com/vuejs/vue-cli/issues/1559
config.resolve
.symlinks(true)
// markdown
config.module
.rule('md')
-9394
View File
File diff suppressed because it is too large Load Diff