分享一個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,歡迎大家提出建議和互相交流,同時也可隨意將項目拉下來進行使用。

A scaffolding based on vue.js

您可能感興趣的文章:

使用vue腳手架(vue-cli)搭建一個項目詳解

圖文講解用vue-cli腳手架創建vue項目步驟

使用vue-cli腳手架工具搭建vue-webpack項目

vue-cli3.0 腳手架搭建項目的過程詳解

vue-cli腳手架搭建的項目去除eslint驗證的方法

解決vue腳手架項目打包后路由視圖不顯示的問題

vue腳手架搭建項目的兼容性配置詳解

使用vue-cli(vue腳手架)快速搭建項目的方法

詳解使用vue-cli腳手架初始化Vue項目下的項目結構

詳解vue-cli 腳手架項目-package.json

詳解如何使用vue-cli腳手架搭建Vue.js項目

文章同步發布:?https://www.geek-share.com/detail/2769911782.html

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

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