搭建緣由
源于公司每次新啟動(dòng)一個(gè)由多人協(xié)同開發(fā)的項(xiàng)目都由負(fù)責(zé)人初始化項(xiàng)目之后,每個(gè)人再去從私服pull一下項(xiàng)目才開始開發(fā)。但是每次初始化工程都是一步步的造輪子,一個(gè)個(gè)依賴去安裝,新建一個(gè)個(gè)不同功能的文件夾,而每個(gè)負(fù)責(zé)人所初始化的項(xiàng)目目錄、以及模塊引入方式參差不齊,以至于開發(fā)中后期因每個(gè)人開發(fā)風(fēng)格的不同導(dǎo)致git提交時(shí)總會(huì)產(chǎn)生各種各樣的“沖突”,也會(huì)產(chǎn)生后期代碼維護(hù)成本增加,所以就有必要考慮一下做一個(gè)統(tǒng)一的類似“腳手架”的功能了,用來給團(tuán)隊(duì)開發(fā)帶來便捷的、統(tǒng)一的、易擴(kuò)展的項(xiàng)目基礎(chǔ)。
預(yù)實(shí)現(xiàn)的功能
公共樣式統(tǒng)一管理,全局sass的友好引入
公共js統(tǒng)一管理
解決vue腳手架初始化的部分問題
路由形式、接口統(tǒng)一管理
store模塊化管理
定義vue前端項(xiàng)目必用的方法
修改好統(tǒng)一的config配置
全局混入/指令的封裝
必要的依賴項(xiàng)
node-sass sass sass-resources sass-loader sass-recources-loader
vuex vuex-persistedstate
axios
babel-polyfill
項(xiàng)目目錄如下
配置公共sass
目錄assets>scss文件形式
mixin.scss內(nèi)容詳見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)目中的頁面引入了
//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')
}
接口統(tǒng)一管理
js目錄下的urlConfig.js
//?開發(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
};
頁面使用方式例如:
this.$http.post(this.URL_CONFIG.UrlConfig.getUserInfo,datas)
.then(res?=>{
console.log(res)
}).catch(error?=>{
console.log(error)
})
//?URL_CONFIG見全局混入中的方法
全局混入管理
全局混入主要用于項(xiàng)目中每個(gè)頁面或模塊都會(huì)用到的函數(shù)方法、計(jì)算屬性、過濾方法等。
文件所屬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)目都能用的到,可以寫在filter里也可以寫在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指令不能滿足需求,自定義的指令形式,在頁面編寫過程中可以帶來很多的便利。
文件所屬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模塊化管理主要是滿足不同開發(fā)人員的需求、避免使用單一store文件導(dǎo)致命名沖突。同時(shí)在main里定義了統(tǒng)一的模塊文件滿足大多數(shù)項(xiàng)目開發(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
})]
})
//切換頁面一般需要的loading動(dòng)畫狀態(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)畫狀態(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 初始配置的打包路徑問題
其實(shí)這個(gè)在上面文件中已經(jīng)有體現(xiàn)了,在這里再次提及一下。
步驟1:修改config>index.js文件
將build{ }下的assetsPublicPath改為如下
assetsPublicPath:?'./',
步驟2:修改build>utils.js文件
找到 fallback: 'vue-style-loader',在其下加入下面這一行
publicPath:?'../../'
結(jié)語
至此,一個(gè)基本完備的vue項(xiàng)目“腳手架”就完成了,以后每次初始化項(xiàng)目都可以按照這套方案來進(jìn)行,省去了很多協(xié)作開發(fā)的交流環(huán)節(jié),形成了能夠滿足大多數(shù)項(xiàng)目的目錄及文件構(gòu)成形式,將此項(xiàng)目托管至私服每次初始化項(xiàng)目只需拉取這個(gè)“腳手架”便能省區(qū)不少初始化項(xiàng)目的時(shí)間,豈不美哉!
此“腳手架”項(xiàng)目已開源至github,歡迎大家提出建議和互相交流,同時(shí)也可隨意將項(xiàng)目拉下來進(jìn)行使用。
您可能感興趣的文章:
使用vue腳手架(vue-cli)搭建一個(gè)項(xiàng)目詳解
圖文講解用vue-cli腳手架創(chuàng)建vue項(xiàng)目步驟
使用vue-cli腳手架工具搭建vue-webpack項(xiàng)目
vue-cli3.0 腳手架搭建項(xiàng)目的過程詳解
vue-cli腳手架搭建的項(xiàng)目去除eslint驗(yàn)證的方法
解決vue腳手架項(xiàng)目打包后路由視圖不顯示的問題
使用vue-cli(vue腳手架)快速搭建項(xiàng)目的方法
詳解使用vue-cli腳手架初始化Vue項(xiàng)目下的項(xiàng)目結(jié)構(gòu)
詳解vue-cli 腳手架項(xiàng)目-package.json
詳解如何使用vue-cli腳手架搭建Vue.js項(xiàng)目
文章同步發(fā)布:?https://www.geek-share.com/detail/2769911782.html