分享一個vue專案“腳手架”專案的實現步驟
搭建緣由
源於公司每次新啟動一個由多人協同開發的專案都由負責人初始化專案之後,每個人再去從私服pull一下專案才開始開發。但是每次初始化工程都是一步步的造輪子,一個個依賴去安裝,新建一個個不同功能的資料夾,而每個負責人所初始化的專案目錄、以及模組引入方式參差不齊,以至於開發中後期因每個人開發風格的不同導致git提交時總會產生各種各樣的“衝突”,也會產生後期程式碼維護成本增加,所以就有必要考慮一下做一個統一的類似“腳手架”的功能了,用來給團隊開發帶來便捷的、統一的、易擴充套件的專案基礎。
預實現的功能
-
公共樣式統一管理,全域性sass的友好引入
-
公共js統一管理
-
解決vue腳手架初始化的部分問題
-
路由形式、介面統一管理
-
store模組化管理
-
定義vue前端專案必用的方法
-
修改好統一的config配置
-
全域性混入/指令的封裝
必要的依賴項
-
node-sass sass sass-resources sass-loader sass-recources-loader
-
vuex vuex-persistedstate
-
axios
-
babel-polyfill
專案目錄如下
配置公共sass
目錄assets>scss檔案形式
mixin.scss內容詳見mixin公共sass函式
common.scss內容如下
@import './mixin.scss'; // 公共函式
@import './icomoon.css'; //字型圖示
@import './wvue-cli.scss'; //專案公共樣式
修改utils.js
引入commom.css,就不用在main.js 或其他專案中的頁面引入了
//57行開始 function resolveResouce(name) { return path.resolve(__dirname, '../src/assets/scss/' + name); } function generateSassResourceLoader() { var loaders = [ cssLoader, // 'postcss-loader', 'sass-loader', { loader: 'sass-resources-loader', options: { // it need a absolute path resources: [resolveResouce('common.scss')] } } ]; if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else { return ['vue-style-loader'].concat(loaders) } } // 注意這裡 return { css: generateLoaders(), postcss: generateLoaders(), less: generateLoaders('less'), sass: generateSassResourceLoader(), scss: generateSassResourceLoader(), stylus: generateLoaders('stylus'), styl: generateLoaders('stylus') }
介面統一管理
js目錄下的urlConfig.js
// 開發環境用config下proxyTable的代理地址 var BASE_URL = '/api'; var isPro = process.env.NODE_ENV === 'production' if(isPro){ BASE_URL= 'http://113.113.113.113:8011' //生產環境下的地址 } const UrlConfig = { getUserInfo:BASE_URL +'user/getinfo', //獲取使用者資訊 } export default { UrlConfig };
頁面使用方式例如:
this.$http.post(this.URL_CONFIG.UrlConfig.getUserInfo,datas) .then(res =>{ console.log(res) }).catch(error =>{ console.log(error) }) // URL_CONFIG見全域性混入中的方法
全域性混入管理
全域性混入主要用於專案中每個頁面或模組都會用到的函式方法、計算屬性、過濾方法等。
檔案所屬components>common>mixins>index.js
//以下只是其中一種思路 import URL_CONFIG from '@/assets/js/urlConfig.js'; const mixin = { data(){ return { URL_CONFIG:URL_CONFIG }, methods: { //像時間戳轉換這種方法大多數專案都能用的到,可以寫在filter裡也可以寫在computed裡,取決於運用場景 formatDate(date, fmt) { if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); } let o = { 'M+': date.getMonth() + 1, 'd+': date.getDate(), 'h+': date.getHours(), 'm+': date.getMinutes(), 's+': date.getSeconds() }; for (let k in o) { if (new RegExp(`(${k})`).test(fmt)) { let str = o[k] + ''; fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : this.padLeftZero(str)); } } return fmt; }, padLeftZero(str) { return ('00' + str).substr(str.length); }, loadPage(path,params){ this.$router.push({ path:path, query:params }) } } } export default mixin
在main.js中引入
//自定義全域性mixin import mixins from '@/components/common/mixins' Vue.mixin(mixins)
全域性指令管理
全域性指令主要用於各個專案中由於vue指令不能滿足需求,自定義的指令形式,在頁面編寫過程中可以帶來很多的便利。
檔案所屬components>common>directive>index.js
//以下只是一種思路,主要目的是分享自定義指令的方法 let mydirective = {} mydirective.install = function (Vue) { //背景顏色 Vue.directive('bg', { bind(el, binding) { el.style.color = '#f6f6f6'; } }), //主題色 Vue.directive('color', { bind(el, binding) { el.style.color = '#42E5D3'; } }), Vue.directive('theme',function(el){ el.style.color = '#42E5D3' el.style.background = '#f6f6f6' }), // 圖片未載入完之前先用隨機背景色佔位 Vue.directive('img', { inserted:function (el, binding) { var color = Math.floor(Math.random()*1000000); el.style.backgroundColor = "#" + color; var img = new Image(); img.src = binding.value; img.onload = function(){ el.style.backgroundImage = 'url('+ binding.value +')' } } }) } export default mydirective;
在main.js中引入
//自定義全域性指令 import directive from '@/components/common/directive' Vue.use(directive)
store 模組化管理
store模組化管理主要是滿足不同開發人員的需求、避免使用單一store檔案導致命名衝突。同時在main裡定義了統一的模組檔案滿足大多數專案開發的場景需求。
檔案所屬store>main.js
import Vue from 'vue' import Vuex from 'vuex' import router from '@/router' import Axios from 'axios' import createPersistedState from 'vuex-persistedstate' import baseInfo_store from './baseInfo' Vue.use(Vuex) const store = new Vuex.Store({ // 用不同的模組管理vuex儲存資料 modules: { baseInfoStore: baseInfo_store, //userInfo模組 }, plugins: [createPersistedState({ storage: window.sessionStorage })] }) //切換頁面一般需要的loading動畫狀態 store.registerModule('pageSwitch', { state: { isLoading: false }, mutations: { updateLoadingStatus (state, payload) { state.isLoading = payload.isLoading } } }) //切換路由的同時切換title router.beforeEach(function (to, from, next) { if(to.meta.title){ document.title = to.meta.title } store.commit('updateLoadingStatus', {isLoading: true}) next() }) router.afterEach(function (to) { store.commit('updateLoadingStatus', {isLoading: false}) }) //ajax請求的動畫狀態 store.registerModule('ajaxSwitch', { state: { ajaxIsLoading: false, ajaxIsPrompt: false, }, mutations: { ajaxStar (state) { state.ajaxIsLoading = true }, ajaxEnd (state) { state.ajaxIsLoading = false }, ajaxPromptShow (state) { state.ajaxIsPrompt = true }, ajaxPromptHide (state) { state.ajaxIsPrompt = false } }, getter : { ajaxIsLoading: state => state.ajaxIsLoading } }) //請求攔截 Axios.interceptors.request.use(config => { store.commit('ajaxStar') return config; }) //響應攔截 Axios.interceptors.response.use(config => { //需要攔截的請求頭 return config }) export default store;
在main.js引入
import store from '@/store/main.js';
main.js的最終形式
import Vue from 'vue' import App from './App' import router from './router' import axios from 'axios'; import "babel-polyfill";import store from '@/store/main.js';//自定義全域性mixin import mixins from '@/components/common/mixins' Vue.mixin(mixins)//自定義全域性指令 import directive from '@/components/common/directive' Vue.use(directive) Vue.config.productionTip = false Vue.prototype.$http = axios; /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
解決vue-cli 初始配置的打包路徑問題
其實這個在上面檔案中已經有體現了,在這裡再次提及一下。
步驟1:修改config>index.js檔案
將build{ }下的assetsPublicPath改為如下
assetsPublicPath: './',
步驟2:修改build>utils.js檔案
找到 fallback: 'vue-style-loader',在其下加入下面這一行
publicPath: '../../'
結語
至此,一個基本完備的vue專案“腳手架”就完成了,以後每次初始化專案都可以按照這套方案來進行,省去了很多協作開發的交流環節,形成了能夠滿足大多數專案的目錄及檔案構成形式,將此專案託管至私服每次初始化專案只需拉取這個“腳手架”便能省區不少初始化專案的時間,豈不美哉!
此“腳手架”專案已開源至github,歡迎大家提出建議和互相交流,同時也可隨意將專案拉下來進行使用。
您可能感興趣的文章:
文章同步釋出: https://www.geek-share.com/detai