从0开始搭建vue2管理后台基础模板

网站主要完成:侧边菜单栏、页面标签卡、内容栏
源代码gitee地址:https://gitee.com/zhao_liangliang1997/navigation-bar

一、起步

1、创建vue项目

vue create 项目名

2、引入element

3、其他安装

1、首先需要安装如下

cnpm install vuex
cnpm install vue-router
cnpm install sass
cnpm install sass-loader
cnpm install node -sass

2、main.js中引入相关

引入后,可能会报错,请别急,继续往下走。

import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 引入基础样式[下面给链接复制style.scss以及variables.scss]
import './assets/scss/style.scss';

Vue.config.productionTip = false
Vue.use(ElementUI);

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

3、改造App.vue

<template>
  <div id="app">
      <router-view/>
  </div>
</template>
<script>
export default {
  name: 'App',
}
</script>
<style lang="scss">
#app {
    height: 100vh;
}
</style>

完成侧边栏的项目结构,如下图:

在这里插入图片描述

相关链接

1、style.scss;
2、variables.scss

4、配置路由[router下的index.js]

配置如下路由后,下一步您需要对layout进行页面设计【第一步侧边菜单栏】

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter({
    routes:[
        {
            path: '/',
            hidden: true,
            component: () =>
                import ('@/page/layout'),
            children: [
                {
                    path: 'index',
                    component: () =>
                        import ('@/page/index'),
                    hidden: true
                }
            ]
        },
    ]
})
export default router

二、侧边菜单栏的设计

1、封装菜单组件navMenu.vue

<template>
    <div>
        <template v-for="(item, index) in userNav">
            <el-menu-item :index="item.path" v-if="!item.hidden && !item.children">
                {{ item.name }}
            </el-menu-item>
            <el-submenu :index="item.path" v-if="!item.hidden && item.children">
                <template slot="title">{{ item.name }}</template>
                <nav-menu :user-nav="item.children"/>
            </el-submenu>
        </template>
    </div>
</template>
<script>
export default {
    name: "navMenu",
    props: {
        userNav: {
            type: Array,
            default: []
        }
    }
}
</script>

2、layout中实现侧边栏
思路: ①首先画出侧边栏;②路由信息存放vuex中;③vuex中的路由从路由js中获取

<template>
    <el-container>
        <el-aside width="20vh" class="aside">
            <div class="logo_box pr">
                <span class="fl w_100 tc f20 text-white w_h_center pl20 pr20">测试服务平台</span>
            </div>
            <el-menu :default-active="activeIndex"
                     class="el-menu-vertical-demo"
                     style="flex: 1; overflow: auto; width: 100%; overflow-x: hidden"
                     background-color="#6187F7"
                     text-color="#fff"
                     active-text-color="#ffd04b"
                     unique-opened
                     @select="handleSelect">
                <template v-for="(item, index) in userNav">
                    <el-menu-item :key="index" :index="item.path" v-if="!item.hidden && !item.children">
                        {{ item.name }}
                    </el-menu-item>
                    <el-submenu :key="index" :index="item.path" v-if="!item.hidden && item.children">
                        <template slot="title">{{ item.name }}</template>
                        <nav-menu :user-nav="item.children"/>
                    </el-submenu>
                </template>
            </el-menu>
        </el-aside>
        <el-container>
            <el-header>Header</el-header>
            <el-main>
                <router-view/>
            </el-main>
        </el-container>
    </el-container>
</template>

<script>
import NavMenu from '@/page/navMenu/navMenu'
import {mapState, mapMutations} from 'vuex'
export default {
    name: "VueLayout",
    components: {
        NavMenu
    },
    data() {
        return {
            url: '',
            activeIndex:'/'
        }
    },
    created() {
        // 获取菜单权限 [因此刻未配动态路由,所以在此处调用]
        this.setMenu()
    },
    computed: {
        ...mapState(['userNav'])
    },
    methods: {
        ...mapMutations(['setMenu']),
        handleSelect: function (key) {
            let path = this.$route.path
            if (path !== key) {
                if (key === '/' && path === '/index') {
                    return
                }
                this.$router.push(key)
            }
        },
    }
}
</script>

<style less scoped>
/deep/ .el-tabs__header {
    margin: 0;
}
.aside {
    background-color: #6187F7;
    display: flex;
    flex-direction: column;
}
.logo_box {
    height: 60px;
    border-bottom: 1px solid white;
}
</style>

3、vuex

//1.引入Vue
import Vue from 'vue';
import Vuex from 'vuex';
import view from '@/router/baseView';
import router from '@/router/index'
import dynamicView from "@/router/dynamicView";
//2.安装
Vue.use(Vuex);
const store = new Vuex.Store({
    //存储状态
    state:{
        userNav: [],    // 导航栏路由, 默认未登录,展示静态路由
        activeIndex: '/',
        tagMap: new Map(),
    },
    // Vuex中的Store状态(state)更新的唯一方式:提交Mutation
    mutations:{//定义mutations
        // 定义改变全局共享数据的方法
        setMenu(state) {
            let baseView = Object.assign([], view) // 初始化导航栏
            // 根据菜单权限获取菜单
            let nav = getNav(dynamicView)
            nav.forEach(item => {
                baseView.push(item)
            })
            state.userNav = baseView
        },
    }
})
//导出
export default store

function getNav(navs) {
    let list = []
    navs.forEach(nav => {
        let obj = {}
        obj.path = nav.path
        obj.name = nav.name
        obj.icon = nav.icon
        obj.isPage = nav.isPage
        if (nav.isPage) {
            obj.component = () => import ('@/views' + nav.path)
        }
        if (nav.children) {
            obj.children = getNav(nav.children)
        }
        list.push(obj)
    })
    return list
}

三、页面标签卡

1、头部、内容栏及页面标签卡

页面标签卡:标签卡为外部引入组件【代码请到Gitee查看】

在这里插入图片描述

2、注意事项:

1、tag改变方法【activeIndex从vuex引入】
2、tag标签页根据路由创建【navClick从vuex引入】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、最终效果

在这里插入图片描述

4、后续相关token

1.客户端使用用户名跟密码请求登录
2.服务端收到请求,去验证用户名与密码
3.验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
4.客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
5.客户端每次向服务端请求资源的时候需要带着服务端签发的 token
6.服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
  • 每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里

  • 基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库

  • token 完全由应用管理,所以它可以避开同源策略

  • 什么是同源策略?
    同源策略是客户端脚本(尤其是 Javascript)的重要的安全度量标准。其目的是防止某个文档或脚本从多个不同源装载。 这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。

  • 为什么要有同源限制?
    我们举例说明:比如一个黑客程序,他利用 Iframe 把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过 Javascript 读取到你的表单中 input 中的内容,这样用户名,密码就轻松到手了

5、permission.js

在登陆这个流程中,permission.js这个是很最重要的一环,是路由的全局钩子(beforeEach和afterEach),全局钩子就是每次跳转的时候可以根据情况进行拦截,不让它进行跳转。使用场景最常见的就是有些页面需要用户登陆之后才能访问,就可以在beforeEach中校验用户是否登陆来进行相对应的拦截处理。

6、相关学习博客推荐:

vue-element-admin 登陆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java亮小白1997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值