ElementUI-Vue前端框架项目初始化
作者:高天阳
邮箱:[email protected]
更改历史
* 2018-2-25 高天阳 初始化文档
1 克隆、安装及启动
1.1 在项目中添加clone权限:
1.2 克隆项目至本地:
git clone [项目克隆地址]
code:
git clone [email protected]:zhangjiakou/zhangjiakouweb.git
1.3 安装依赖:
npm install
# 建议不要用cnpm安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
1.4 服务启动:
# 启动服务
npm run dev
2 目录结构、文件功能介绍
2.1 目录结构:
zhangjiakouweb/node_modules 项目开发依赖
zhangjiakouweb/src/router/ 框架路由配置
zhangjiakouweb/src/views/ 编写代码存放目录
zhangjiakouweb/src/lang/ i18n配置
2.2 主要文件及功能
- 框架路由配置
zhangjiakouweb/src/router/index.js 配置路由文件
- 无需修改部分
import Vue from 'vue'
import Router from 'vue-router'
const _import = require('./_import_' + process.env.NODE_ENV)
// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow.
// so only in production use lazy-loading;
// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading
Vue.use(Router)
/* Layout */
import Layout from '../views/layout/Layout'
/** note: submenu only apppear when children.length>=1
* detail see https://panjiachen.github.io/vue-element-admin-site/#/router-and-nav?id=sidebar
**/
/**
* hidden: true if `hidden:true` will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu, whatever its child routes length
* if not set alwaysShow, only more than one route under the children
* it will becomes nested mode, otherwise not show the root menu
* redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] will control the page roles (you can set multiple roles)
title: 'title' the name show in submenu and breadcrumb (recommend set)
icon: 'svg-name' the icon show in the sidebar,
noCache: true if fasle ,the page will no be cached(default is false)
}
**/
export const constantRouterMap = [
{ path: '/login', component: _import('login/index'), hidden: true },
{ path: '/authredirect', component: _import('login/authredirect'), hidden: true },
{ path: '/404', component: _import('errorPage/404'), hidden: true },
{ path: '/401', component: _import('errorPage/401'), hidden: true },
{
path: '',
component: Layout,
redirect: 'dashboard',
children: [{
path: 'dashboard',
component: _import('dashboard/index'),
name: 'dashboard',
meta: { title: 'dashboard', icon: 'dashboard', noCache: true }
}]
},
{
path: '/documentation',
component: Layout,
redirect: '/documentation/index',
children: [{
path: 'index',
component: _import('documentation/index'),
name: 'documentation',
meta: { title: 'documentation', icon: 'documentation', noCache: true }
}]
}
]
export default new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
- 需修改部分(只举其中两个代表性例子)
export const asyncRouterMap = [
{
path: '/sharedFolders', // 路径
component: Layout, // 组件
redirect: 'sharedFolders', // 定向
name: 'sharedFolders', // 名称
meta: {
title: 'sharedFolders', // 标题
icon: 'component' // 图标
},
children: [
{
path: 'fileManagement', // 子菜单路径
component: _import('sharedFolders/fileManagement'), // 组件
name: 'fileManagement', // 组件名称
meta: { title: 'fileManagement' } // 组件标题
},
{
path: 'folderManagement',
component: _import('sharedFolders/folderManagement'),
name: 'folderManagement',
meta: { title: 'folderManagement' }
},
{
path: 'capacityPassword',
component: _import('sharedFolders/capacityPassword'),
name: 'capacityPassword',
meta: { title: 'capacityPassword' }
}
]
},
{
path: '/documentCirculation', // 路径
component: Layout, // 组件
redirect: 'documentCirculation', // 定向
name: 'documentCirculation', // 名称
meta: {
title: 'documentCirculation', // 标题
icon: 'example' // 图标
},
children: [
{
path: '/documentCirculation/documentApproval', // 二级菜单路径
component: _import('documentCirculation/documentApproval/index'), // 二级菜单组件
redirect: '/documentCirculation/documentApproval/complex-table', // 二级菜单组件定向
name: 'documentApproval', // 二级菜单组件名称
meta: {
title: 'documentApproval', // 二级菜单组件标题
icon: 'table' // 二级菜单组件图标
},
children: [
{
path: 'approvalLaunched', // 三级菜单路径
component: _import('documentCirculation/documentApproval/approvalLaunched/index'), // 三级菜单组件
name: 'approvalLaunched', // 三级菜单名称
meta: { title: 'approvalLaunched' } // 三级菜单标题
},
{
path: 'branchLeaders',
component: _import('documentCirculation/documentApproval/branchLeaders/index'),
name: 'branchLeaders',
meta: { title: 'branchLeaders' }
},
{
path: 'authorityLeaders',
component: _import('documentCirculation/documentApproval/authorityLeaders/index'),
name: 'authorityLeaders',
meta: { title: 'authorityLeaders' }
},
{
path: 'deputyAttorney',
component: _import('documentCirculation/documentApproval/deputyAttorney/index'),
name: 'deputyAttorney',
meta: { title: 'deputyAttorney' }
},
{
path: 'attorneyGeneral',
component: _import('documentCirculation/documentApproval/attorneyGeneral/index'),
name: 'attorneyGeneral',
meta: { title: 'attorneyGeneral' }
},
{
path: 'documentPublishing',
component: _import('documentCirculation/documentApproval/documentPublishing/index'),
name: 'documentPublishing',
meta: { title: 'documentPublishing' }
}
]
},
{
path: '/documentCirculation/documentHis',
component: _import('documentCirculation/documentHis/index'),
redirect: '/documentCirculation/documentHis/complex-table',
name: 'documentHis',
meta: {
title: 'documentHis',
icon: 'table'
},
children: [
{
path: 'hisApprovalLaunched',
component: _import('documentCirculation/documentHis/hisApprovalLaunched/index'),
name: 'hisApprovalLaunched',
meta: { title: 'hisApprovalLaunched' }
},
{
path: 'documentReview',
component: _import('documentCirculation/documentHis/documentReview/index'),
name: 'documentReview',
meta: { title: 'documentReview' }
},
{
path: 'hisDocumentCirculation',
component: _import('documentCirculation/documentHis/hisDocumentCirculation/index'),
name: 'hisDocumentCirculation',
meta: { title: 'hisDocumentCirculation' }
},
{
path: 'documentList',
component: _import('documentCirculation/documentHis/documentList/index'),
name: 'documentList',
meta: { title: 'documentList' }
}
]
}
]
},
]
- 导航栏
wechatgame/src/app/navigation/ 导航配置
wechatgame/src/app/navigation/navigation.module.js 导航路由配置
wechatgame/src/app/navigation/navigation.controller.js 工具栏控制器配置
wechatgame/src/app/navigation/XXX/layouts 框架导航页面不同样式布局方案
一般情况下 只会修改页面样式 此次还修改了控制器 增加了一个打开关闭判定
- 工具栏
wechatgame/src/app/toolbar/ 工具栏配置
wechatgame/src/app/toolbar/toolbar.module.js 工具栏路由配置
wechatgame/src/app/toolbar/toolbar.controller.js 工具栏控制器配置
wechatgame/src/app/toolbar/XXX/layouts 工具栏页面不同样式布局方案
工具栏主要包括:LOGO、下拉列表、搜索、国际化、更多
修改了工具栏LOGO内容、登录用户姓名 注释了下拉栏多余内容、国际化、更多
2.3 安装restangular并注入
安装restangular插件
bower install --save restangular
在项目路由配置文件引入restangular
在模块路由引入restangular
在页面路由引入restangular
3 常见问题及处理
3.1 模块加载失败
- 报错提示:路由配置出现问题
- 处理方法:页面路由需配置为模块的路由
3.2 Sass安装失败报错
- 报错提示:项目无法启动,报错提示如下图
- 处理方法1:此问题需安装node-sass
npm install node-sass
- 处理方法2:此问题需查看node版本(过高或过低均会影响Sass安装 建议node-6.X.X版本)
3.3 bower、gulp命令不是内部或外部可识别的命令
npm安装bower、gulp成功,但bower install、gulp serve却提示命令不是内部或外部可识别的命令
处理方法:全局安装bower、gulp
npm install bower -g
npm install gulp -g
3.4 配置restangular失败
- 报错提示:
- 处理方法:模块路由也需要注入restangular
3.5 表格查询后出现空白效果(客户体验不好)
- 报错提示:
- 问题分析:
单页显示数据量过大 导致翻页后页面渲染位置不正确
- 处理方法:删除
ms-scroll
4 最佳实践
4.1 service注入
在项目中创建service文件
在调用公共方法的controller注入service
在controller中调用service的方法
- 注意:此样例service中引入了locals因此需要在项目中声明locals
若不引人项目会报错
4.2 datepicker汉化
- 原组件样式:
- 修改后组件样式:
- 处理方法:
/**
* 时间格式化
* @param date
*/
$mdDateLocaleProvider.months = ['一月', '二月', '三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'];
$mdDateLocaleProvider.shortMonths = $mdDateLocaleProvider.months;
$mdDateLocaleProvider.days = ['星期日','星期一', '星期二', '星期三','星期四','星期五','星期六'];
$mdDateLocaleProvider.shortDays = ['日','一', '二', '三','四','五','六'];
$mdDateLocaleProvider.monthHeaderFormatter = function(date) {
return date.getFullYear() + ' ' + $mdDateLocaleProvider.shortMonths[date.getMonth()];
};
$mdDateLocaleProvider.formatDate = function(date) {
return date? moment(date).format('YYYY-MM-DD') : '';
};
4.3 登录用户名密码存储于cookies
- 页面样式:
- cookies存储位置:
- 处理方法:
HTML:
JS:
- 核心代码
/**
* 存储cookie
*/
if(vm.isRemember){
vm.setCookie('user',vm.form.loginId,7); //保存帐号到cookie,有效期7天
vm.setCookie('pwd',vm.form.password,7); //保存密码到cookie,有效期7天
}else{
vm.setCookie('user',"",-1); //清除cookie
vm.setCookie('pwd',"",-1); //清除cookie
}
5 其他常用命令提示
5.1 引入ui-grid组件,为解决打包部署后框架文字变为韩文问题,在部署脚本写了替换css的命令。
5.2 切换分支命令(开发分支:dev)
git checkout -b dev
git branch --set-upstream dev remotes/origin/dev
5.3 安装插件:
- 查看插件是否存在于bower库
bower search [插件名称]
- 安装插件并存储于项目依赖
bower install [插件名称] --save
bower install [插件名称] -S
- 安装插件并存储于开发依赖
bower install [插件名称] --save-dev
bower install [插件名称] -D
5.4 打包项目:
gulp build 打包
6 代码结构
vm.setSearchParams = function(resetFlag){
var deferred = $q.deferred();
$q.all([1, 2]).then(function(values){
vm.search.filters = {
'table': {
'column': {
'in': values[0]
}
}
}
}, function(err){
});
Restangular().then(function(res){
deferred.resolve(res.data);
}, function(err){
deferred.reject();
});
return deferred.promise;
};
vm.search = function(){
vm.setFilters().then(function(data){
vm.process(data);
}, function(err){
console.log(err);
});
Restangular().then(function(res){
vm.process(data);
})
};
vm.process = function(data){
};
vm.item = {};
vm.loadItem = function(id){
Restangular().then(function(res){
vm.item = res.data;
})
};
vm.clearBeforeUpdate = function(){
};
vm.updateItem = function(){
vm.clearBeforeUpdate();
Restangular().post()
};
vm.columnOnChange = function(value){
};