使用vue構建項目,項目結構清晰會提升開發效率,熟悉項目的各類配置一樣會讓開發效率更高,本篇幅不長,純屬分享,但願幫助小白提升開發效率,也歡迎大神討論指正html
my-vue-test:.
│ .browserslistrc
│ .env.production
│ .eslintrc.js
│ .gitignore
│ babel.config.js
│ package-lock.json
│ package.json
│ README.md
│ vue.config.js
│ yarn-error.log
│ yarn.lock
│
├─public
│ favicon.ico
│ index.html
│
└─src
├─apis //接口文件根據頁面或實例模塊化
│ index.js
│ login.js
│
├─components //工具組件
│ └─header
│ index.less
│ index.vue
│
├─config //配置(環境變量配置不一樣passid等)
│ env.js
│ index.js
│
├─contant //常量
│ index.js
│
├─images //圖片
│ logo.png
│
├─pages //多頁面vue項目,不一樣的實例
│ ├─index //主實例
│ │ │ index.js
│ │ │ index.vue
│ │ │ main.js
│ │ │ router.js
│ │ │ store.js
│ │ │
│ │ ├─components //業務組件
│ │ └─pages //此實例中的各個路由
│ │ ├─amenu
│ │ │ index.vue
│ │ │
│ │ └─bmenu
│ │ index.vue
│ │
│ └─login //另外一個實例
│ index.js
│ index.vue
│ main.js
│
├─scripts //包含各類經常使用配置,工具函數
│ │ map.js
│ │
│ └─utils
│ helper.js
│
├─store //vuex倉庫
│ │ index.js
│ │
│ ├─index
│ │ actions.js
│ │ getters.js
│ │ index.js
│ │ mutation-types.js
│ │ mutations.js
│ │ state.js
│ │
│ └─user
│ actions.js
│ getters.js
│ index.js
│ mutation-types.js
│ mutations.js
│ state.js
│
└─styles //樣式統一配置
│ components.less
│
├─animation
│ index.less
│ slide.less
│
├─base
│ index.less
│ style.less
│ var.less
│ widget.less
│
└─common
index.less
reset.less
style.less
transition.less
複製代碼
vue.config.js一般是一份寫好後能夠不斷複製,可是會用不如會寫,須要知道里面的原理,多頁面使用nodejs來配置多個入口,代碼更加優雅,下面是一份經常使用的vue.config.js配置,附註釋vue
const path = require("path")
const fs = require("fs")
/**
* @readdirSync fs模塊,用於讀取文件夾下全部的文件/文件夾,返回數組,fs.readdir的同步版本
* @resolve path模塊,用於拼接文件路徑
* @existsSync fs模塊,判斷路徑是否存在,返回布爾值
*/
const dirs = fs.readdirSync(path.resolve(process.cwd(), "src/pages"))
const pages = dirs.reduce((config,dirname)=>{
const filePath = `src/pages/${dirname}/main.js`
const tplPath = path.resolve(process.cwd(), `./public/${dirname}.html`)
if(fs.existsSync(tplPath)){
config[dirname] = filePath
}else{
config[dirname] = {
entry:filePath,//page的入口
template:'public/index.html',//模板的來源
filename:`${dirname}.html`//在dist/xx.html輸出
}
}
return config
},{})
// 多頁面 pages 使用的模版默認爲 public/[dir-name].html,若是找不到該模版,默認使用 public/index.html
/**
* publicPath: 應用會默認部署在根路徑,使用publicPath能夠定義部署在子路徑,pages模式不要使用相對路徑
* productionSourceMap: 爲true 則打包會生成.map文件
* contentBase: 告訴服務器從那個目錄提取靜態文件
* compress: 一切服務都啓用 gzip 壓縮
* historyApiFallback: 當使用 HTML5 History API 時,任意的 404 響應均可能須要被替代爲 index.html
* disableHostCheck: 繞過主機檢查
* devServer.proxy.changeOrigin: 默認狀況下,代理時會保留主機標頭的來源,您能夠將changeOrigin設置爲true來覆蓋此行爲
* devServer.proxy.secure: 默認狀況下,不接受運行在 HTTPS 上,且使用了無效證書的後端服務器,設置爲false表示接受
* chainWebpack: webpack的鏈式操做
* configureWebpack:多是個對象,也多是個函數,主要是經過webpack-merge合併到配置裏
* configureWebpack.resolve: 至關於合併內容到webpack原來的resolve[https://webpack.docschina.org/configuration/resolve/#resolve]
* configureWebpack.resolve.alias: 建立 import 或 require 的別名,來確保模塊引入變得更簡單
*/
module.exports = {
publicPath: process.env.VUE_APP_MODE === "production" ? "/prod/" : "/",
pages,
outputDir:process.env.VUE_APP_MODE === "production"? path.resolve(`${process.cwd()}/dist-prod/`):path.resolve(`${process.cwd()}/dist-beta/`),
productionSourceMap:process.env.VUE_APP_MODE === "beta",
devServer:{
port:3434,
host: "127.0.0.1",
contentBase: "./dist",
compress:true,
historyApiFallback:true,
disableHostCheck: true,
proxy:{
"/": {
target: "http://10.122.122.10:8070",
changeOrigin: true,
secure: false,
// pathRewrite: {"^/sjjc" : ""}
},
}
},
chainWebpack: config => {
config.module
.rule("images")
.use("url-loader")
.tap(args => {
return {
limit: 4096,
fallback: {
loader: "file-loader",
options: {
name: "images/[name].[hash:8].[ext]",
},
},
};
});
config.module
.rule("svg")
.use("file-loader")
.tap(args => {
return {
name: "images/[name].[hash:8].[ext]",
};
});
},
configureWebpack: {
resolve:{
alias:{
"@_src": path.resolve(__dirname,"src/")
}
}
}
}
複製代碼
在根目錄下配置.env文件,能夠設置環境變量(可設置多個)node
.env.produciton
和.env.development
全局變量僅除NODE_ENV
和BASE_URL
這兩個保留變量外,其他自定義變量都需使用VUE_APP
開頭。webpack
VUE_APP_MODE=beta
注意點:.env
文件裏不容許存在註釋git
/**
* .env.produciton內部寫法
*/
NODE_ENV=production
VUE_APP_MODE=production
複製代碼
使用store模塊化配合路由守衛,能夠實現不一樣路由在頁面上的不一樣配置,例如特定路由須要展現不一樣的樣式,特定路由不須要頭部,不須要側邊導航欄等,這些能夠在
router.js
中配置路由守衛,利用store定義各個屬性,實例化前經過mapstate
拿到配置,實現不一樣路由不一樣樣式的效果github
// @_src/store/index.js
import Vuex from "vuex";
import Vue from "vue";
import index from "./index/index.js";
import user from "./user";
Vue.use(Vuex);
const stores = {
"index": index,
user,
};
export const storeCreator = (moduleNames) => {
const names = Array.isArray(moduleNames) ? moduleNames : [moduleNames];
const modules = names.reduce((all, name) => {
if (stores[name]) {
all[name] = stores[name];
}
return all;
}, {});
return new Vuex.Store({
modules: {
...modules
}
});
};
複製代碼
import { storeCreator} from "@_src/store"
export default storeCreator(["index","user"])
複製代碼
import Vue from "vue"
import VueRouter from "vue-router"
import store from "./store";
export const routes = [
//初始進入重定向至父級通用事項頁面
{
path: "/",
redirect: "/a-menu",
name: "home"
},
{
name: "菜單A",
path: "/a-menu",
component: () => import("./pages/amenu/index.vue"),
meta: { title: "菜單A",icon:"xxx", menuCode: "xxx"}
},
{
name: "菜單B",
path: "/b-menu",
component: () => import("./pages/bmenu/index.vue"),
meta: { title: "菜單A",icon:"xxx", menuCode: "xxx"}
},
]
// header的title的顏色是否爲白色路由
const writeTitleRoutes = [
{
path: "/b-menu",
name: "菜單B",
},
];
Vue.use(VueRouter);
const router = new VueRouter({
routes
});
//配置路由導航守衛
router.beforeEach((to,from,next)=>{
let writeTitle=false
for(let i=0;i<writeTitleRoutes.length;i++){
const pathReg = new RegExp(writeTitleRoutes[i].path);
if (pathReg.test(to.path)) {
writeTitle = true;
break;
}
}
if (store.state.index.writeTitle !== writeTitle) {
store.commit("index/SET_TITLE", writeTitle);
}
next();
})
export default router;
複製代碼