前言:通常咱們在建立vue項目的時候比較多的採用官方的vue-cli2腳手架去構建項目,通常來講這種模式建立的項目也不須要過多的配置便可使用,可是有一個痛點就是每一個項目都須要從新構建和配置,那有沒有一種方式能夠省去這些繁瑣的過程呢,好比說咱們有兩個一樣的項目,使用的都是vue框架,或者說咱們以前配置好的一些項目咱們想拿過來直接用。今天咱們就聊一聊如何去基於vue構建一套可複用,靈活配置的框架,保證咱們在須要使用是直接拿過來就能夠用 。css
整體來講咱們須要考慮三點:vue
1、接口api的管理
首先咱們說說接口api如何統一的管理起來,在調用的時候能方便快捷,而且能減小http的請求,優化使用體驗和節省資源。ios
目前vue-cli3已經更新使用很長時間了,建議你們使用vue-cli3腳手架去構建項目
咱們再封裝好axios請求的時候就應該考慮api如何去統一的管理起來,這對項目的優化層面來講很是重要,由於管理api能夠很大的減小http的請求來節省服務資源提高響應速度。git
例如咱們這樣作,新建一個api文件,在api文件下新建index.js專門存放後期須要使用到的接口:github
import request from '@/request/axios'//這個就是咱們封裝好的axios文件 var ENV =process.env.NODE_ENV var Tenv; ENV=='development'?Tenv='/api':Tenv='' // 接口封裝請求示例 export const getDiaryList = (pageIndex,pageSize) => { return request({ url: Tenv+'/getDiaryList/list', method: 'get', params: { pageIndex:pageIndex, pageSize:pageSize, } }) }
順便貼上個人axios的封裝代碼:vue-router
/** * http配置 * axios參數說明 */ import axios from 'axios' import NProgress from 'nprogress'//這是導航欄的請求狀態動畫插件,具體見下圖 import 'nprogress/nprogress.css' axios.defaults.timeout = 10000; //返回其餘狀態嗎 axios.defaults.validateStatus = function (status) { return status >= 200 && status <= 500; // 默認的 }; //跨域請求,容許保存cookie axios.defaults.withCredentials = true; NProgress.configure({ showSpinner: false }); //HTTPrequest攔截 axios.interceptors.request.use(config => { NProgress.start(); const meta = (config.meta || {}); const isToken = meta.isToken === false; //headers中配置serialize爲true開啓序列化 return config }, error => { return Promise.reject(error) }); //HTTPresponse攔截 axios.interceptors.response.use(res => { NProgress.done(); const status = res.data.code || 200; const message = res.data.msg || '未知錯誤'; if (status !== 200) { return Promise.reject(new Error(message)) } return res; }, error => { NProgress.done(); return Promise.reject(new Error(error)); }); export default axios;
NProgress就是作這個事的,固然不要也能夠,由於我這是一個後臺管理系統:
這樣一來,咱們有多個api的話能夠直接管理起來,或者有多個類型的也能夠分文件存放,用的話只須要引入就能夠了,由於們發現好多初學者都直接在頁面內每次都調用axios.get這樣的方式vuex
頁面引入api文件:vue-cli
import {getDiaryList} from '@/api/index' //能夠是一個對象下面有多個
使用:json
getDiaryList(pageIndex,pageSize){ getDiaryList(pageIndex,pageSize).then(res=>{ // 請求成功處理 console.log(res.data) }).catch(res=>{ //請求失敗處理 console.log('請求失敗') }) },
2、路由的管理
爲何要作路由的管理呢,路由能夠說是vue的靈魂所在,以前我就接手過一個項目,全部的路由所有在router下index的文件裏寫着,也沒有父子之分,使用查找起來極爲不方便。
關於路由的管理,咱們能夠在router下新建一個文件夾專門去管理路由,好比說這個文件夾名叫RouterPage,咱們能夠分模塊分頁面去管理,好比說咱們能夠在RouterPage下新建一個index.js管理公用、分模塊的頁面路由,這樣在使用上也能夠方便不少,管理上也輕鬆了許多,不至於咱們下次交給別人的時候一臉茫然。
好比咱們的RouterPage下index.js文件能夠是這樣的:axios
/**路由頁面配置文件**/ export default [ { path: "/", redirect: '/index',}, { path: '/index', name: '首頁', component: () => import( '@/views/index'), meta: { requireAuth: true},//是否檢查登陸, children:[ { path:'/', name:'登陸頁', component: () => import( '@/views/home'), }, ] }, { path: '/login', name: '登陸頁', component: () => import( '@/views/login'), meta: { requireAuth: false} }, ]
咱們在router下的index.js文件直接import再添加路由加可使用了,在上面RouterPage下的index.js咱們能夠去配置公用的、模塊的等各類路由;
import Vue from 'vue' import VueRouter from 'vue-router' import RouterPage from './RouterPage/'//引入我能建立的RouterPage文件名, Vue.use(VueRouter) const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, }) router.addRoutes([...RouterPage]);//添加路由 export default router
還有一點我覺的在封裝的是確定會考慮到,項目也確定會用到,就是檢查當前打開的頁面用戶是否登陸、是否須要登陸,能夠根據路由的全局監測去控制,能夠在src目錄下新建一個inspect.js文件專門去管理控制:
import router from './router' import Cookies from 'js-cookie'//操做cookie的插件 router.beforeEach((to, from, next) => { //Cookies.set('isAuth', 'iii', { expires: 1 }); //to.matched.some(record => record.meta.requireAuth)這個就是咱們再路由中設置的meta下requireAuth的屬性,爲true即表示須要判斷是否登陸,爲false就不用判斷 if (to.matched.some(record => record.meta.requireAuth)) { if (Cookies.get('isAuth')) { //判斷的條件能夠自定,我這裏是cookie判斷,登陸了會存儲isAuth if (to.fullPath == '/login') { } else { next() } } else { next({ path: '/login', query: { redirect: to.fullPath } }) } } else { Cookies.remove('isAuth'); next() } })
而後把這個文件在main.js全局引入就能夠了,就能夠實現路由變化是監測用戶是否登陸或者登陸是否過時。
3、公用數據的管理
關於公用數據的管理,官方已經提供了一種完美的方法,就是vuex狀態數據管理,這個我有一篇文章專門說過若是去使用vuex,不會的能夠去看看。
vuex使用教程
固然還有另一種方法,就是json數據管理方法,這種的話也能夠實現本地公用數據的管理,但我仍是建議使用官方的vuex。
好比說咱們有一個導航,須要去作本地菜單的預配置,我爲何不採用vuex的緣由是,有可能咱們菜單會有二級三級甚至四級放在vuex裏或比較影響數據的直觀性,那麼咱們能夠這樣作,建立一個nav.config.js:
let results={ title:'管理平臺', icon:'el-icon-s-platform', tab:[ {name:'導航1',path:'/index/login','icon':'el-icon-s-check',children:[ {name:'子集',path:'/','icon':'el-icon-s-check'}, {name:'子集1',path:'/','icon':'el-icon-s-check'}, {name:'子集2',path:'/','icon':'el-icon-s-check'}, {name:'子集3',path:'/','icon':'el-icon-s-check'}, {name:'子集4',path:'/','icon':'el-icon-s-check'}, ]}, {name:'導航7',path:'/index/home','icon':'el-icon-s-check'}, {name:'用戶管理',path:'/index/login','icon':'el-icon-menu',children:[ {name:'子集1',path:'/','icon':'el-icon-s-check'}, {name:'子集1',path:'/','icon':'el-icon-s-check'}, {name:'子集2',path:'/','icon':'el-icon-s-check',children:[ {name:'子集11',path:'/','icon':'el-icon-s-check'}, {name:'子集12',path:'/','icon':'el-icon-s-check'}, {name:'子集23',path:'/','icon':'el-icon-s-check'}, {name:'子集34',path:'/','icon':'el-icon-s-check'}, {name:'子集45',path:'/','icon':'el-icon-s-check'}, ]}, {name:'子集3',path:'/','icon':'el-icon-s-check'}, {name:'子集4',path:'/','icon':'el-icon-s-check'}, ]}, {name:'導航9',path:'/index/login','icon':'el-icon-s-check'}, {name:'導航10',path:'/index/login','icon':'el-icon-s-check'} ] } export default { results }
而後在須要的文件引入或者賦值給vuex的state上:
import navConfig from'../nav.config' data(){ return { tabResults:navConfig.results, } },
這樣咱們就能夠直接在特定的文件去使用this.tabResults去操做或者頁面直接綁定使用了,也是很是的方便,多用於本地菜單的配置,能夠靈活管理,如:
4、公用方法的管理
公用方法的管理其實可公用數據的管理差很少的,vuex也能夠實現,可是咱們通常的仍是習慣於管理在公用的方法文件中,達到直觀、方便、靈活的效果。
好比咱們能夠新建一個utils.js:
/** * 日期格式化 */ export function dateFormat(date, format) { format = format || 'yyyy-MM-dd hh:mm:ss'; if (date !== 'Invalid Date') { let o = { "M+": date.getMonth() + 1, //month "d+": date.getDate(), //day "h+": date.getHours(), //hour "m+": date.getMinutes(), //minute "s+": date.getSeconds(), //second "q+": Math.floor((date.getMonth() + 3) / 3), //quarter "S": date.getMilliseconds() //millisecond } if (/(y+)/.test(format)) format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); for (let k in o) if (new RegExp("(" + k + ")").test(format)) format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); return format; } return ''; } /** * Json強轉爲Form類型 * @param obj * @returns {FormData} */ export function toFormData(obj) { const data = new FormData(); Object.keys(obj).forEach(key => { data.append(key, Array.isArray(obj[key]) ? obj[key].join(',') : obj[key]); }); return data; }
能夠在main.js分別引入或者所有引入
分別引入,只使用一個或多個方法:
import { toFormData } from './utils'
所有引入:
import Utils from './utils' //使用 Utils.toFormData(obj)
總結:以上呢咱們從四個方面說了下如何封裝屬於本身的可複用的vue框架,比較建議的作法的就是封裝好一個保存起來,能夠放在阿里code上也能夠放在github上,這樣咱們下次再使用的時候直接dowm下來作基本的代理或者域名配置就能夠,能極大的節省不少時間,避免重複的工做。
好了我是不浪熊,歡迎你們關注個人博客小程序(目前在正在完善),咱們一塊兒學歷交流,一塊兒進步成長。
小程序碼:
或者微信搜太小程序「知付博客」體驗
知付博客官網