您好,登錄后才能下訂單哦!
搭建緣由
源于公司每次新啟動(dòng)一個(gè)由多人協(xié)同開(kāi)發(fā)的項(xiàng)目都由負(fù)責(zé)人初始化項(xiàng)目之后,每個(gè)人再去從私服pull一下項(xiàng)目才開(kāi)始開(kāi)發(fā)。但是每次初始化工程都是一步步的造輪子,一個(gè)個(gè)依賴去安裝,新建一個(gè)個(gè)不同功能的文件夾,而每個(gè)負(fù)責(zé)人所初始化的項(xiàng)目目錄、以及模塊引入方式參差不齊,以至于開(kāi)發(fā)中后期因每個(gè)人開(kāi)發(fā)風(fēng)格的不同導(dǎo)致git提交時(shí)總會(huì)產(chǎn)生各種各樣的“沖突”,也會(huì)產(chǎn)生后期代碼維護(hù)成本增加,所以就有必要考慮一下做一個(gè)統(tǒng)一的類似“腳手架”的功能了,用來(lái)給團(tuán)隊(duì)開(kāi)發(fā)帶來(lái)便捷的、統(tǒng)一的、易擴(kuò)展的項(xiàng)目基礎(chǔ)。
預(yù)實(shí)現(xiàn)的功能
必要的依賴項(xiàng)
項(xiàng)目目錄如下
配置公共sass
目錄assets>scss文件形式
mixin.scss內(nèi)容詳見(jiàn)mixin公共sass函數(shù)
common.scss內(nèi)容如下
@import './mixin.scss'; // 公共函數(shù)
@import './icomoon.css'; //字體圖標(biāo)
@import './wvue-cli.scss'; //項(xiàng)目公共樣式
修改utils.js
引入commom.css,就不用在main.js 或其他項(xiàng)目中的頁(yè)面引入了
//57行開(kāi)始 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') }
接口統(tǒng)一管理
js目錄下的urlConfig.js
// 開(kāi)發(fā)環(huán)境用config下proxyTable的代理地址 var BASE_URL = '/api'; var isPro = process.env.NODE_ENV === 'production' if(isPro){ BASE_URL= 'http://113.113.113.113:8011' //生產(chǎn)環(huán)境下的地址 } const UrlConfig = { getUserInfo:BASE_URL +'user/getinfo', //獲取用戶信息 } export default { UrlConfig };
頁(yè)面使用方式例如:
this.$http.post(this.URL_CONFIG.UrlConfig.getUserInfo,datas) .then(res =>{ console.log(res) }).catch(error =>{ console.log(error) }) // URL_CONFIG見(jiàn)全局混入中的方法
全局混入管理
全局混入主要用于項(xiàng)目中每個(gè)頁(yè)面或模塊都會(huì)用到的函數(shù)方法、計(jì)算屬性、過(guò)濾方法等。
文件所屬components>common>mixins>index.js
//以下只是其中一種思路 import URL_CONFIG from '@/assets/js/urlConfig.js'; const mixin = { data(){ return { URL_CONFIG:URL_CONFIG }, methods: { //像時(shí)間戳轉(zhuǎn)換這種方法大多數(shù)項(xiàng)目都能用的到,可以寫(xiě)在filter里也可以寫(xiě)在computed里,取決于運(yùn)用場(chǎng)景 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)
全局指令管理
全局指令主要用于各個(gè)項(xiàng)目中由于vue指令不能滿足需求,自定義的指令形式,在頁(yè)面編寫(xiě)過(guò)程中可以帶來(lái)很多的便利。
文件所屬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' }), // 圖片未加載完之前先用隨機(jī)背景色占位 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模塊化管理主要是滿足不同開(kāi)發(fā)人員的需求、避免使用單一store文件導(dǎo)致命名沖突。同時(shí)在main里定義了統(tǒng)一的模塊文件滿足大多數(shù)項(xiàng)目開(kāi)發(fā)的場(chǎng)景需求。
文件所屬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存儲(chǔ)數(shù)據(jù) modules: { baseInfoStore: baseInfo_store, //userInfo模塊 }, plugins: [createPersistedState({ storage: window.sessionStorage })] }) //切換頁(yè)面一般需要的loading動(dòng)畫(huà)狀態(tài) store.registerModule('pageSwitch', { state: { isLoading: false }, mutations: { updateLoadingStatus (state, payload) { state.isLoading = payload.isLoading } } }) //切換路由的同時(shí)切換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請(qǐng)求的動(dòng)畫(huà)狀態(tài) 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 } }) //請(qǐng)求攔截 Axios.interceptors.request.use(config => { store.commit('ajaxStar') return config; }) //響應(yīng)攔截 Axios.interceptors.response.use(config => { //需要攔截的請(qǐng)求頭 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 初始配置的打包路徑問(wèn)題
其實(shí)這個(gè)在上面文件中已經(jīng)有體現(xiàn)了,在這里再次提及一下。
步驟1:修改config>index.js文件
將build{ }下的assetsPublicPath改為如下
assetsPublicPath: './',
步驟2:修改build>utils.js文件
找到 fallback: 'vue-style-loader',在其下加入下面這一行
publicPath: '../../'
結(jié)語(yǔ)
至此,一個(gè)基本完備的vue項(xiàng)目“腳手架”就完成了,以后每次初始化項(xiàng)目都可以按照這套方案來(lái)進(jìn)行,省去了很多協(xié)作開(kāi)發(fā)的交流環(huán)節(jié),形成了能夠滿足大多數(shù)項(xiàng)目的目錄及文件構(gòu)成形式,將此項(xiàng)目托管至私服每次初始化項(xiàng)目只需拉取這個(gè)“腳手架”便能省區(qū)不少初始化項(xiàng)目的時(shí)間,豈不美哉!
此“腳手架”項(xiàng)目已開(kāi)源至github,歡迎大家提出建議和互相交流,同時(shí)也可隨意將項(xiàng)目拉下來(lái)進(jìn)行使用。
A scaffolding based on vue.js
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。