VUE侧边栏导航后台搭建

一个做安全的学习前后端开发,多少有些吃力,不得不拜读几个专业的开发大佬的博客

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的选项,主体跳转至对应页面

参考链接:

https://www.cnblogs.com/wbjxxzx/p/9977220.html 

猜你喜欢

转载自blog.csdn.net/qq_38376348/article/details/107792261
今日推荐