1 安裝vue-cli3.0
0 淘寶鏡像
npm install -g cnpm --registry=https://registry.npm.taobao.org
1 安裝vue-cli
npm install -g @vue/cli
# OR
yarn global add @vue/cli
2 查看版本
vue --version
3 vue-cli構(gòu)建項(xiàng)目
vue create vue-demo
選擇默認(rèn)即可、可起服務(wù)
4 目錄結(jié)構(gòu)
├── README.md # 說(shuō)明
|-- dist # 打包后文件夾
├── babel.config.js # babel語(yǔ)法編譯
├── package-lock.json
├── package.json
├── public # 靜態(tài)文件夾
│ ├── favicon.ico
│ └── index.html #入口頁(yè)面
└── src # 源碼目錄
├── App.vue - 頁(yè)面
├── assets - 靜態(tài)目錄
│ └── logo.png
├── components 組件
│ └── HelloWorld.vue
└── main.js # 入口文件,加載公共組件
|-- vue.config.js # 配置文件
|-- .eslintrc.js # ES-lint校驗(yàn)
|-- .gitignore # git忽略上傳的文件格式
|-- babel.config.js # babel語(yǔ)法編譯
|-- package.json # 項(xiàng)目基本信息
標(biāo)準(zhǔn)的vue目錄結(jié)構(gòu)
2 環(huán)境變量和模式
0 介紹
在npm下實(shí)際上vue-cli 啟動(dòng)的時(shí)候,已經(jīng)確定了環(huán)境變量與模式,這樣方便代碼的構(gòu)建
打開package.json后
我們這邊描述的環(huán)境就在scripts中
1 模式
是 Vue CLI 項(xiàng)目中一個(gè)重要的概念。默認(rèn)情況下,一個(gè) Vue CLI 項(xiàng)目有三個(gè)模式:
-
development模式用于vue-cli-service serve -
production模式用于vue-cli-service build和vue-cli-service test:e2e -
test模式用于vue-cli-service test:unit
你可以通過(guò)傳遞
--mode選項(xiàng)參數(shù)為命令行覆寫默認(rèn)的模式。例如,如果你想要在構(gòu)建命令中使用開發(fā)環(huán)境變量,請(qǐng)?jiān)谀愕?package.json腳本中加入
<br />
"dev-build": "vue-cli-service build --mode development",
2 調(diào)用
那么我們?cè)诖a里面怎么調(diào)用呢、和他的應(yīng)用場(chǎng)景呢
process.env.NODE_ENV
這樣我們就可以獲取他的環(huán)境變量
3 場(chǎng)景
我們?cè)趕rc目錄下新建一個(gè)config<br />構(gòu)建一個(gè)env.js的目錄
let baseUrl = '';
const env = process.env
if (env.NODE_ENV == 'development') {
baseUrl = `http://192.168.1.1`; // 開發(fā)環(huán)境地址
} else if (env.NODE_ENV == 'production') {
baseUrl = `http://192.168.1.2`; //生產(chǎn)環(huán)境地址
} else if (env.NODE_ENV == 'test') {
baseUrl = `http://192.168.1.3`; //測(cè)試環(huán)境地址
}
export {
baseUrl,
env
}
那么這樣我們就可以直接使用不同環(huán)境下的
3 IE兼容處理、移除console
npm install @babel/polyfill -s
npm install babel-plugin-transform-remove-console -s
在babel.config.js中配置如下
const plugins = []
if (process.env.NODE_ENV === 'production') {
// 移除console.log
plugins.push('transform-remove-console')
}
module.exports = {
presets: [
['@vue/app', {
polyfills: [
'es6.array.iterator',
'es6.promise',
'es7.promise.finally',
'es6.symbol',
'es6.array.find-index',
'es7.array.includes',
'es6.string.includes',
'es6.array.find',
'es6.object.assign'
]
}]
],
plugins
}
4 vue-cli 基本配置
新建一個(gè)vue.config.js的文件夾,開始可配置vue-cli
module.exports = {
//部署應(yīng)用包時(shí)的基本 URL
publicPath: process.env.NODE_ENV === 'production' ? '/online/' : './',
//當(dāng)運(yùn)行 vue-cli-service build 時(shí)生成的生產(chǎn)環(huán)境構(gòu)建文件的目錄
outputDir: 'dist',
//放置生成的靜態(tài)資源 (js、css、img、fonts) 的 (相對(duì)于 outputDir 的) 目錄
assetsDir: 'assets',
// eslint-loader 是否在保存的時(shí)候檢查 安裝@vue/cli-plugin-eslint有效
lintOnSave: true,
//是否使用包含運(yùn)行時(shí)編譯器的 Vue 構(gòu)建版本。設(shè)置true后你就可以在使用template
runtimeCompiler: true,
// 生產(chǎn)環(huán)境是否生成 sourceMap 文件 sourceMap的詳解請(qǐng)看末尾
productionSourceMap: false,
}
5 添加別名
新建一個(gè)vue.config.js的文件夾,開始可配置vue-cli
1 別名配置
const path = require('path'); //引入path模塊(node)
const resolve = (dir) => path.join(__dirname, dir); //將文件組成絕對(duì)路徑
module.exports = {
chainWebpack: config => {
// 添加別名
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
}
}
2 運(yùn)用場(chǎng)景
目錄的結(jié)構(gòu)可能層層疊疊,后在達(dá)到目錄
例如: 剛剛的env.js目錄
import {baseUrl} from '../config/env'
但是我們不一定保證,目錄就那么靠近,那么怎么處理
// @代表src目錄下,即可這樣調(diào)用
import {baseUrl} from '@/config/env'
7 優(yōu)化-配置externals
防止將某些 import 的包(package)打包到 bundle 中,而是在運(yùn)行時(shí)(runtime)再去從外部獲取這些擴(kuò)展依賴
<br />
項(xiàng)目中的使用
一般性vue項(xiàng)目,我們都會(huì)把一些框架包,給抽離出來(lái)。例如:
- Vue
- ELEMENT
- VueRouter
- Vuex
- axios
1 引入框架
我們把一些外包引用的包,提取出來(lái),放在public中
2 編輯 externals
我們?cè)趘ue.config.
module.exports = {
configureWebpack: config => {
config.externals = {
'vue': 'Vue',
'element-ui': 'ELEMENT',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
}
}
3 引入cdn
那么這時(shí)候我們需要在 public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/element-ui/2.5.4/theme-chalk/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/animate/3.5.2/animate.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/iconfont.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/index.css">
<title>vue-demo</title>
</head>
<body>
<noscript>
<strong>We're sorry but vue-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="<%= BASE_URL %>cdn/vue/2.5.2/vue.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vuex/2.4.1/vuex.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vue-router/3.0.1/vue-router.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/axios/1.0.0/axios.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/element-ui/2.5.4/index.js" charset="utf-8"></script>
</body>
</html>
8 優(yōu)化-開啟Gzip 壓縮
1 介紹
vue cli 3.0相比2.0有不少的改動(dòng),最明顯的就是 build文件夾不見(jiàn)了,改為根目錄的vue.config.js<br />在此記錄一下Gzip配置的過(guò)程
npm i -D compression-webpack-plugin
2 修改vue.config.js
const CompressionPlugin = require("compression-webpack-plugin")
module.exports = {
configureWebpack:config=>{
if(process.env.NODE_ENV === 'production'){
return{
plugins: [
new CompressionPlugin({
test:/\.js$|\.html$|.\css/, //匹配文件名
threshold: 10240,//對(duì)超過(guò)10k的數(shù)據(jù)壓縮
deleteOriginalAssets: false //不刪除源文件
})
]
}
}
},
}
3 nginx配置gzip
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
第1行:開啟Gzip
第2行:不壓縮臨界值,大于1K的才壓縮,一般不用改
第3行:buffer,就是,嗯,算了不解釋了,不用改
第4行:用了反向代理的話,末端通信是HTTP/1.0,有需求的應(yīng)該也不用看我這科普文了;有這句的話注釋了就行> 了,默認(rèn)是HTTP/1.1
第5行:壓縮級(jí)別,1-10,數(shù)字越大壓縮的越好,時(shí)間也越長(zhǎng),看心情隨便改吧
第6行:進(jìn)行壓縮的文件類型,缺啥補(bǔ)啥就行了,JavaScript有兩種寫法,最好都寫上吧,總有人抱怨js文件沒(méi)有壓> 縮,其實(shí)多寫一種格式就行了
第7行:跟Squid等緩存服務(wù)有關(guān),on的話會(huì)在Header里增加"Vary: Accept-Encoding",我不需要這玩意,自己> 對(duì)照情況看著辦吧
第8行:IE6對(duì)Gzip不怎么友好,不給它Gzip了
9 優(yōu)化-首屏加載
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/element-ui/2.5.4/theme-chalk/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/animate/3.5.2/animate.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/index.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/iconfont.css">
<link rel="stylesheet" href="<%= BASE_URL %>cdn/iconfont/1.0.0/index.css">
<title>vue-demo</title>
<style>
html,
body,
#app {
height: 100%;
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999999;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
/* COLOR 1 */
border-top-color: #FFF;
-webkit-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-ms-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-moz-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-o-animation: spin 2s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
animation: spin 2s linear infinite;
/* Chrome, Firefox 16+, IE 10+, Opera */
z-index: 1001;
}
#loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
/* COLOR 2 */
border-top-color: #FFF;
-webkit-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-moz-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-o-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-ms-animation: spin 3s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
animation: spin 3s linear infinite;
/* Chrome, Firefox 16+, IE 10+, Opera */
}
#loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
/* COLOR 3 */
-moz-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-o-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-ms-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
-webkit-animation: spin 1.5s linear infinite;
/* Chrome, Opera 15+, Safari 5+ */
animation: spin 1.5s linear infinite;
/* Chrome, Firefox 16+, IE 10+, Opera */
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(0deg);
/* IE 9 */
transform: rotate(0deg);
/* Firefox 16+, IE 10+, Opera */
}
100% {
-webkit-transform: rotate(360deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(360deg);
/* IE 9 */
transform: rotate(360deg);
/* Firefox 16+, IE 10+, Opera */
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(0deg);
/* IE 9 */
transform: rotate(0deg);
/* Firefox 16+, IE 10+, Opera */
}
100% {
-webkit-transform: rotate(360deg);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: rotate(360deg);
/* IE 9 */
transform: rotate(360deg);
/* Firefox 16+, IE 10+, Opera */
}
}
#loader-wrapper .loader-section {
position: fixed;
top: 0;
width: 51%;
height: 100%;
background: #7171C6;
/* Old browsers */
z-index: 1000;
-webkit-transform: translateX(0);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateX(0);
/* IE 9 */
transform: translateX(0);
/* Firefox 16+, IE 10+, Opera */
}
#loader-wrapper .loader-section.section-left {
left: 0;
}
#loader-wrapper .loader-section.section-right {
right: 0;
}
/* Loaded */
.loaded #loader-wrapper .loader-section.section-left {
-webkit-transform: translateX(-100%);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateX(-100%);
/* IE 9 */
transform: translateX(-100%);
/* Firefox 16+, IE 10+, Opera */
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader-wrapper .loader-section.section-right {
-webkit-transform: translateX(100%);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateX(100%);
/* IE 9 */
transform: translateX(100%);
/* Firefox 16+, IE 10+, Opera */
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader {
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.loaded #loader-wrapper {
visibility: hidden;
-webkit-transform: translateY(-100%);
/* Chrome, Opera 15+, Safari 3.1+ */
-ms-transform: translateY(-100%);
/* IE 9 */
transform: translateY(-100%);
/* Firefox 16+, IE 10+, Opera */
-webkit-transition: all 0.3s 1s ease-out;
transition: all 0.3s 1s ease-out;
}
/* JavaScript Turned Off */
.no-js #loader-wrapper {
display: none;
}
.no-js h1 {
color: #222222;
}
#loader-wrapper .load_title {
font-family: 'Open Sans';
color: #FFF;
font-size: 19px;
width: 100%;
text-align: center;
z-index: 9999999999999;
position: absolute;
top: 60%;
opacity: 1;
line-height: 30px;
}
#loader-wrapper .load_title span {
font-weight: normal;
font-style: italic;
font-size: 13px;
color: #FFF;
opacity: 0.5;
}
</style>
</head>
<body>
<noscript>
<strong>We're sorry but vue-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加載 vue,請(qǐng)耐心等待
<br>
<span>V1.3</span>
</div>
</div>
</div>
<!-- built files will be auto injected -->
<script src="<%= BASE_URL %>cdn/vue/2.5.2/vue.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vuex/2.4.1/vuex.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/vue-router/3.0.1/vue-router.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/axios/1.0.0/axios.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>cdn/element-ui/2.5.4/index.js" charset="utf-8"></script>
</body>
</html>
10 預(yù)處理器 (Sass/Less/Stylus)
# Sass
npm install -D sass-loader node-sass
# Less
npm install -D less-loader less
# Stylus
npm install -D stylus-loader stylus
然后你就可以導(dǎo)入相應(yīng)的文件類型,或在 *.vue 文件中這樣來(lái)使用:
<style scoped lang="stylus">
.personal
position relative
.banner-red
width 100%
height 100px
</style>
11 node自動(dòng)化部署
1 安裝scp2
npm install scp2 --save-dev
2 配置一個(gè)服務(wù)器列表
deploy/products.js
/*
*定義多個(gè)服務(wù)器賬號(hào) 及 根據(jù) SERVER_ID 導(dǎo)出當(dāng)前環(huán)境服務(wù)器賬號(hào)
*/
const SERVER_LIST = [
{
id: 0,
name: 'A-測(cè)試環(huán)境',
host: 'xxx.xxx.xxx.xxx', // ip
port: 22,// 端口
username: 'root', // 登錄服務(wù)器的賬號(hào)
password: 'root', // 登錄服務(wù)器的賬號(hào)
path: 'xxx/xxx/xxx', // 發(fā)布至靜態(tài)服務(wù)器的項(xiàng)目路徑
del: ['/var/www/jx/admin/js', '/var/www/jx/admin/css'] // 刪除這些無(wú)法替換的
},
{
id: 1,
name: 'B-生成環(huán)境',
host: 'xxx.xxx.xxx.xxx', // ip
port: 22,// 端口
username: 'root', // 登錄服務(wù)器的賬號(hào)
password: 'root', // 登錄服務(wù)器的賬號(hào)
path: 'xxx/xxx/xxx', // 發(fā)布至靜態(tài)服務(wù)器的項(xiàng)目路徑
del: ['/var/www/jx/admin/js', '/var/www/jx/admin/css'] // 刪除這些無(wú)法替換的
},
];
module.exports = SERVER_LIST;
3 創(chuàng)建scp2自動(dòng)化部署腳本
const scpClient = require('scp2');
const ora = require('ora');
const chalk = require('chalk');
const servers = require('./products');
let server = servers[process.env.NODE_ENV === 'prod' ? 1 : 0];
const spinner = ora('正在發(fā)布到' + (process.env.NODE_ENV === 'prod' ? '生產(chǎn)' : '測(cè)試') + '服務(wù)器...');
var Client = require('ssh2').Client;
var conn = new Client();
conn
.on('ready', function() {
// rm 刪除dist文件,\n 是換行 換行執(zhí)行 重啟nginx命令 我這里是用docker重啟nginx
let dels = ""
server.del.forEach(item => {
dels += `rm -rf ${item}\n`;
});
conn.exec(dels, function (
err,
stream
) {
if (err) throw err;
stream
.on('close', function(code, signal) {
// 在執(zhí)行shell命令后,把開始上傳部署項(xiàng)目代碼放到這里面
spinner.start();
scpClient.scp(
'dist/',
{
host: server.host,
port: server.port,
username: server.username,
password: server.password,
path: server.path
},
function (err) {
spinner.stop();
if (err) {
console.log(chalk.red('發(fā)布失敗.\n'));
throw err;
} else {
console.log(chalk.green('Success! 成功發(fā)布到' + (process.env.NODE_ENV === 'prod' ? '生產(chǎn)' : '測(cè)試') + '服務(wù)器! \n'));
}
}
);
conn.end();
})
.on('data', function (data) {
console.log('STDOUT: ' + data);
})
.stderr.on('data', function (data) {
console.log('STDERR: ' + data);
});
});
})
.connect({
host: server.host,
port: server.port,
username: server.username,
password: server.password
});
4 添加指令
在 package.json 中添加指令
"upload-test": "NODE_ENV=test node ./deploy",
"upload-prod": "NODE_ENV=prod node ./deploy"
5 使用指令
發(fā)布測(cè)試環(huán)境
npm run upload-test
12 node自動(dòng)化新建頁(yè)面
每一次都需要需要寫vue的大致構(gòu)造,我覺(jué)得還是比較麻煩的一件事。一般性可以使用vscode新建,但是我認(rèn)為node更加方便
1 配置屬于你的模板
generateTpl.js
安裝個(gè)人習(xí)慣可以寫多個(gè)模板這里,我們只演示一種
exports.table = function(pageName) {
var tpl = `<template>
<basic-container>
<h3>${pageName}-page</h3>
</basic-container>
</template>
<script>
export default {
data() {
return {
};
},
methods: {
}
};
</script>
<style scoped>
</style>
`
return tpl;
}
2 安裝 inquirer
npm install inquirer --save-dev
3 創(chuàng)建自動(dòng)化新建腳本
var path = require('path');
var fs = require('fs');
var generateTpl = require('./generateTpl');
var inquirer = require('inquirer')
const createPage = {
template: "table",
init: function() {
const promptName = [{
type: 'input',
message: '模板的名稱',
name: 'templateName',
filter: function (val) {
return val.toLowerCase()
}
}]
const promptList = [{
type: 'list',
message: '請(qǐng)選擇一種模版',
name: 'template',
choices: ['表格', '表單'],
filter: function (val) {
return val.toLowerCase()
}
}]
inquirer.prompt(promptName).then(name => {
inquirer.prompt(promptList).then(anwsers => {
this.initParams(name.templateName);
if (anwsers.template==='表格') {
this.template = "table"
}else{
this.template = "form"
}
this.getAllPage();
this.generatePage();
})
})
},
initParams: function (templateName) {
this.pageName = templateName;
this.pageDir = path.join(__dirname, '../src/views');
this.allPages = ""
},
getAllPage: function() {
this.allPages = fs.readdirSync(this.pageDir);
},
generatePage: function(){
if(this.allPages.indexOf(this.pageName) == -1) {
this.toGenerageDir();
} else {
console.error('當(dāng)前頁(yè)面已經(jīng)存在了');
}
},
toGenerageDir: function(){
try{
fs.mkdir(path.join(this.pageDir, this.pageName), function(err){
if(err){
console.error(err);
return;
}
this.toGenerateFiles();
console.log('頁(yè)面創(chuàng)建完成');
}.bind(this));
}catch(e){
console.error(e);
}
},
toGenerateFiles: function() {
// 選擇模板
var vueFile = path.join(this.pageDir, this.pageName, `index.vue`);
var imageDir = path.join(this.pageDir, this.pageName, 'images')
// 創(chuàng)建文件
fs.writeFileSync(vueFile, generateTpl[this.template](this.pageName));
fs.mkdirSync(imageDir)
}
}
createPage.init();
3 添加指令
在 package.json 中添加指令
"create-page": "node create-page/create-page.js",
4 使用指令
npm run create-page