搭建緣由
源於公司每次新啟動一個由多人協同開發的項目都由負責人初始化項目之后,每個人再去從私服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,歡迎大家提出建議和互相交流,同時也可隨意將項目拉下來進行使用。
