加入vue-router、element-ui、完成导航栏

pull/1/head
soul2 3 years ago
parent 1db45a5dee
commit 66d15b5283
  1. 14
      .editorconfig
  2. 7
      .env.development
  3. 1
      .gitignore
  4. 6
      package.json
  5. 20
      src/App.vue
  6. 18
      src/layout/components/AppMain.vue
  7. 17
      src/layout/components/background/index.vue
  8. 33
      src/layout/components/footer.vue
  9. 131
      src/layout/components/navbar/index.vue
  10. 41
      src/layout/index.vue
  11. 17
      src/main.js
  12. 19
      src/router/beforce.js
  13. 73
      src/router/index.js
  14. 8
      src/settings.js
  15. 2
      src/store/getters.js
  16. 7
      src/store/index.js
  17. 16
      src/store/modules/menu.js
  18. 80
      src/style/index.scss
  19. 3
      src/style/layout/footer.scss
  20. 23
      src/style/layout/variables.scss
  21. 48
      src/style/transition.scss
  22. 10
      src/utils/get-page-title.js
  23. 17
      src/views/home/index.vue
  24. 19
      src/views/sodemo/index.vue
  25. 31
      src/views/soui/index.vue
  26. 46
      vue.config.js

@ -0,0 +1,14 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

@ -0,0 +1,7 @@
ENV = 'development'
# 上下文
VUE_APP_CONTEXT_PATH = '/'
# 接口地址
VUE_APP_BASE_API = 'http://localhost:7330'

1
.gitignore vendored

@ -2,3 +2,4 @@
package-lock.json
/public/
/.idea/
/dist/

@ -13,6 +13,9 @@
"element-ui": "^2.15.6",
"js-cookie": "^2.2.0",
"nprogress": "^0.2.0",
"sass-loader": "^10.0.5",
"node-sass": "^7.0.3",
"normalize.css": "7.0.0",
"vue": "^2.6.11",
"vue-router": "^3.5.2",
"vuex": "^3.6.2"
@ -24,7 +27,8 @@
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11"
"vue-template-compiler": "^2.6.11",
"path-to-regexp": "^6.2.0"
},
"eslintConfig": {
"root": true,

@ -1,6 +1,6 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
@ -13,12 +13,14 @@ export default {
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
/*#app {*/
/* font-family: Avenir, Helvetica, Arial, sans-serif;*/
/* -webkit-font-smoothing: antialiased;*/
/* -moz-osx-font-smoothing: grayscale;*/
/* text-align: center;*/
/* color: #2c3e50;*/
/* height: 100%;*/
/* width: 100%;*/
/* !*margin-top: 60px;*!*/
/*}*/
</style>

@ -0,0 +1,18 @@
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<router-view :key="key"/>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
key() {
return this.$route.path
}
}
}
</script>

@ -0,0 +1,17 @@
<template>
<div id="background"></div>
</template>
<script>
// todo
export default {
name: "Background"
}
</script>
<style scoped lang="scss">
#background {
height: 100%;
width: 100%;
}
</style>

@ -0,0 +1,33 @@
<template>
<div id="app-footer">
<a class="record-number" href="http://beian.miit.gov.cn/">粤ICP备2020098994号</a>
</div>
</template>
<script>
export default {
name: "AppFooter"
}
</script>
<style scoped lang="scss">
@import "~@/style/layout/footer.scss";
#app-footer {
position: absolute;
bottom: 20px;
left: 0;
width: 100%;
}
.record-number {
color: #000;
border-bottom: none;
text-decoration: none;
}
.record-number:hover {
border-bottom: #{$recordNumberHover} 1px solid;
color: #{$recordNumberHover};
}
</style>

@ -0,0 +1,131 @@
<template>
<div id="navbar">
<el-menu
:default-active="activeMenu"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:active-text-color="variables.menuActiveText"
:unique-opened="false"
:collapse-transition="false"
mode="horizontal"
:router="true"
:style="menuStyle"
>
<el-col :xs="menuItemSize.xs" :sm="menuItemSize.sm" :md="menuItemSize.md" :lg="menuItemSize.lg"
:xl="menuItemSize.xl"
v-for="(route, i) in routes" :key="i">
<el-menu-item v-if="route.children.length === 1" :index="to(route.children[0])">
{{ title(route.children[0]) }}
</el-menu-item>
<el-submenu v-else-if="route.children.length > 1" :index="route.path">
<template slot="title">{{ route.meta.title || title(route.children[0]) }}</template>
<el-menu-item v-for="(child) in route.children" :key="child.path" :index="to(child)">
{{ child.meta.title }}
</el-menu-item>
</el-submenu>
</el-col>
</el-menu>
</div>
</template>
<script>
import variables from '@/style/layout/variables.scss'
import {mapGetters} from "vuex";
export default {
name: "Navbar",
components: {},
data() {
return {
screenWidth: document.body.clientWidth
}
},
computed: {
...mapGetters([
'routes'
]),
menuItemSize() {
return {
xs: 6,
sm: 5,
md: 4,
lg: 3,
xl: 1
}
},
menuStyle() {
if (this.screenWidth >= 600) {
return {
paddingLeft: '15%',
paddingRight: '15%'
}
} else {
return {}
}
},
activeMenu() {
const route = this.$route
const {meta, path} = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
variables() {
return variables
},
},
mounted() {
window.onresize = () => {
this.screenWidth = document.body.clientWidth
}
// console.log('routes -> ', this.routes)
},
watch: {
screenWidth(newValue) {
// resize使
if (!this.timer) {
// screenWidthdatascreenWidth
this.screenWidth = newValue;
this.timer = true;
setTimeout(() => {
//console.log(this.screenWidth);
this.timer = false;
}, 400);
}
}
},
methods: {
title(route) {
return route.meta.title
},
to(route) {
return route.path
}
},
}
</script>
<style scoped lang="scss">
@import "~@/style/layout/variables.scss";
#navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 9;
}
.is-active {
border-bottom: #{$subMenuActiveText} 3px solid;
}
.el-menu-item {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style>

@ -0,0 +1,41 @@
<template>
<div id="layout">
<el-container>
<el-header>
<navbar/>
</el-header>
<el-main>
<el-scrollbar>
<app-main/>
</el-scrollbar>
</el-main>
<el-footer>
<app-footer/>
</el-footer>
</el-container>
</div>
</template>
<script>
import AppMain from "@/layout/components/AppMain";
import Navbar from "@/layout/components/navbar";
import AppFooter from "@/layout/components/footer";
export default {
name: "Layout",
components: {Navbar, AppMain, AppFooter}
}
</script>
<style scoped lang="scss">
#layout {
width: 100%;
height: 100%;
box-sizing: border-box;
}
el-container {
height: 100%;
padding-top: 0;
}
</style>

@ -1,12 +1,17 @@
import Vue from 'vue'
import App from './App.vue'
import store from "@/store";
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import router from './router'
import '@/style/index.scss' // 全局样式
import '@/router/beforce'
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
el: '#app',
render: h => h(App),
store
}).$mount('#app')
el: '#app',
render: h => h(App),
router,
store
})

@ -0,0 +1,19 @@
import router from './index'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import getPageTitle from '@/utils/get-page-title'
router.beforeEach(async (to, from, next) => {
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
next()
})
router.afterEach(() => {
// finish progress bar
NProgress.done()
})

@ -0,0 +1,73 @@
import Vue from "vue";
import VueRouter from "vue-router";
import Layout from "@/layout";
Vue.use(VueRouter)
export const routes = [
{
path: '',
component: Layout,
children: [{
path: '/',
name: 'Home',
component: () => import('@/views/home/index'),
meta: {title: '首页', icon: 'dashboard'}
}]
},
{
path: '',
component: Layout,
children: [{
path: '/soui',
name: 'SoUI',
component: () => import('@/views/soui/index'),
meta: {title: 'SoUI', icon: 'dashboard'}
}]
},
{
path: '',
component: Layout,
children: [{
path: '/demo',
name: 'SoDemo',
component: () => import('@/views/sodemo/index'),
meta: {title: '灵魂演示', icon: 'dashboard'}
}]
},
// {
// path: '',
// component: Layout,
// meta: {title: '多菜单测试', icon: 'dashboard'},
// children: [{
// path: '/a',
// name: 'a',
// component: () => import('@/views/sodemo/index'),
// meta: {title: '菜单1', icon: 'dashboard'}
// },{
// path: '/b',
// name: 'b',
// component: () => import('@/views/sodemo/index'),
// meta: {title: '菜单2', icon: 'dashboard'}
// }]
// },
]
const createRouter = () => new VueRouter({
base: process.env.VUE_APP_CONTEXT_PATH || '/',
mode: 'history', // require service support
scrollBehavior: () => ({y: 0}),
routes: routes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router

@ -0,0 +1,8 @@
module.exports = {
title: 'soul2',
// 启动时自动打开url
autoOpenBrowser: false
}

@ -1,5 +1,5 @@
const getters = {
routes: state => state.routes
routes: state => state.menu.routes
}
export default getters

@ -1,12 +1,15 @@
import Vue from 'vue'
import Vuex from 'vuex'
import getters from "@/store/getters";
import menu from "@/store/modules/menu"
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {},
getters
modules: {
menu
},
getters
})
export default store

@ -0,0 +1,16 @@
import {routes} from '@/router'
const state = {
routes
}
const mutations = {}
const actions = {}
export default {
namespaced: true,
state,
mutations,
actions
}

@ -0,0 +1,80 @@
@import "./transition.scss";
* {
margin: 0;
padding: 0;
}
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif;
box-sizing: border-box;
margin: 0;
}
html {
height: 100%;
box-sizing: border-box;
}
#app {
height: 100%;
text-align: center;
box-sizing: border-box;
}
// main-container global css
.app-container {
position: relative;
padding: 20px;
}
// table-operate-container global css
.table-operate-container {
margin-top: 20px;
}
// table-container global css
.table-container {
margin-top: 20px;
}
// webkit内核滚动条优化Chrome Safari 浏览器
*:hover::-webkit-scrollbar {
display: block;
}
::-webkit-scrollbar {
display: none;
/*滚动条整体样式*/
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 10px;
}
::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 8px;
background-color: rgba(144, 147, 153, 0.5);
-webkit-transition: 0.3s background-color;
transition: 0.3s background-color;
}
::-webkit-scrollbar-track {
/*滚动条里面轨道*/
/* -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 6px;
background-color: rgba(144,147,153,.3); */
}
/* 火狐美化滚动条 */
* {
scrollbar-color: #c8d2e0 #f3f4f9;
/* 滑块颜色 滚动条背景颜色 */
scrollbar-width: thin;
/* 滚动条宽度有三种:thin、auto、none */
}

@ -0,0 +1,3 @@
//color
//备案号
$recordNumberHover: #b79500

@ -0,0 +1,23 @@
// navbar
$menuText: #fff;
$menuActiveText: #ffd04b;
$subMenuActiveText: #ffd04b;
$menuBg: #545c64;
$menuHover: #ffd04b;
$subMenuBg: #545c64;
$subMenuHover: #ffd04b;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
}

@ -0,0 +1,48 @@
// global transition css
/* fade */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* breadcrumb transition */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}

@ -0,0 +1,10 @@
import defaultSettings from '@/settings'
const title = defaultSettings.title || 'Vue Admin Template'
export default function getPageTitle(pageTitle) {
if (pageTitle) {
return `${pageTitle} - ${title}`
}
return `${title}`
}

@ -0,0 +1,17 @@
<template>
<div>
这是一个首页 <br>
如你所见它现在还什么都没有但马上就会有了 <br>
By Soul2
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
</style>

@ -0,0 +1,19 @@
<template>
<div id="so-demo">
灵魂演示 <br>
这是一套你不能错过的魔兽地图编辑器入门教程 <br>
灵魂演示是灵魂所制作的一套强大的魔兽地图编辑器系统演示地图涵盖了许多新手入门所关注和需要的内容 <br>
你可以选择点击这里一次性下载所有演示地图也可以通过点击下方各个按钮以你希望的方式下载你所需要的特定演示地图 <br>
提醒灵魂演示地图基于 YDWE 1.27.5 制作请使用 YDWE 1.27.5 或以上的版本打开灵魂演示地图否则可能会导致 WE兼容性错误 <br>
</div>
</template>
<script>
export default {
name: "SoDemo"
}
</script>
<style scoped>
</style>

@ -0,0 +1,31 @@
<template>
<div id="soui">
So UI <br>
这是一个魔兽争霸3地图编辑器的功能扩展包. <br>
<div class="readme">
<div class="title">
关于SoUI
</div>
<ul>
<li>这是一个基于YDWEv1.31.8(+网易DzAPI 1.2.9a)打包的魔兽争霸3地图编辑器扩展包.</li>
<li>该扩展包添加了一些减少重复劳动的编辑器额外动作UI.</li>
<li>扩展包部分内容仍处于测试阶段,其功能可能存有未知BUG.</li>
<li>已提供部分额外功能的演示地图,安装后可以在安装目录\example(演示地图)\SoUI文件夹内找到.</li>
<li>未经本人许可擅自将SoUI在网上散播者将承担盗版乱传的相关法律责任,并且传播者将承担所有使用者使用本UI带来的所有负面后果,本人不承担任何责任.</li>
<li>发现任何BUG可以<a href="" id="ret">点击这里</a>进行反馈</li>
<li>
SoUI仅对编辑器功能进行扩展,不涉及编辑器原有功能的修改.
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "SoUi"
}
</script>
<style scoped>
</style>

@ -0,0 +1,46 @@
'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')
function resolve(dir) {
return path.join(__dirname, dir)
}
const name = defaultSettings.title || '未命名标题'
const autoOpenBrowser = defaultSettings.autoOpenBrowser || false
const port = process.env.port || process.env.npm_config_port || 6810 // dev port
module.exports = {
/**
* You will need to set publicPath if you plan to deploy your site under a sub path,
* for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
* then publicPath should be set to "/bar/".
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: process.env.VUE_APP_CONTEXT_PATH || '/',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
// disableHostCheck: true,
port: port,
open: autoOpenBrowser,
overlay: {
warnings: false,
errors: true
}
// before: require('./mock/mock-server.js')
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title.
name: name,
resolve: {
alias: {
'@': resolve('src')
}
}
},
}
Loading…
Cancel
Save