开发前,我们需要熟悉一下项目结构,该项目其实是vue脚手架的element ui升级版。
项目结构和vue脚手架雷同,在vue官网和vue-element-admin官网都可以找到参考。
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 源代码
│ ├── assets # 静态资源
│ │ ├── css # 项目所有 CSS 样式 主题
│ │ ├── icons # 项目所有 svg icons
│ │ └── images # 项目图片
│ ├── components # 全局公用组件
│ ├── layout # 全局 layout
│ ├── mock # 项目 mock 模拟数据
│ ├── router # 路由
│ │ ├── modules # 各模块路由
│ │ ├── index.js # 路由入口
│ │ └── permission.js # 权限管理
│ ├── service # 所有 AJAx 请求
│ ├── store # 全局 store 管理
│ ├── utils # 全局公用方法
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ ├── main.ext.default.js # main.js 的扩展 文件 (复制重命名为 main.ext.js)
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── settings.js # 系统配置文件
├── tests # 测试
├── .browserslistrc # 项目的浏览器配置
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .babel.confi.js # babel-loader 配置
├── vue.config.default.js # vue-cli 配置(复制重命名为 vue.config.js)
└── package.json # package.json
上面列出的结构可能与您获得的脚手架不完全一样,实际上,它和我的项目结构也不一样,但是做参考足够了(大多只是文件位置差异)。
在package.json有一些项目信息,我们可以自己修改,如网页名称,作者之类。该配置不直接影响页面展示。
{
"name": "kexinran-blog-admin",
"version": "1.0.0",
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
"author": "kexinran " ,
...
}
现在,我们可以修改网页title(浏览器标签名称),logo等展示配置,使这个项目更像我们自己的项目。
**总之,title在settings.js中修改,图片是public中的图片,直接覆盖自己想要的图片上去即可。**这是结果,下面是分析过程:
在public/index.html中我们看到网页的title和icon设置,为两个变量。
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %>title>
根据vue脚手架官方文档和变量的使用格式,该变量应该来自于vue.config,js。
在该js中寻找,同时参考官方文档中vue.config.js配置介绍,找到变量对应位置。
module.exports = {
publicPath: '/', // <%= BASE_URL %>
...
configureWebpack: {
name: name, // <%= webpackConfig.name %>
resolve: {
alias: {
'@': resolve('src')
}
}
},
...
}
可以看出,icon的地址最终结果为根目录下的favicon.ico文件,要改变icon,可以改变目录的拼接结果,也可以覆盖图片到对应地址。
(装有index.html的目录是根目录,也就是public)
再看name属性对应的是name变量,该变量在js文件中有定义。
const defaultSettings = require('./src/settings.js')
...
const name = defaultSettings.title || 'vue Admin Template' // page title
可以看到,该变量来自于’./src/settings.js’中的导出对象的title属性,所以我们去找到那个文件,改变其对应属性就可以了。
这时我注意到这里导入使用的是require,这和import有什么不同呢,百度得知,首先遵循的规范不同,require是CommonJS的一部分,import / export 是ES6的新规范,使用时的区别是require是是运行时调用,所以require理论上可以运用在代码的任何地方import是编译时调用,所以必须放在文件开头。
关于模块的问题,以后会详细说明。
同时,我在settings.js中看到固定头部配置和侧边logo配置,如果要使用,后改为true即可。
可以想象它的实现原理与title应该是相同的。
刚刚在settings.js中看到侧边logo配置。
module.exports = {
...
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo: true
...
}
如上该为true即可。
首先找到侧边栏相关代码的位置,侧边栏是每个路由都应当有的组件,通常有两种实现方式,一种是使用二级路由,将侧边栏放在一级路由上,一种是在每个路由中引入它,打开router文件,发现在每个路由中都引入了Layout文件,打开该文件果然是相关代码。
首先打开index.vue,通过template锁定侧边栏组件sidebar,打开该组件的index.vue文件,一眼看到决定logo的代码。
这个组件通过v-if决定是否显示,初步猜想该值showLogo应该是与刚刚在setting中设定的boolean值绑定的。
向下看,该值来自于store(vuex)。
computed: {
...
showLogo() {
return this.$store.state.settings.sidebarLogo
}
...
}
在store/settings.js中看到,该值果然来自于刚刚设置的setting的值。
import defaultSettings from '@/settings'
const {
showSettings, fixedHeader, sidebarLogo } = defaultSettings
const state = {
showSettings: showSettings,
fixedHeader: fixedHeader,
sidebarLogo: sidebarLogo
}
然后你就发现,侧边栏上面多了一格logo和title,但是这个title和网页title并不一致,这个title是要单独设置的。
首先找到负责logo的文件,src/layout/components/Sidebar/Logo.vue。
在模板中看到结构为transition=>router-link,transition为过度动画,来那个router-link,根据不同的key值判断是侧边栏在不同状态(压缩和展开)时的效果,可以看到,只要设置了logo,两种状态下logo都是展示的,而在折叠状态下,优先展示logo,未设置logo的情况下展示title。
文件下面的代码中有对title和logo的设置,修改即可。
export default {
...
data() {
return {
title: '我的权限管理系统',
logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
}
}
}
刚刚2.2.2中说道,settings.js中看到固定头部配置。
现在打开侧边栏中的example=>table,像下滑动右边页面,可以看到页面上方的橡皮屑导航被划走了。
固定头部配置为true时,滑动页面橡皮屑导航固定。
定位该橡皮屑导航代码从最简单的路由’/dashboard’入手,打开对应的文件,’@/views/dashboard/index’。
打开文件,该文件模板中只要一个简单的div,对应右下块,该文件不包含侧边栏。
方向错了,回到路由文件,我发现,该路由为二级路由,一级路由导向Layout,二级路由对应的是dashboard等页面,此时可知,顶部导航栏在Layout中。
果然,在layout/index的模板中,我找到了相关代码。
<div class="main-container">
<div :class="{
'fixed-header':fixedHeader}">
<navbar /> // 顶部导航栏组件
div>
<app-main /> // 放置二级路由的组件
div>
在放置顶部导航栏组件的div中,定义了一个动态类fixed-header,我猜绑定的fixedHeader最终与我们配置的属性绑定,该类决定导航栏的固定。
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{
$sideBarWidth});
transition: width 0.28s;
}
computed: {
fixedHeader() {
return this.$store.state.settings.fixedHeader
}
}