分享一個(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)行使用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 使用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)目
相關(guān)文章
vue中el-table單元格復(fù)制功能實(shí)現(xiàn)
這篇文章主要介紹了vue中el-table單元格復(fù)制功能實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07
Vue3中的ref為何要用.value進(jìn)行值的調(diào)用呢
這篇文章主要介紹了Vue3中的ref為何要用.value進(jìn)行值的調(diào)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
詳解vue組件化開發(fā)-vuex狀態(tài)管理庫(kù)
本篇文章主要介紹了詳解vue組件化開發(fā)-vuex狀態(tài)管理庫(kù),具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04
解決vue的 v-for 循環(huán)中圖片加載路徑問題
今天小編就為大家分享一篇解決vue的 v-for 循環(huán)中圖片加載路徑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09
vue.js樣式布局Flutter業(yè)務(wù)開發(fā)常用技巧
這篇文章主要為大家介紹了vue.js樣式布局Flutter業(yè)務(wù)開發(fā)中的常用技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-11-11
vue?cli3配置image-webpack-loader方式
這篇文章主要介紹了vue?cli3配置image-webpack-loader方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07

