分享一個(gè)vue項(xiàng)目“腳手架”項(xiàng)目的實(shí)現(xiàn)步驟

搭建緣由

源于公司每次新啟動(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)行使用。

A scaffolding based on vue.js

您可能感興趣的文章:

使用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腳手架搭建項(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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評(píng)論 6 540
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,275評(píng)論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,368評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,736評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,919評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,481評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,235評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,427評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,656評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評(píng)論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,160評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,380評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容

  • ## 框架和庫的區(qū)別?> 框架(framework):一套完整的軟件設(shè)計(jì)架構(gòu)和**解決方案**。> > 庫(lib...
    Rui_bdad閱讀 2,948評(píng)論 1 4
  • 1.腳手架: (1) npm install -g vue-cli (2) vue init webpac...
    蘇苡閱讀 3,412評(píng)論 1 2
  • 1、active-class是哪個(gè)組件的屬性?嵌套路由怎么定義?答:vue-router模塊的router-lin...
    jane819閱讀 1,763評(píng)論 0 15
  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在本質(zhì)上,閉包就 是將函數(shù)內(nèi)部和函數(shù)外...
    xuguibin閱讀 9,702評(píng)論 1 52
  • vue-cli雖然強(qiáng)大,但是它有很多個(gè)步驟要我們?nèi)ミx擇配置,而實(shí)際上公司業(yè)務(wù)很多配置是固定的,比如要安裝vue-r...
    阿爾法乀閱讀 3,507評(píng)論 1 0