一个做安全的学习前后端开发,多少有些吃力,不得不拜读几个专业的开发大佬的博客
0x00 初始化VUE项目
vue ui
按照上一篇博客内容点这里,初始化VUE项目
0x01 修改文件
第一步,修改入口文件
修改app.vue为如下,主要是增加<router-view/>,用于路由匹配
<template>
<div id="app">
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
<script>
export default {
name:'App',
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
修改mian.js,主要作用是初始化我们上一步的App.vue
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import '@/styles/index.scss'
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
需要注意的是,这里引入了style下的scss文件,我们需要创建一个对应的css文件,同时在src目录下也创建style文件夹,style.scss内容为:
html {
height: 100%;
}
body {
position: relative;
top: 0;
left: 0;
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 100%;
overflow: hidden;
}
.app {
$solidBorder: 1px solid #eee;
$sideCollapsedWidth: 66px;
$sideExpandedWidth: 230px;
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
font-size: 1em;
width: 100%;
height: 100%;
min-width: 900px;
border: $solidBorder;
display: flex;
display: -webkit-flex;
flex-flow: row nowrap;
&-side {
width: 230px;
height: 100%;
font-weight: 700;
border-right: $solidBorder;
&-left {
background-color: rgb(238, 241, 246);
}
&-logo {
height: 60px;
text-align: center;
}
&-collapsed {
width: 66px!important;
}
&-expanded {
width: 230px!important;
}
}
&-header {
width: 100%;
height: 60px;
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
border-bottom: $solidBorder;
&-userinfo {
position: absolute;
right: 0;
margin-right: 25px;
display: flex;
flex-flow: row nowrap;
height: 60px;
justify-content: flex-start;
align-items: center;
}
}
&-body {
font-size: 1em;
width: 100%;
height: 100%;
padding: 20px;
overflow-y: scroll;
}
&-footer {
width: 100%;
height: 60px;
}
}
.inline-block {
display: inline-block;
}
下一步:配置路由,修改router文件下index.js,配置路由,配置思路:当请求跟节点则转发至dashboard并且装载Container组件,当请求路由为dashboard或者article时,则装载Container组件以及对应的Dashboard或者Article组件,Dashboard或者Article组件为Container的子路由
import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/views/TheLogin'
import Container from '@/views/Container'
import Dashboard from '@/views/dashboard'
import Article from '@/views/article'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/',
redirect: '/dashboard',
name: 'Container',
component: Container,
children: [
{path: 'dashboard', name: '首页', component: Dashboard, },
{path: 'article', name: '文章', component: Article, },
]
}
]
})
下一步:在views下创建Container.vue,大致布局为侧边栏布局侧边栏,头部,内容主体,可以参考https://element.eleme.cn/#/zh-CN/component/container 的布局方式,只不过我们需要在内容主体增加<router-view/>作为路由出口,内容为:
<template>
<div class="app">
<el-container>
<el-aside class="app-side app-side-left"
:class="isCollapse ? 'app-side-collapsed' : 'app-side-expanded'">
<div class="app-side-logo">
<img src="@/assets/img.jpg"
:width="isCollapse ? '60' : '60'"
height="60" />
</div>
<div>
<!-- 我是样例菜单 -->
<el-menu default-active="1-4-1"
router
class="el-menu-vertical-demo"
@open="handleOpen"
:collapse="isCollapse">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span slot="title">导航一</span>
</template>
<el-menu-item-group>
<span slot="title">分组一</span>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="/article">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<span slot="title">选项4</span>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3"
disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</div>
</el-aside>
<el-container>
<el-header class="app-header">
<el-menu default-active="/"
router
class="el-menu-demo tab-page"
mode="horizontal"
@select="handleSelect"
active-text-color="#409EFF">
<el-menu-item index="/">首页</el-menu-item>
</el-menu>
</el-header>
<el-main class="app-body">
<template>
<router-view/>
</template>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: 'Container',
data() {
return {
username: '',
isCollapse: false
}
},
methods: {
toggleSideBar() {
this.isCollapse = !this.isCollapse
},
logout: function () {
this.$confirm('确认退出?', '提示', {})
.then(() => {
sessionStorage.removeItem('user');
this.$router.push('/login');
})
.catch(() => { });
},
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
handleSelect(key, keyPath) {
console.log(key, keyPath);
},
},
mounted: function () {
let user = sessionStorage.getItem('user');
if (user) {
this.username = user;
}
},
}
</script>
<style>
</style>
在views下创建article.vue和dashboard.vue,分容分别为:
<template >
<div>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1>
<h1>Article</h1> <h1>Article</h1>
<h1>Article</h1>
</div>
</template>
<script>
export default {
name: 'Article'
}
</script>
<template>
<h1>dashboard test</h1>
</template>
<script>
export default {
name: 'Dashboard'
}
</script>
然后创建TheLogin.vue
<template>
<div class="login-container">
<el-form :model="ruleForm2" :rules="rules2"
status-icon
ref="ruleForm2"
label-position="left"
label-width="0px"
class="demo-ruleForm login-page">
<h3 class="title">系统登录</h3>
<el-form-item prop="username">
<el-input type="text"
v-model="ruleForm2.username"
auto-complete="off"
placeholder="用户名"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password"
v-model="ruleForm2.password"
auto-complete="off"
placeholder="密码"
></el-input>
</el-form-item>
<el-checkbox
v-model="checked"
class="rememberme"
>记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button type="primary" style="width:100%;" @click="handleSubmit" :loading="logining">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data(){
return {
logining: false,
ruleForm2: {
username: 'admin',
password: '123456',
},
rules2: {
username: [{required: true, message: 'please enter your account', trigger: 'blur'}],
password: [{required: true, message: 'enter your password', trigger: 'blur'}]
},
checked: false
}
},
methods: {
handleSubmit(event){
this.$refs.ruleForm2.validate((valid) => {
if(valid){
this.logining = true;
if(this.ruleForm2.username === 'admin' &&
this.ruleForm2.password === '123456'){
this.logining = false;
sessionStorage.setItem('user', this.ruleForm2.username);
this.$router.push({path: '/article'});
}else{
this.logining = false;
this.$alert('username or password wrong!', 'info', {
confirmButtonText: 'ok'
})
}
}else{
console.log('error submit!');
return false;
}
})
}
}
};
</script>
<style scoped>
.login-container {
width: 100%;
height: 100%;
}
.login-page {
-webkit-border-radius: 5px;
border-radius: 5px;
margin: 180px auto;
width: 350px;
padding: 35px 35px 15px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
}
label.el-checkbox.rememberme {
margin: 0px 0px 15px;
text-align: left;
}
</style>
全部代码奉上,至此,项目结构为:
0x02 运行项目
运行项目后效果:
点击我们修改过index的选项,主体跳转至对应页面
参考链接: