底层架构优化

pull/59/head
smallchill 7 years ago
parent 9c2d8504be
commit 3dc3cb6481
  1. 21
      src/components/basic-container/main.vue
  2. 216
      src/components/iframe/main.vue
  3. 1
      src/lang/en.js
  4. 1
      src/lang/zh.js
  5. 53
      src/page/index/sidebar/index.vue
  6. 158
      src/page/index/sidebar/sidebarItem.vue
  7. 5
      src/page/index/tags.vue
  8. 59
      src/page/index/top/top-lang.vue
  9. 104
      src/page/index/top/top-menu.vue
  10. 5
      src/page/index/top/top-search.vue
  11. 2
      src/permission.js
  12. 3
      src/router/avue-router.js
  13. 1
      src/store/getters.js
  14. 4
      src/store/modules/common.js
  15. 3
      src/styles/media.scss
  16. 4
      vue.config.js

@ -1,5 +1,6 @@
<template>
<div class="basic-container">
<div class="basic-container"
:class="{'basic-container--block':block}">
<el-card>
<slot></slot>
</el-card>
@ -7,9 +8,15 @@
</template>
<script>
export default {
name: "basicContainer"
};
export default {
name: "basicContainer",
props: {
block: {
type: Boolean,
default: false
}
}
};
</script>
<style lang="scss">
@ -17,6 +24,12 @@ export default {
padding: 10px 6px;
border-radius: 10px;
box-sizing: border-box;
&--block {
height: 100%;
.el-card {
height: 100%;
}
}
.el-card {
width: 100%;
}

@ -7,123 +7,123 @@
</template>
<script>
import { mapGetters } from "vuex";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
export default {
name: "AvueIframe",
data() {
return {
urlPath: this.getUrlPath() //iframe src
};
},
created() {
NProgress.configure({ showSpinner: false });
},
mounted() {
this.load();
this.resize();
},
props: ["routerPath"],
watch: {
$route: function() {
this.load();
},
routerPath: function() {
// routerPathsrc
this.urlPath = this.getUrlPath();
}
},
computed: {
...mapGetters(["screen"]),
src() {
return this.$route.query.src
? this.$route.query.src.replace("$", "#")
: this.urlPath;
}
},
methods: {
//
show() {
NProgress.start();
import {mapGetters} from "vuex";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
export default {
name: "AvueIframe",
data() {
return {
urlPath: this.getUrlPath() //iframe src
};
},
//
hide() {
NProgress.done();
created() {
NProgress.configure({showSpinner: false});
},
//
resize() {
window.onresize = () => {
this.iframeInit();
};
mounted() {
this.load();
this.resize();
},
//
load() {
this.show();
var flag = true; //URL
if (this.$route.query.src.indexOf("?") == -1) {
flag = false;
}
var list = [];
for (var key in this.$route.query) {
if (key != "src" && key != "name" && key != "i18n") {
list.push(`${key}= this.$route.query[key]`);
}
props: ["routerPath"],
watch: {
$route: function () {
this.load();
},
routerPath: function () {
// routerPathsrc
this.urlPath = this.getUrlPath();
}
list = list.join("&").toString();
if (flag) {
this.$route.query.src = `${this.$route.query.src}${
list.length > 0 ? `&list` : ""
}`;
} else {
this.$route.query.src = `${this.$route.query.src}${
list.length > 0 ? `?list` : ""
}`;
},
computed: {
...mapGetters(["screen"]),
src() {
return this.$route.query.src
? this.$route.query.src.replace("$", "#")
: this.urlPath;
}
//3s
let time = 3;
const timeFunc = setInterval(() => {
time--;
if (time == 0) {
this.hide();
clearInterval(timeFunc);
}
}, 1000);
this.iframeInit();
},
//iframe
iframeInit() {
const iframe = this.$refs.iframe;
const clientHeight =
document.documentElement.clientHeight - (screen > 1 ? 200 : 130);
if (!iframe) return;
iframe.style.height = `${clientHeight}px`;
if (iframe.attachEvent) {
iframe.attachEvent("onload", () => {
this.hide();
});
} else {
iframe.onload = () => {
this.hide();
methods: {
//
show() {
NProgress.start();
},
//
hide() {
NProgress.done();
},
//
resize() {
window.onresize = () => {
this.iframeInit();
};
},
//
load() {
this.show();
var flag = true; //URL
if (this.$route.query.src.indexOf("?") == -1) {
flag = false;
}
var list = [];
for (var key in this.$route.query) {
if (key != "src" && key != "name" && key != "i18n") {
list.push(`${key}= this.$route.query[key]`);
}
}
list = list.join("&").toString();
if (flag) {
this.$route.query.src = `${this.$route.query.src}${
list.length > 0 ? `&list` : ""
}`;
} else {
this.$route.query.src = `${this.$route.query.src}${
list.length > 0 ? `?list` : ""
}`;
}
//3s
let time = 3;
const timeFunc = setInterval(() => {
time--;
if (time == 0) {
this.hide();
clearInterval(timeFunc);
}
}, 1000);
this.iframeInit();
},
//iframe
iframeInit() {
const iframe = this.$refs.iframe;
const clientHeight =
document.documentElement.clientHeight - (screen > 1 ? 200 : 130);
if (!iframe) return;
iframe.style.height = `${clientHeight}px`;
if (iframe.attachEvent) {
iframe.attachEvent("onload", () => {
this.hide();
});
} else {
iframe.onload = () => {
this.hide();
};
}
},
getUrlPath: function () {
// iframe src
let url = window.location.href;
url = url.replace("/myiframe", "");
return url;
}
},
getUrlPath: function() {
// iframe src
let url = window.location.href;
url = url.replace("/myiframe", "");
return url;
}
}
};
};
</script>
<style lang="scss">
.iframe {
width: 100%;
height: 100%;
border: 0;
overflow: hidden;
box-sizing: border-box;
}
</style>
.iframe {
width: 100%;
height: 100%;
border: 0;
overflow: hidden;
box-sizing: border-box;
}
</style>

@ -96,6 +96,7 @@ export default {
color: 'color'
},
tagsView: {
search: 'Search',
menu: 'menu',
closeOthers: 'Close Others',
closeAll: 'Close All'

@ -95,6 +95,7 @@ export default {
color: '换色'
},
tagsView: {
search: '搜索',
menu: '更多',
closeOthers: '关闭其它',
closeAll: '关闭所有'

@ -3,7 +3,8 @@
<logo></logo>
<el-scrollbar style="height:100%">
<div v-if="validatenull(menu)"
class="avue-sidebar--tip">{{$t('menuTip')}}</div>
class="avue-sidebar--tip">{{$t('menuTip')}}
</div>
<el-menu unique-opened
:default-active="nowTagValue"
mode="vertical"
@ -20,30 +21,32 @@
</template>
<script>
import { mapGetters } from "vuex";
import logo from "../logo";
import sidebarItem from "./sidebarItem";
export default {
name: "sidebar",
components: { sidebarItem, logo },
data() {
return {};
},
created() {
this.$store.dispatch("GetMenu").then(data => {
if (data.length === 0) return;
this.$router.$avueRouter.formatRoutes(data, true);
});
},
computed: {
...mapGetters(["website", "menu", "tag", "keyCollapse", "screen"]),
nowTagValue: function() {
return this.$router.$avueRouter.getValue(this.$route);
}
},
mounted() {},
methods: {}
};
import {mapGetters} from "vuex";
import logo from "../logo";
import sidebarItem from "./sidebarItem";
export default {
name: "sidebar",
components: {sidebarItem, logo},
data() {
return {};
},
created() {
this.$store.dispatch("GetMenu").then(data => {
if (data.length === 0) return;
this.$router.$avueRouter.formatRoutes(data, true);
});
},
computed: {
...mapGetters(["website", "menu", "tag", "keyCollapse", "screen"]),
nowTagValue: function () {
return this.$router.$avueRouter.getValue(this.$route);
}
},
mounted() {
},
methods: {}
};
</script>
<style lang="scss" scoped>
</style>

@ -39,91 +39,93 @@
</div>
</template>
<script>
import { mapGetters } from "vuex";
import { validatenull } from "@/util/validate";
import config from "./config.js";
export default {
name: "sidebarItem",
data() {
return {
config: config
};
},
props: {
menu: {
type: Array
},
screen: {
type: Number
},
first: {
type: Boolean,
default: false
import {mapGetters} from "vuex";
import {validatenull} from "@/util/validate";
import config from "./config.js";
export default {
name: "sidebarItem",
data() {
return {
config: config
};
},
props: {
type: Object,
default: () => {
return {};
menu: {
type: Array
},
screen: {
type: Number
},
first: {
type: Boolean,
default: false
},
props: {
type: Object,
default: () => {
return {};
}
},
collapse: {
type: Boolean
}
},
collapse: {
type: Boolean
}
},
created() {},
mounted() {},
computed: {
...mapGetters(["roles"]),
labelKey() {
return this.props.label || this.config.propsDefault.label;
},
pathKey() {
return this.props.path || this.config.propsDefault.path;
},
iconKey() {
return this.props.icon || this.config.propsDefault.icon;
created() {
},
childrenKey() {
return this.props.children || this.config.propsDefault.children;
mounted() {
},
nowTagValue() {
return this.$router.$avueRouter.getValue(this.$route);
}
},
methods: {
generateTitle(item) {
return this.$router.$avueRouter.generateTitle(
item[this.labelKey],
(item.meta || {}).i18n
);
},
vaildAvtive(item) {
const groupFlag = (item["group"] || []).some(ele =>
this.$route.path.includes(ele)
);
return this.nowTagValue === item[this.pathKey] || groupFlag;
},
vaildRoles(item) {
item.meta = item.meta || {};
return item.meta.roles ? item.meta.roles.includes(this.roles) : true;
},
validatenull(val) {
return validatenull(val);
computed: {
...mapGetters(["roles"]),
labelKey() {
return this.props.label || this.config.propsDefault.label;
},
pathKey() {
return this.props.path || this.config.propsDefault.path;
},
iconKey() {
return this.props.icon || this.config.propsDefault.icon;
},
childrenKey() {
return this.props.children || this.config.propsDefault.children;
},
nowTagValue() {
return this.$router.$avueRouter.getValue(this.$route);
}
},
open(item) {
if (this.screen <= 1) this.$store.commit("SET_COLLAPSE");
this.$router.$avueRouter.group = item.group;
this.$router.$avueRouter.meta = item.meta;
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: item[this.labelKey],
src: item[this.pathKey],
i18n: (item.meta || {}).i18n
}),
query: item.query
});
methods: {
generateTitle(item) {
return this.$router.$avueRouter.generateTitle(
item[this.labelKey],
(item.meta || {}).i18n
);
},
vaildAvtive(item) {
const groupFlag = (item["group"] || []).some(ele =>
this.$route.path.includes(ele)
);
return this.nowTagValue === item[this.pathKey] || groupFlag;
},
vaildRoles(item) {
item.meta = item.meta || {};
return item.meta.roles ? item.meta.roles.includes(this.roles) : true;
},
validatenull(val) {
return validatenull(val);
},
open (item) {
if (this.screen <= 1) this.$store.commit("SET_COLLAPSE");
this.$router.$avueRouter.group = item.group;
this.$router.$avueRouter.meta = item.meta;
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: item[this.labelKey],
src: item[this.pathKey]
}, item.meta),
query: item.query
});
}
}
}
};
};
</script>

@ -133,9 +133,8 @@
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: tag.label,
src: tag.value,
i18n: tag.meta.i18n
}),
src: tag.value
}, tag.meta),
query: tag.query
});
},

@ -4,40 +4,45 @@
<i class="icon-zhongyingwen"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :disabled="language==='zh'"
command="zh">中文</el-dropdown-item>
command="zh">中文
</el-dropdown-item>
<el-dropdown-item :disabled="language==='en'"
command="en">English</el-dropdown-item>
command="en">English
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "top-lang",
data() {
return {};
},
created() {},
mounted() {},
computed: {
...mapGetters(["language", "tag"])
},
props: [],
methods: {
handleSetLanguage(lang) {
this.$i18n.locale = lang;
this.$store.commit("SET_LANGUAGE", lang);
let tag = this.tag;
let title = this.$router.$avueRouter.generateTitle(
tag.label,
(tag.meta || {}).i18n
);
//label
this.$router.$avueRouter.setTitle(title);
import {mapGetters} from "vuex";
export default {
name: "top-lang",
data() {
return {};
},
created() {
},
mounted() {
},
computed: {
...mapGetters(["language", "tag"])
},
props: [],
methods: {
handleSetLanguage(lang) {
this.$i18n.locale = lang;
this.$store.commit("SET_LANGUAGE", lang);
let tag = this.tag;
let title = this.$router.$avueRouter.generateTitle(
tag.label,
(tag.meta || {}).i18n
);
//label
this.$router.$avueRouter.setTitle(title);
}
}
}
};
};
</script>
<style lang="scss" scoped>

@ -26,62 +26,62 @@
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "top-menu",
data() {
return {
itemHome: {
name: '首页',
source: 'el-icon-menu',
},
activeIndex: "0",
items: [],
};
},
created() {
this.getMenu();
},
computed: {
...mapGetters(["tagCurrent", "menu"])
},
methods: {
getMenu() {
this.$store.dispatch("GetTopMenu").then(res => {
this.items = res;
});
import {mapGetters} from "vuex";
export default {
name: "top-menu",
data() {
return {
itemHome: {
name: '首页',
source: 'el-icon-menu',
},
activeIndex: "0",
items: [],
};
},
generateTitle(item) {
return this.$router.$avueRouter.generateTitle(
item.name,
(item.meta || {}).i18n
);
created() {
this.getMenu();
},
openMenu(item) {
this.$store.dispatch("GetMenu", item.id).then(data => {
if (data.length !== 0) {
this.$router.$avueRouter.formatRoutes(data, true);
}
let itemActive,
childItemActive = 0;
if (item.path) {
itemActive = item;
} else {
if (this.menu[childItemActive].length == 0) {
itemActive = this.menu[childItemActive];
computed: {
...mapGetters(["tagCurrent", "menu"])
},
methods: {
getMenu() {
this.$store.dispatch("GetTopMenu").then(res => {
this.items = res;
});
},
generateTitle(item) {
return this.$router.$avueRouter.generateTitle(
item.name,
(item.meta || {}).i18n
);
},
openMenu(item) {
this.$store.dispatch("GetMenu", item.id).then(data => {
if (data.length !== 0) {
this.$router.$avueRouter.formatRoutes(data, true);
}
let itemActive,
childItemActive = 0;
if (item.path) {
itemActive = item;
} else {
itemActive = this.menu[childItemActive].children[childItemActive];
if (this.menu[childItemActive].length == 0) {
itemActive = this.menu[childItemActive];
} else {
itemActive = this.menu[childItemActive].children[childItemActive];
}
}
}
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: itemActive.label,
src: itemActive.path,
i18n: itemActive.meta.i18n
})
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: itemActive.label,
src: itemActive.path
}, itemActive.meta)
});
});
});
}
}
}
};
};
</script>

@ -88,9 +88,8 @@
this.$router.push({
path: this.$router.$avueRouter.getPath({
name: item[this.labelKey],
src: item[this.pathKey],
i18n: (item.meta || {}).i18n
}),
src: item[this.pathKey]
}, item.meta),
query: item.query
});
}

@ -12,6 +12,8 @@ NProgress.configure({showSpinner: false});
const lockPage = store.getters.website.lockPage; //锁屏页
router.beforeEach((to, from, next) => {
const meta = to.meta || {};
const isMenu = meta.menu === undefined ? to.query.menu : meta.menu;
store.commit('SET_IS_MENU', isMenu === undefined);
if (getToken()) {
if (store.getters.isLock && to.path != lockPage) { //如果系统激活锁屏,全部跳转到锁屏页
next({path: lockPage})

@ -9,6 +9,7 @@ RouterPlugin.install = function (vue, router, store, i18n) {
this.$vue = new vue({i18n});
function isURL(s) {
if (s.includes('html')) return true;
return /^http[s]?:\/\/.*/.test(s)
}
@ -55,7 +56,7 @@ RouterPlugin.install = function (vue, router, store, i18n) {
getPath: function (params) {
let {src} = params;
let result = src || '/';
if (src.includes("http") || src.includes("https")) {
if (isURL(src)) {
result = `/myiframe/urlPath?${objToform(params)}`;
}
return result;

@ -11,6 +11,7 @@ const getters = {
screen: state => state.common.screen,
isLock: state => state.common.isLock,
isFullScren: state => state.common.isFullScren,
isMenu: state => state.common.isMenu,
lockPasswd: state => state.common.lockPasswd,
tagList: state => state.tags.tagList,
tagWel: state => state.tags.tagWel,

@ -11,6 +11,7 @@ const common = {
language: getStore({name: 'language'}) || 'zh',
isCollapse: false,
isFullScren: false,
isMenu: true,
isShade: false,
screen: -1,
isLock: getStore({name: 'isLock'}) || false,
@ -45,6 +46,9 @@ const common = {
SET_FULLSCREN: (state) => {
state.isFullScren = !state.isFullScren;
},
SET_IS_MENU: (state, menu) => {
state.isMenu = menu;
},
SET_LOCK: (state) => {
state.isLock = true;
setStore({

@ -58,6 +58,7 @@
height: calc(100% - 64px);
box-sizing: border-box;
overflow: hidden;
transition: all 0.5s;
background: #f0f2f5;
z-index: 1026;
@ -68,7 +69,7 @@
}
.avue-view {
padding: 10px !important;
padding: 0 10px !important;
width: 100%;
box-sizing: border-box;
}

@ -26,9 +26,9 @@ module.exports = {
proxy: {
'/api': {
//本地服务接口地址
//target: 'http://localhost',
target: 'http://localhost',
//远程演示服务地址
target: 'https://saber.bladex.vip/api',
//target: 'https://saber.bladex.vip/api',
ws: true,
pathRewrite: {
'^/api': '/'

Loading…
Cancel
Save