项目介绍
基于vue-cli@2.0的常用配置,代码切换到vuecli@2.0分支查看;
后期基于vue-cli@3.0进行配置优化,具体查看基于vue-cli@3.0搭建管理系统项目并进行配置优化
基于vue2.0项目开发中的一些思路
主要包括:
使用脚手架初始化项目
将需要用到的工具函数新建一个utils文件夹统一管理
使用router的一些优化
使用Vuex的一些优化
封装axios及统一管理api
# 在项目目录和server目录分别进行安装依赖
git clone git@github.com:crui14994/Vue_Init-Config.git
# 在项目目录和server目录分别进行安装依赖
cnpm install
# 运行项目
npm run dev
使用脚手架初始化项目
# 安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 用cnpm 命令安装vue-cli了,在命令行输入下面的命令:
cnpm install vue-cli -g
# 用vue init命令来初始化项目
vue init webpack-simple Vue_Init-Config
# 在项目目录和server目录分别进行安装依赖
cnpm install
# 运行项目
npm run dev
将需要用到的工具函数新建一个utils文件夹统一管理
在根目录新建一个utils文件夹
-
在文件夹下新建index.js用于几种管理工具函数
export default { storage: require('./storage.js').default, //本地存储localStorage formatDate: require('./formatDate.js').default, //日期格式化 }
-
编写工具函数导出右index.js导入
/** formatDate.js * 格式化日期 * @param {string} str 需要格式化的样子 * @param {String|Date} day 日期对象或者日期字符串 * @return {String} * @template formatDate('YYYY年mm月dd日hh小时ff分钟ss秒 星期w','2017/1/1 12:13:14') 返回:2017年01月01日12小时13分钟14秒 星期日; */ function formatDate (str, day) { let d, arr let type = Object.prototype.toString.call(day) if (type === '[object Date]') { d = day } else if (type === '[object String' && (arr = day.match(/(\d{4})[-/](\d{1,2})[-/](\d{1,2})(?:\s+(\d{1,2}):(\d{1,2}):(\d{1,2}))?/))) { arr = arr.slice(0, arr[4] ? 7 : 4) arr[2] = arr[2] - 1 d = new (Function.prototype.bind.apply(Date, arr))() } else { return '' } const obj = { 'yyyy': d.getFullYear(), 'yy': ('' + d.getFullYear()).slice(-2), 'm': d.getMonth() + 1, 'mm': ('0' + (d.getMonth() + 1)).slice(-2), 'd': d.getDate(), 'dd': ('0' + d.getDate()).slice(-2), 'h': d.getHours(), 'hh': ('0' + d.getHours()).slice(-2), 'f': d.getMinutes(), 'ff': ('0' + d.getMinutes()).slice(-2), 's': d.getSeconds(), 'ss': ('0' + d.getSeconds()).slice(-2), 'w': ['日', '一', '二', '三', '四', '五', '六'][d.getDay()] } return ('' + str).replace(/([a-z]+)/ig, function (k) { return obj[k.toLowerCase()] || '' }) } export default formatDate
/*storage.js *本地存储localStorage */ class Storage { constructor () { this.storage = window.localStorage this.prefix = 'mytest_' //给key家一个前缀 } set (key, value, fun) { if (typeof value !== 'string') { try { value = JSON.stringify(value) } catch (e) { } } this.storage.setItem(this.prefix + key, value) typeof fun === 'function' && fun() } get (key, fun) { let value = this.storage.getItem(this.prefix + key) try { value = JSON.parse(value) if (value === null) value = {} } catch (e) { value = {} } return typeof fun === 'function' ? fun.call(this, value) : value } remove (key) { this.storage.removeItem(this.prefix + key) } cle() { this.storage.clear(); } } export default new Storage() ```
-
在main.js中把通用方法挂载到Vue原型上在组件中只需使用this即可使用相关的函数
import utils from "./utils/index" //导入工具函数 // 把通用方法挂载到Vue原型上 Vue.prototype.$formatDate = utils.formatDate Vue.prototype.$storage = utils.storage
-
在组件中使用
computed:{ dateNow(){ return this.$formatDate('YYYY年mm月dd日hh小时ff分钟ss秒 星期w',new Date()) } }
使用vue-router的一些优化(代码中只提供思路;没有具体实现)
-
在根目录新建一个router文件夹;安装vue-router
cnpm install vue-router --save-dev
-
在文件夹下新建index.js和route.js两个文件
在index.js中对路由进行配置;
在route.js中对各个路径进行配置(具体参考源码)
import Vue from 'vue'; import VueRouter from 'vue-router'; import { routers } from './route'; // import { Loading } from 'element-ui'; // import { setTitle } from 'src/assets/js/util'; Vue.use(VueRouter); const routerConfig = { mode: 'history', linkActiveClass: 'active', routes: routers }; const router = new VueRouter(routerConfig); // let loading; // router.beforeEach((to, form, next) => { // loading = Loading.service({ // // fullscreen: true, // target: '.content-wrapper', // text: '跳转中...' // }); // // 设置window.document.title 的名称 // setTitle(to.meta.title); // if (!to.matched.length) { // next({ // path: '/error/404', // replace: true // }); // } else { // next(); // } // }); // router.afterEach((to, from) => { // // 解决某些情况下loading无法关闭的情况 // setTimeout(() => { // loading.close(); // }, 0) // }); export default router;
-
在main.js中引入router
import router from './router/index';
使用Vuex的一些优化
-
在根目录新建一个store文件夹;安装vue-router
cnpm install vuex --save
-
在文件夹下新建index.js和user.js两个文件
在index.js引入我们的vue和vuex
在user.js中定义user需要使用到的状态
//index.js import Vue from 'vue'; import Vuex from 'vuex'; import user from './user'; Vue.use(Vuex); export default new Vuex.Store({ modules: { user } });
//user.js import utils from "./../utils/index"; const state = { //token token: utils.storage.get("token") }; const mutations = { setToken(state, data) { state.token = data; } }; export default { state, mutations };
-
在main.js中引入router
//sotre import store from "./store/index";
封装axios;统一管理api
-
在utils下新建axios.js文件
import axios from 'axios' // import { Message } from 'element-ui' //sotre import store from "./../store/index"; import qs from 'qs' // 序列化请求数据,视服务端的要求 // 创建axios实例 const service = axios.create({ //这里baseurl就是刚开始配置的开发环境和线上环境地址,webpack会自动读取无需手动再改 baseURL: process.env.BASE_URL, //baseurl timeout: 5000 // 请求超时时间 }) // request拦截器 service.interceptors.request.use(config => { // Tip: 1 // 请求开始的时候可以结合 vuex 开启全屏的 loading 动画 // Tip: 2 // 带上 token , 可以结合 vuex 或者重 localStorage // if (store.getters.token) { // config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 // } else { // // 重定向到登录页面 // } // Tip: 3 // 根据请求方法,序列化传来的参数,根据后端需求是否序列化 if (config.method.toLocaleLowerCase() === 'post' || config.method.toLocaleLowerCase() === 'put' || config.method.toLocaleLowerCase() === 'delete') { config.data = qs.stringify(config.data) } return config }, error => { // 请求错误时做些事(接口错误、超时等) // Tip: 4 // 关闭loadding console.log('request:', error); return Promise.reject(error) // 在调用的那边可以拿到(catch)你想返回的错误信息 }) // respone拦截器 service.interceptors.response.use( response => response, /** * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页 * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中 */ // const res = response.data; // if (res.code !== 20000) { // Message({ // message: res.message, // type: 'error', // duration: 5 * 1000 // }); // // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; // if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { // confirmButtonText: '重新登录', // cancelButtonText: '取消', // type: 'warning' // }).then(() => { // store.dispatch('FedLogOut').then(() => { // location.reload();// 为了重新实例化vue-router对象 避免bug // }); // }) // } // return Promise.reject('error'); // } else { // return response.data; // } error => { console.log('err' + error)// for debug // Message({ // message: error.message, // type: 'error', // duration: 5 * 1000 // }) return Promise.reject(error) }) export default service
-
在src下新建目录api和user.js文件
import service from "./../utils/axios"; export function mock(apiRouter) { return service({ url: "https://easy-mock.com/mock/5c9c8e9ba0feb92705bf12b7/example/"+apiRouter, method: "get", }); }
-
在组件中的使用
import { mock } from "./api/user"; created() { mock("mock").then(response => { this.reponseData = response.data; }); }