底层架构优化

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save