這裏準備採用的技術棧爲:vue全家桶+element-uicss
這裏由於是後臺管理系統,沒有作SSR的必要。因此這裏就採用先後端分離來昨晚這個項目~html
vue init webpack gwc_manage
這裏不選擇安裝eslint和測試單元。用過的人應該知道很是酸爽。前端
項目初始化成功後,vue
npm run dev
能夠看到項目成功運行在8080端口。我麼就能夠打開8080端口查看咱們搭建好的項目webpack
上圖所述,就是vue初始化後的頁面。ios
npm install less less-loader -s
注:後面的-s表示本地安裝-g表示全局安裝,不些則表示默認本地安裝web
由於使用了less後,我的通常喜歡將整個項目的配色進行一個管理。因此須要進行全局的配置。vue-router
這裏安裝完成後,繼續安裝vuex
npm install sass-resources-loader --save-dev
接下來,咱們找到build文件夾下的utils文件npm
exports.cssLoaders = function (options) {}中加上一下代碼:
function lessResourceLoader() { var loaders = [ cssLoader, 'less-loader', { loader: 'sass-resources-loader', options: { resources: [ path.resolve(__dirname, '../src/assets/styles/common.less'), ] } } ]; if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else { return ['vue-style-loader'].concat(loaders) } }
注意位置必定要加對,且記得把path.resolve(__dirname,'../src/assets/styles/common.less')
路徑改爲本身對應的文件。而後後面將 return{} 塊中的 less: generateLoaders('less')
替換成上面自定義的函數 less: lessResourceLoader();
修改完配置文件記得重啓服務器:npm run dev
給你們上圖看一下主要配置:
重啓服務後,基本就配置完成。不過咱們仍是的檢測一下。
@bg-blue: #3576e0;
在App.vue中修改
<style lang="less" scoped> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; background-color: @bg-blue; } </style>
而後保存,打開瀏覽器。就能夠看到咱們配置好的全局變量被成功引用
背景色變成藍色。說明在common.less中定義的變量被正常調用。這裏全局的less配置也就成功了。
項目搭建好了,可是能夠看到一些基本的樣式須要咱們進行更改
assets文件夾下styles文件中新建base.less文件。百度搜索reset.css而後複製文中的基本樣式,並添加html,body寬高爲100%便可。
新建function.less文件css樣式工具封裝在文中找到適合本身項目的文件複製並粘貼金function.less文件。
新建index.css文件做爲出口文件。文件內容以下:
@import './base.less';
@import './function.less';
在main.js文件中引入index.css文件
至此引入的基本的樣式文件就算被全局引用了。
至於封裝的function樣式類,咱們只須要在須要的時候,選擇性的 添加類名便可。
npm install element-ui -s
安裝完成後,在main.js中引入
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI);
安裝完成後,修改App.vue:
<template> <div id="app"> <img src="./assets/logo.png"> <el-button type="danger">測試Element</el-button> <router-view/> </div> </template>
打開瀏覽器,咱們能夠看到button按鈕是已經生效了。
這裏,element-ui也已經安裝成功。
在src文件夾下新建utils文件夾新建http.js爲咱們的請求方法的文件
封裝前,咱們須要藉助axios來做爲請求的底層,而且須要緩存機制去緩存登陸狀態
這裏藉助兩個依賴包 axios和vue-cookies
npm install axios vue-cookies -s
這裏封裝三個類型的。get請求一個post,json格式的一個post,body格式的一個
import axios from 'axios' import Vue from 'vue' // 請求方式的配置 export const postJsonRequest = (url, params) => { return axios({ method: 'post', url: url, data: params, headers: { 'Content-Type': 'application/json', }, }); } export const postRequest = (url, params) => { return axios({ method: 'post', url: url, data: params, transformRequest: [function (data) { let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }], headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); } export const getRequest = (url, data = {}) => { return axios({ method: 'get', params: data, url: url, }); }
這個就是請求方法的配置
隨後咱們在utils目錄下新建index.js文件做爲工具文件夾的出口文件
引入封裝的http請求並掛在到Vue原型鏈上供全局使用
import * as http from './http'; const install = (Vue, opts = {}) => { if (install.installed) return; Vue.prototype.$http = http; } export default install
main.js
import Utils from './utils';
Vue.use(Utils);
這裏方法請求的封裝就算是完成了。
攔截器的配置
攔截器:登陸狀態的管理,以及每次請求時,咱們作的一些處理。對不一樣code狀態作的不一樣的處理
攔截器分爲請求攔截器和響應攔截器。字面意思可理解爲:請求時的攔截和響應時的攔截
import axios from 'axios' import { Message } from 'element-ui' import router from 'vue-router' import Vue from 'vue' import VueCookies from 'vue-cookies' // 請求攔截 axios.interceptors.request.use(config => { if (VueCookies.isKey('isLogin')) { const token = getToken(config); config.headers['token'] = token; } return config; }, err => { Message.error({ message: '請求超時!' }); return Promise.resolve(err); }) // 響應攔截 axios.interceptors.response.use(res => { switch (res.data.code) { case 200: return res.data.result; case 401: Message.error({ message: res.data.message }); router.push('/login'); VueCookies.remove('userinfo'); return Promise.reject(res); case 201: Message.error({ message: res.data.message }); case 403: Message.warning({ message: res.data.message }); return Promise.reject(res); default: return Promise.reject(res); } }, err => { if (!err.response) { return false; } switch (err.response.status) { case 500: Message.error({ message: '服務器出小差了⊙﹏⊙∥' }); break; case 504: Message.error({ message: '服務器被吃了⊙﹏⊙∥' }); break; case 404: Message.error({ message: '服務器被吃了⊙﹏⊙∥' }); break; case 403: Message.error({ message: '權限不足,請聯繫管理員!' }); break; default: Message.error({ message: '網絡超時' }); } return Promise.reject(err); })
Vue攔截器的基本配置也就是以上這些了。下來我的想要實現一個loading的局部加載。就要藉助計數器了。
爲何說要作一個計數器?
//請求時loading配置 var loading; function startLoading() { loading = Vue.prototype.$loading({ lock: true, text: "Loading...", background: 'rgba(0, 0, 0, 0.5)', target: document.querySelector('.loading-area') //設置加載動畫區域 }); } function endLoading() { loading.close(); } var needLoadingRequestCount = 0; //開啓loading並計數 function showFullScreenLoading() { if (needLoadingRequestCount === 0) { startLoading(); } needLoadingRequestCount++; }; //計數器==0關閉loading function tryHideFullScreenLoading() { if (needLoadingRequestCount <= 0) return; needLoadingRequestCount--; if (needLoadingRequestCount === 0) { endLoading(); } };
loading的依賴在element安裝後是直接掛在到了vue的原型鏈上。咱們再也不須要作過多處理。這裏計數器完成。下來咱們只須要在請求的時候調用,在響應的時候或者請求報錯的時候調用關閉的方法便可。
須要注意的是要實現局部的加載,咱們就須要在響應實現loading的地方添加類型loading-area才能夠!!!
http.js全部代碼以下:
/** * @description 配置網絡請求 * @author luokaibin chaizhiyang */ import axios from 'axios' import { Message } from 'element-ui' import router from 'vue-router' import Vue from 'vue' import VueCookies from 'vue-cookies' axios.defaults.timeout = 300000; // 請求超時5fen //請求時loading配置 var loading; function startLoading() { loading = Vue.prototype.$loading({ lock: true, text: "Loading...", background: 'rgba(0, 0, 0, 0.5)', target: document.querySelector('.loading-area') //設置加載動畫區域 }); } function endLoading() { loading.close(); } var needLoadingRequestCount = 0; function showFullScreenLoading() { if (needLoadingRequestCount === 0) { startLoading(); } needLoadingRequestCount++; }; function tryHideFullScreenLoading() { if (needLoadingRequestCount <= 0) return; needLoadingRequestCount--; if (needLoadingRequestCount === 0) { endLoading(); } }; // 請求攔截 axios.interceptors.request.use(config => { showFullScreenLoading(); if (VueCookies.isKey('userinfo')) { const token = getToken(config); config.headers['token'] = token; } return config; }, err => { tryHideFullScreenLoading(); Message.error({ message: '請求超時!' }); return Promise.resolve(err); }) // 響應攔截 axios.interceptors.response.use(res => { tryHideFullScreenLoading(); switch (res.data.code) { case 200: return res.data.result; case 401: Message.error({ message: res.data.message }); router.push('/login'); // VueCookies.remove('userinfo'); return Promise.reject(res); case 201: Message.error({ message: res.data.message }); case 403: Message.warning({ message: res.data.message }); return Promise.reject(res); default: return Promise.reject(res); } }, err => { tryHideFullScreenLoading(); if (!err.response) { return false; } switch (err.response.status) { case 500: Message.error({ message: '服務器出小差了⊙﹏⊙∥' }); break; case 504: Message.error({ message: '服務器被吃了⊙﹏⊙∥' }); break; case 404: Message.error({ message: '服務器被吃了⊙﹏⊙∥' }); break; case 403: Message.error({ message: '權限不足,請聯繫管理員!' }); break; default: Message.error({ message: '網絡超時' }); } return Promise.reject(err); }) // 請求方式的配置 export const postJsonRequest = (url, params) => { return axios({ method: 'post', url: url, data: params, headers: { 'Content-Type': 'application/json', }, }); } export const postRequest = (url, params) => { return axios({ method: 'post', url: url, data: params, transformRequest: [function (data) { let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }], headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); } export const getRequest = (url, data = {}) => { return axios({ method: 'get', params: data, url: url, }); }
至此整個的全局loading,攔截器,fetch方法的封裝就算完成了。
element-ui的使用,咱們要多借助官方文檔去靈活使用。而不是死記硬背。太多的ui框架,再強的大腦也背不過來,況且,爲了本身的頭髮着想一下啦~
這裏並未設置跨域訪問。你們能夠根據vue的代理。這樣也是能夠進行跨域訪問的。詳見個人這篇博文Vue設置代理進行跨域訪問,不過這篇文章是針對vue3.0設置,2.0的設置文件,爲config下的index.js文件。固然前提是後端接口也進行跨域的設置,不然單純的前端設置是沒有做用的。
局部loading的使用,要求有一個好的佈局基礎。不然,在後期的使用過程當中,會有喝多樣式錯亂的問題。
請求方式有不少種,還有下載文件的請求配置,delete,post,put等等你們可根據本身需求靈活配置。最終的使用this.$http. get/post/put/...等等就能夠進行調用
底層佈局(Layout),路由(Router),狀態庫(vuex),Github倉庫關聯。
敬請期待~