Fork me on GitHub
余鸢

后台管理开发(一):开发技术框架相关及home页面详解

开发相关的技术栈

  • vuejs2.0:一套构建用户界面的渐进式框架,易用、灵活、高效
  • element-ui:一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的组件库
  • vue-router:官方的路由组件,配合vue.js创建单页应用(SPA)非常简单
  • axios: 基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 node.js 中使用
  • scass

构建项目框架

使用vue-cli脚手架搭建项目

1
2
3
4
5
6
7
8
# 创建一个基于 webpack 模板的新项目hs
$ vue init webpack hs
# 进入项目目录
$ cd hs
# 安装依赖
$ npm install
# 运行项目
$ npm run dev

项目运行后看到以下界面,恭喜你,项目环境搭建成功!

1

项目结构及新建的基础页面

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
├── build #webpack编译相关文件目录,一般不用动
├── config #配置目录
│ ├────dev.env.js #开发环境变量
│ ├────index.js #主配置文件
│ └────prod.env.js #生产环境变量
├── dist #生产环境下build后的文件存放目录(发布目录)
├── server #服务端代码目录,提供给前端接口
├── src #前端项目源码目录
│ ├───—api #封装的接口文件目录
│ ├───—assets #资源目录
│ ├───—common #公用文件目录
│ ├───—components #组件及页面文件目录
│ ├───—router #路由目录
│ ├───—App.vue #项目入口文件
│ ├───—bus.js #公共通信组件
│ └────main.js #项目的核心文件
├── static #开发模式下的静态资源目录
├── index.html #首页入口文件,你可以添加一些 meta 信息或同统计代码啥的
├── package.json #项目配置文件
└── README.md #项目的说明文档,markdown 格式

创建基础页面

首先需要先简单创建几个基本页面方便接下来展示。

home.vue

1
2
3
4
5
<template>
<div>
首页
</div>
</template>

其他页面就省略了,创建占位。目录截图如下:

4

目录明细:

src/components/

  • logine ——————– 登录页
  • home ——————–首页
  • menu ——————– 菜单管理页
  • permission ——————– 权限管理页
  • role ——————– 角色管理页
  • uesr ——————– 用户管理页
  • organiz ———————— 机构管理页
  • inte-setting ———————— 综合设置页

配置及安装依赖

在package.json中配置所需的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
"dependencies": {
"babel-runtime":"^6.26.0",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"element-ui": "^2.0.0-beta.1",
"scss": "^0.2.4",
"axios": "^0.17.0"
},
"devDependencies": {
...
"babel-polyfill": "^6.26.0",
...
}

这里简单说明下babel-polyfill,它是对ES6的API做转义。有兴趣的同学可以查阅其他资料。

安装依赖

1
$npm install

引入element-ui

在app.vue引入element-ui,然后就可以在其他任何页面中使用了

1
2
3
import Element from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
Vue.use(Element)

设置路径别名

设置路径别名,以减少开发过程中路径的复杂性,比如../../这类路径。

修改webpack.base.conf.js

1
2
3
4
5
6
7
8
9
10
11
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'common': resolve('src/common'),
'components': resolve('src/components'),
'api': resolve('src/api'),
'base': resolve('src/base')
}
},

配置router

在router/index.js配置routers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
let router = new Router({
routes: [
{
path: '/',
name: '登录',
component: Login
},
{
path: '/home',
component: Home,
name: '系统设置',
iconCls: 'el-icon-setting',
children: [
{
path: '/menu',
name: '菜单管理',
component: Menu
},
{
path: '/permission',
name: '权限管理',
component: Permission
},
{
path: '/role',
name: '角色管理',
component: Role
},
{
path: '/user',
name: '用户管理',
component: User
}
]
},
{
path: '/home',
component: Home,
name: '组织架构',
iconCls: 'el-icon-menu',
children: [
{
path: '/organiz',
name: '机构管理',
component: Organiz
},
{
path: '/setting',
name: '综合设置',
component: InSetting
}
]
}
]
})

编写home.vue组件

使用element-ui2.0的Container布局容器,方便快速搭建页面的基本结构。

先上components/home.vue的代码及效果图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<template>
<el-container class="container">
<el-header class="header">
<el-row>
<el-col :span="24" class="h-col">
<el-col :span="10" class="logo" :class="collapsed?'logo-collapse-width':'logo-width'">
{{collapsed ? '' : title}}
</el-col>
<el-col :span="10">
<div class="tools" @click.prevent="collapse">
<i class="el-icon-arrow-right"></i>
</div>
</el-col>
<el-col :span="4" class="userinfo">
<el-dropdown trigger="hover">
<span class="el-dropdown-link userinfo-inner">{{userName}}<i class="el-icon-setting"></i></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>设置</el-dropdown-item>
<el-dropdown-item @click.native="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-col>
</el-row>
</el-header>
<el-container>
<el-aside class="aside" :class="{showSidebar:!collapsed}">
<el-menu default-active="0" class="el-menu" ref="menuCollapsed" router :collapse="collapsed">
<template v-for="(item,index) in $router.options.routes" v-if="item.name !== '登录'">
<el-submenu :index="index+''" v-if="!item.leaf">
<template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span></template>
<el-menu-item v-for="child in item.children"
:index="child.path"
:key="child.path"
v-if="!child.menuShow"
:class="$route.path==child.path?'is-active':''"
>{{child.name}}
</el-menu-item>
</el-submenu>
<el-menu-item v-else-if="item.leaf&&item.children&&item.children.length"
:index="item.children[0].path"
:class="$route.path==item.children[0].path?'is-avtive':''">
<i :class="item.iconCls"></i><span slot="title">{{item.children[0].name}}</span>
</el-menu-item>
</template>
</el-menu>
</el-aside>
<el-main>
<transition>
<router-view></router-view>
</transition>
</el-main>
</el-container>
</el-container>
</template>

运行项目展示页面如下:

3

代码分析:

接下来依次分析home.vue的代码。

动态配置菜单

使用菜单组件<el-menu>:default-active="0"设置当前激活菜单的index,设置为router模式会在激活导航时以 index 作为 path 进行路由跳转

1
2
3
<el-menu :default-active="0" class="el-menu" ref="menuCollapsed" router :collapse="collapsed">
...
</e-menu>

接着使用$router.options.routes来遍历生成侧边导航栏,v-if将登录的路径隐藏。在菜单中通过submenu组件可以生成二级菜单

1
2
3
4
5
<template v-for="(item,index) in $router.options.routes" v-if="item.name !== '登录'">
<el-submenu :index="index+''" v-if="!item.leaf">
<template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span>
</el-submenu>
</template>

分组名可以通过title属性直接设定进行solt分发菜单

1
<template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span></template>

item.nameitem.children.name来配置菜单栏和子菜单栏的名称。$route.path表示当前路由对象的路径

1
2
3
4
5
6
<el-menu-item v-for="child in item.children"
:index="child.path"
:key="child.path"
v-if="!child.menuShow"
:class="$route.path==child.path?'is-active':''"
>{{child.name}}</el-menu-item>

最后,如上图路由菜单展示,完美~!

导航菜单折叠功能

首先在data中创建是否折叠collapsed属性,默认值为false。写个collapse()方法以此来控制菜单是否折叠。

1
2
3
4
5
6
7
8
9
10
11
data () {
return {
collapsed: false
}
},
methods: {
collapse () {
this.collapsed = !this.collapsed
},
}

分别在header和aside组件上设置collapsed来控制菜单折叠

1
2
3
4
5
6
7
<el-col :span="10" class="logo" :class="collapsed?'logo-collapse-width':'logo-width'">
{{collapsed ? '' : title}}
</el-col>
<el-aside class="aside" :class="{showSidebar:!collapsed}">
...
</el-aside>

具体代码看:https://github.com/hs-web/hsweb-ui-vue