基于Vue从头搭建后台管理系统

模板地址

https://gitee.com/yurunfei/jiuwei-manager

模板截图

53D02B27-7057-4f06-B5BF-5503FE8E94F0.png
0E5ABC26-A2C9-47b5-8C94-79E1F66098BA.png
E9E6101D-B46D-4c3c-BEE1-D65F9DE756A6.png
58FAAF85-92FB-48fa-8B26-5066490FAF4B.png

技术框架:

vue-router+axios +vuex +sass+md5 + element ui

开发前准备

使用yarn来管理和导入组件

1.导入sass的方式:

高版本可能会导致未知问题,以下面的版本为主,可以正常导入和运行:
1. yarn add sass-loader@7.1.0 --dev
2. yarn add node-sass@4.12.0 --dev

引入其他scss文件的时候需要导入:
3. yarn add sass-resources-loader@2.0.1 --dev

全部导入完成后,打开webpack.base.conf.js: 在rules下面添加:

 {
      test: / \.scss$ / ,
      loaders: [ 'style' , 'css' , 'sass' ]
 }

scss使用测试:如下测试修改字体颜色

< style lang = "scss" >
$color : red ;
div { color : $color ;}
</ style >
2.导入Element UI的方式:

yarn add element-ui
main.js

import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI, { size: 'small', zIndex: 3000 });
3.normalize可以适配各种浏览器,使其样式保持一致:

yarn add normalize.css
main.js里面引入:

import 'normalize.css/normalize.css'

开发过程

1.项目整体布局文件:

可以copy现有的style文件,去除原有样式布局。
在static文件夹下建立icon文件夹存放图标文件,img文件夹存放png图片。如果使用阿里巴巴图标库的图标,可以从图标库获取链接地址,比如:


image.png

拷贝至index.html里面:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>樱花后台管理系统</title>
    <link rel="stylesheet" href="//at.alicdn.com/t/font_2385466_0zl4ktn7ehhl.css">
  </head>

用的时候:

<i class="iconfont icon-weibo"></i>

在App.vue里面导入自定义样式文件:

<style lang="scss">
@import "./style/style";
@import "../static/icon/iconfont.css";
</style>
2.工具类存放文件:

建立utils文件夹,存放内容为:
公共类方法
json文件
路由文件router.js(为了统一管理,摒弃router文件)
全局状态管理文件store.js(为了方便管理放在此处)


image.png
3.建立页面路由,router.js:

将登陆页设置为根路由:

import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/page/index'  // 登录页

Vue.use(Router)

export default Router({
    routes: [
        {
          path:'/',
          component: Index
        }
    ]
})
image.png
4.搭建完登录页面之后进入管理后台首页,需要注意:
  • 首页左侧的菜单项、右侧顶部的状态栏是一直存在的,所以,作为主体框架,切换的每个功能页都为主体框架的子路由。
import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/page/index'  // 登录页
import Admin from '@/page/admin'  // 主体框架

Vue.use(Router)

export default Router({
    routes: [
        {
          path:'/',
          component: Index
        },
        {
          path:'/admin',
          component: Admin,
          children:[  // 子路由
            // 产品页
            { path: '/home', component: () => import('@/page/home/home') },
          ]
        }
    ]
})

这里使用了懒加载的方式,为了避免以后页面越来越多,打包后加载缓慢的问题,懒加载路由可以使页面按需加载,进行首屏优化

5.admin.vue为主体框架页,包含:左侧菜单栏和顶部状态栏

左侧菜单栏单独封装成组件,放在components文件夹下,是为了方便做权限管理,使结构看起来更清晰。
如果想让admin下的子路由显示出来,需要添加
<router-view class="content" :class="{ 'side-hide': collapse }"></router-view>
让子路由有一个入口可以添加进当前路由。

5.首页的统计图表使用的是v-chanrt,分为:纯数字统计、折线图、条形图、饼图、环形图几种常用图表

注意:1.数字显示千分位可以使用方法:.toLocaleString()
2.适配手机,需要设置css当屏幕宽度小于500的时候,改变内容宽度

  .tl1-item {
      width: calc((100% - 60px) / 4);
    }
 @media screen and (max-width: 768px) {
    .tl1-item {
      width: 100%;
    }
  }

具体用法可以参考这篇博客:https://blog.csdn.net/piano9425/article/details/99283830

image.png

6.顶部tags标签记录导航

每次打开新的页面,顶部自动增加tags标签,点击跳转到对应的路由。
因为不在一个页面,需要用到vuex状态管理。最好对不同功用的状态单独建立modules模块,然后统一导入,导入方式为:
inddex.js:

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

在标签组件的watch里面对 $route进行监听,每当 $route发生改变时就调用vuex里面添加路由的方法。首次运行页面,路由还没有发生改变,需要在mounted里面调用一次添加路由的方法

image.png

需要注意的是关闭图标在tag里面,点击的时候容易遇到冒泡,需要使用@click.stop阻止冒泡,关闭标签的方法写在vuex里面。

 deleteTagsAction: (state, view) => {
    state.visitedViews.splice(state.visitedViews.indexOf(view), 1)
  },

如果是把当前页关掉了,就加载标签数组的最后一个路由

const lastView = visitedViews.slice(-1)[0]
      if (lastView) {
        this.$router.push(lastView.path)
      } else {
        this.$router.push('/')
 }

删除数组元素的时候用splice,而获取数组某个元素的时候使用slice,-1表示从最后数起的第一个元素,因为获取到的是一个数组,所以需要[0]取值

7.表格高度动态计算
this.$nextTick(() => {
        let windowHeight =
          document.documentElement.clientHeight || document.body.clientHeight;
        let topHeight =
          64 + 54 + 20 + 56 + 40 + this.$refs.searchv.clientHeight;
        let tableH = windowHeight - topHeight - 75;
        this.tableH = tableH ;
});
  • 顶部状态栏高度:64
  • 路由标签高度:54
  • 导航文字距离固定栏距离:20
  • 导航文字高度:56
  • 正文与导航文字的总间距:40
  • 随着菜单栏收缩可变搜索栏高度: this.$refs.searchv.clientHeight
  • 预留给底部分页器的高度:75

目前存在的bug:可以监听到菜单栏的收缩,但是再重新计算高度的时候,ref获取到的搜索栏高度没变,实际已经发生改变,导致表格下移,有一部分分页器淹没在页面下面

6.产品列表页
  • 添加了切换表格和卡片的功能,点击查看详情可以跳转到详情页,并从详情页返回;
  • 点击查询可以打印出搜索参数,便于数据请求;
  • 新增按钮添加了常用的表单选项,因为ant-design-vue可以提供更为炫酷的动画效果,所以此处采取按需导入的方式,导入了ant-design-vueModel组件,与Element ui的Form组件搭配使用
    image.png
7.权限管理

大致说一下权限管理的思路:

左侧菜单栏的路由已经在本地配置好了,但不是所有人都有权限看见,比如在管理后台创建三种角色,分别为:管理员、商务、临时用户,管理员可以添加用户,但是商务不能,就得对商务这个角色隐藏权限管理的模块。

因此,给每个角色配置好权限后,再由后台返回该角色能够看到的菜单项,与本地做比对,如果后台没有返回就不显示,返回才显示。

一般的权限管理分为三级,比如权限管理模块为一级,其下所包含的用户管理为二级,用户管理页面的修改密码按钮为三级。

一级和二级都可以在el-menu里面处理,三级需要另写方法。

全局状态管理可以使用vuex存储后台返回的数据。

模拟权限管理:使用账号1登录是管理员权限,可以看到所有菜单,使用其他账号登录,看不到权限管理菜单

项目结构:

  • 登录
  • 首页统计
  • 商品列表
  • 商品详情
  • 菜单权限
  • 权限组
  • 权限分配
  • 401/403/404错误页面
  • 个人中心

可以使用的小技巧

1.快速删除node_modules:

在碰到node_modules包出现问题报错,这种事情经常发生╮(╯▽╰)╭,可能装包的时候没装好就会报这种错,如果是把node_modules整个删除到垃圾桶里,需要等待超级长的时间,实在是太麻烦啦,所以只需要安装一个管理工具,敲一行代码,几秒钟就可以删掉:
1、安装npm包–rimraf
npm install rimraf -g
2、在cmd指令下,进入所需删除的node_modules文件夹的位置
3、输入以下指令进行删除
rimraf node_modules
这样就可以简单粗暴得秒删。O(∩_∩)O~~
附带yarn清除缓存命令:
yarn cache clean

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容