1、官方文档
element-admin
panjiachen.gitee.io/vue-element…
element-ui
element.eleme.cn/#/zh-CN/com…
2、下载安装
集成版本(选择i8n分支,进入中文版)
git clone https://github.com.cnpmjs.org/PanJiaChen/vue-element-admin.git
基础版本
git clone https://github.com.cnpmjs.org/PanJiaChen/vue-admin-template.git
3、运行
安装依赖
npm install --registry=https://registry.npm.taobao.org
启动项目
npm run dev
4、项目结构
5、重命名项目
修改项目文件夹名称
修改package.jsom的name、description、author
和 package-lock.jsom的name
6、ElementUI中文版
找到 src/main.js
// import locale from 'element-ui/lib/locale/lang/en' // lang i18n
----------------------------------------------------------------
// Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式声明
Vue.use(ElementUI)
7、取消 ESLint 校验
找到vue.config.js
lintOnSave: false, // process.env.NODE_ENV === 'development',
8、菜单设置
-
找到src/settings.js
-
将自己的ico图标替换在 public/favicon.ico
-
找到Logo组件 src/layout/components/Sidebar/Logo.vue
data() {
return {
title: '梦学谷博客管理系统',
logo: require('@/assets/logo-new.png') // 注意不能直接写 '@/assets/logo-new.png'
}
}
- showSettings用来设置是否显示控制面板
- tagsView用来设置是否显示页面标签
9、icon(svg)
- 在阿里图标,把svg下载至src/icons/svg
- 在项目中引用
<svg-icon icon-class="password" /> // icon-class 为 icon 的名字
10、富文本tiny
- 去除默认菜单显示
<!-- 只需修改调用代码 -->
<tinymce :height="300" v-model="content" menubar=""></tinymce>
- 添加字体和字号
export default {
name: 'tinymce',
props: {
id: {
type: String
},
value: {
type: String,
default: ''
},
toolbar: {
type: Array,
required: false,
default() {
// 第一步
// 修改前
// return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright']
// 修改后
return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright | fontsizeselect | fontselect']
}
},
},
mounted() {
this.initTinymce()
},
methods: {
initTinymce() {
window.tinymce.init({
toolbar: this.toolbar,
menubar: this.menubar,
plugins: 'advlist,autolink,code,paste,textcolor,colorpicker,fullscreen,link,lists,media,wordcount,imagetools',
// 第二步,添加字号选项
fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt",
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
})
}
}
}
- 图片上传
// 在初始化时配置上传地址
window.tinymce.init({
//图片上传地址
images_upload_url: '你的服务器图片上传地址',
后端需请求参数为file
,响应location
为图片地址
11、router
- 路由白名单
// src/permission.js
const whiteList = ['/login'] // no redirect whitelist
12、面包屑 Dashboar 中文显示
在 src/components/Breadcrumb/index.vue
中修改为首页
13、伸缩菜单栏
- 去除伸缩菜单栏按钮 1、 src/layout/components/Navbar.vue 注释掉Hamburger组件
2、在/src/store/modules/app.js,把opened改成true
3、app.js中还有两处注释
14、跨域及接口
- 设置
vue.config.js
,注释mock
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
[process.env.VUE_APP_BASE_API]: {
target: process.env.VUE_APP_BASE_API,
changeOrigin: true, //配置跨域
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
}
// before: require('./mock/mock-server.js')
}
- 在
.env.development
设置VUE_APP_BASE_API
VUE_APP_BASE_API = 'http://localhost:80/php/'
- 接口请求格式
// api/article.js
import request from '../utils/request';
export function fetchList(query) {
return request({
url: '/article/list',
method: 'get',
params: query
})
}
// views/example/list
import { fetchList } from '@/api/article'
export default {
data() {
list: null,
listLoading: true
},
methods: {
fetchData() {
this.listLoading = true
fetchList().then(response => {
this.list = response.data.items
this.listLoading = false
})
}
}
}
- header请求头设置
// src/utils/request.js
if (store.getters.token) {
// 你可以自定义添加header头
config.headers['X-Token'] = getToken()
}
- php接口格式
<?php
header('Content-Type: text/html;charset=utf-8');
header('Access-Control-Allow-Origin:*'); // *代表允许任何网址请求
header('Access-Control-Allow-Methods: HEAD, GET, OPTIONS, POST, PUT');
// 设置接收的header头,可以自定义
header('Access-Control-Allow-Headers: X-Token,Content-Type, Content-Range, Content-Disposition, Content-Description');
header('Access-Control-Max-Age: 1728000');
header('Access-Control-Allow-Credentials: true');
$data = array(
'token'=> "admin-token"
);
$result = (object)array(
'code'=>20000,
'message'=>'成功',
'data'=>$data,
);
echo json_encode($result);
?>
15、请求状态码与错误提示
// src/utils/request.js
// code为成功的状态码
if (res.code !== 200) {
Message({
message: res.msg || 'Error', // msg为错误提示
type: 'error',
duration: 5 * 1000
})
16、动态菜单
- php接口格式
<?php
header('Content-Type: text/html;charset=utf-8');
header('Access-Control-Allow-Origin:*'); // *代表允许任何网址请求
header('Access-Control-Allow-Methods: HEAD, GET, OPTIONS, POST, PUT');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description');
header('Access-Control-Max-Age: 1728000');
header('Access-Control-Allow-Credentials', 'true');
$data = array(
(object)array(
'path'=> '/goods',
'component'=> 'Layout',
'redirect'=> '/goods/index',
'name'=> 'goods',
'meta'=> (object)array(
'title'=> '商品管理',
'icon'=> 'goods'
),
'children'=> array(
(object)array(
'path'=> 'list',
'component'=> "goods_list",
'name'=> 'goods_list',
'meta'=> (object)array( 'title'=> '商品列表','icon'=> 'menu' ),
),
(object)array(
'path'=> 'coop',
'component'=> "goods_coop",
'name'=> 'goods_coop',
'meta'=> (object)array(
'title'=> '正在撮合商品',
'activeMenu'=> '/project', //指定菜单高亮
'icon'=> 'menu'
)
)
)
)
);
$result = (object)array(
'code'=>200,
'message'=>'成功',
'data'=>$data,
);
echo json_encode($result);
?>
src/router/index.js
/**
* 定义替换组件的map对象
*/
export const componentMap = {
'Layout':require('@/layout').default,
'redirect_index':() => import('@/views/redirect/index').then(m=>m.default),
'login_index':() => import('@/views/login/index').then(m=>m.default),
'login_auth_redirect':() => import('@/views/login/auth-redirect').then(m=>m.default),
'error_page_404':() => import('@/views/error-page/404').then(m=>m.default),
'error_page_401':() => import('@/views/error-page/401').then(m=>m.default),
'dashboard_index':() => import('@/views/dashboard/index').then(m=>m.default),
'guide_index':() => import('@/views/guide/index').then(m=>m.default),
'icons_index':() => import('@/views/icons/index').then(m=>m.default),
//新建页面根据name替换路由
'goods_list':() => import('@/views/goods/list/index').then(m=>m.default),
'goods_coop':() => import('@/views/goods/coop/index').then(m=>m.default),
}
src/store/modules/perssion.js
// 引入componentMap和后端菜单接口
import { asyncRoutes, constantRoutes , componentMap } from '@/router'
import { getRouter } from '@/api/user'
......
// 替换route对象中的component
function replaceComponent(comp){
if(comp.component && typeof(comp.component) == 'string'){
comp.component = componentMap[comp.component]
}
if(comp.children && comp.children.length>0){
for(let i=0;i<comp.children.length;i++){
comp.children[i] = replaceComponent(comp.children[i])
}
}
return comp
}
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
// 新添加代码 start
// 接受后端菜单数据并进行处理
getRouter().then(response => {
let MyRoutes = response.data.filter(curr => {
if(curr.children == null || curr.children.length == 0){
delete curr.children
}
return replaceComponent(curr)
})
// 新添加代码 end
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = MyRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(MyRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
}) // 增加本行代码
})
}
}
- 最后去除冗余的
asyncRoutes
代码
17、菜单样式
- 设置每个字菜单的高度
src/styles/sidebar.scss
// menu hover
.submenu-title-noDropdown,
.el-submenu__title {
height: 50px; // 设置每个字菜单的高度
&:hover {
background-color: $menuHover !important;
}
}
- 设置选中菜单的颜色
src/styles/sidebar.scss
// 设置选中菜单的颜色
.el-menu-item.is-active {
background-color: #35B4B9 !important;
}
src/styles/variables.scss
设置子菜单颜色