一個不夠「懶」的程序員不是好程序員。 --------魯迅css
相信每一個一個程序員都不但願花過多的時間去造不必造的輪子(純粹爲了學習的略過),通過不斷的成長和經驗的積累,咱們總得造出一些有意義的能夠長期使用的「輪子」(由於沒有現成的,哈哈🤣),也就是你們都將求的代碼的複用性。前端
此篇文章主要分享一下我是怎樣省去每次初始化Vue項目的那幾十分鐘。vue
先讓咱們回憶一下初始化Vue項目的步驟:node
vue init webpack project-namelinux
npm/cnpm install ....webpack
修改webpack配置git
刪除vue-cli初始化頁面程序員
修改main.js,配置第三方插件github
新建好多文件夾web
等等...
總之,這一通下來體驗是真的極其很差,除非有些人就喜歡重複這樣無趣的操做,PS:也有人可能扒一份以前的項目刪刪改改、縫縫補補也算是初始化了一個新項目,but,這真不是優雅的方式。🤔
咱們學習或借用外來資源主要仍是會取其精華、棄其糟粕的,因此在vue-cli3的基礎上,咱們先把它自己容易有坑的地方解決,再進一步完善和增長咱們本身的需求,這樣就知足咱們的長期需求了。
那麼本篇文章在分享如何構建項目框架的同時,還會分享到Vue高級概念Mixins
、directive
、過濾器
、vuex管理
等方法的基礎使用方式。
像靜態資源、公共樣式、router這些最基礎的項目組成可能就仁者見仁智者見智了,每一個人有本身存放位置的習慣和風格,這裏展現一下個人項目構成你們就一目瞭然了,畢竟這些都不是重點。😶
首先在assets/scss下新建文件common.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: { 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') } 複製代碼
完成以上配置,就能在項目中的任何頁面瘋狂的飆車了。
若是是多人蔘與的項目,就不得不對接口進行統一管理,固然就算是一我的也是很是有必要的,由於這樣不至於後期由於後端一個小小的接口改動致使牽一髮而動全身。
配置參照形式
// 開發環境用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 }; 複製代碼
使用方式之一,在main.js中將UrlConfig掛載到Vue原型
import URL_CONFIG from '@/assets/js/urlConfig.js';
Vue.prototype.$url = URL_CONFIG.UrlConfig
而後在頁面使用
this.$url.getUserInfo
這樣就能將接口統一管理,並且不用在每次上線打包都去對base_url進行改動了(生產環境多的除外),同時在多人協做開發的過程當中也不會出現生成多種接口管理形式的狀況,爲合併代碼時的衝突減小必定的隱患。
簡單來說Mixins
就是咱們能夠重複使用的代碼,在功能模塊比較多的項目中有不少重複的方法是必然存在的,由不少種方法能夠幫咱們抽離這些可複用的代碼,可是Vue中提供了一種比較好的特性之一就是Mixins
,它可使用任何咱們在頁面中定義的methods
、data
、mounted
等方法。
定義一個formatTime.js的mixin,將它使用在一些咱們須要轉換時間戳的頁面,例如:
const formatTime = { methods: { //像時間戳轉換這種方法大多數項目都能用的到,能夠寫在filter裏也能夠寫在computed裏,取決於運用場景 formatTime(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); }, } } export default formatTime 複製代碼
而後在頁面中使用
import formatTime from '路徑'
mixins:['formatTime']
這樣咱們就算把具備重複方法的代碼在局部頁面抽離了,固然以上示例只是簡單說明Mixins
的基本使用方法,像轉換時間戳還有更優雅的方法,具體怎樣使用仍是得結合場景去構建。
另一種就是在項目中每一個頁面或者說絕大多數頁面都可以使用到的方法,這時候咱們就能夠考慮一下將它掛載到原型,以便進行更便捷的使用,例如一個全局使用的Mixins
有以下方法:
loadPage(path,params){ this.$router.push({ path:path, query:params }) } 複製代碼
那麼咱們將他在main.js中引入
import globalMixins from '@/components/common/mixins'
Vue.mixin(globalMixins )
全局指令就是Vue容許用戶自定義一些經常使用的對DOM進行底層操做的方法,諸如v-for
、v-if
這些指令。它能夠幫咱們實現什麼。舉個栗子:咱們須要給統一一下網頁各種元素的背景色以及primary
、danger
、error
這樣相似主題的顏色,咱們可能會用sass/less寫一套樣式變量,再定義class以控制統一的顏色。
咱們用自定義指令實現一下它:
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 globalDirective from '@/components/common/directive'
Vue.use(globalDirective )
而後在頁面中咱們就能夠像用v-for
、v-if
這樣的方法去使用v-bg
、v-color
、v-theme
了,固然有人可能會講自定義指令這樣用有點大材小用了,用sass和統一的class去管理項目的主題等基礎配置也是很好的。仍是那句話,結合場景談業務纔不算耍流氓,😉固然自定義指令還有更多高級的用法,能夠參考Vue文檔去實現更多本身的業務邏輯。
這個需求可能僅僅是我我的的需求,由於一直以來個人目標是能使用鍵盤就儘可能不使用鼠標去操做電腦的,對命令行操做那更是無以用言語描述😊,由於比較喜歡linux,雖然我是一個前端,廢話少說實現一下.
首先咱們須要compressing
這個插件,在build文件夾下建一個zip.js
compressing插件壓縮成zip文件的最基礎使用方式是這樣的,
compressing.zip.compressDir('dist', 'dist.zip') .then(() => { process.exit() }) .catch(err => { console.error(err); }); 複製代碼
可是咱們能不能每次壓縮文件用讓執行命令的時候輸入呢,同時讓文件名更有標識性,否則每次都是dist.zip,假如咱們須要備份文件豈不是很尷尬.
首先要實現命令行提示和輸入文件名要用到node的stdout
和stdin
,以下:
process.stdout.write(`請輸入壓縮文件名:`) process.stdin.resume() process.stdin.on('data', (chunk) => { chunk = chunk.toString().trim(); //輸入的文件名 //輸入完要作的事 }); 複製代碼
再增長一項需求,有時候我不想輸入文件名,可是我還要壓縮文件名格式統一且儘可能保證名稱不會重複.
最後實現一下這個比較個性的需求,代碼上😁
#!/usr/bin/env node process.stdin.setEncoding('utf8'); const compressing = require('compressing'); const prefixName = 'wvue-cli_'; //默認壓縮包前綴 function formatDateToString(date){ var year = date.getFullYear(); var month = date.getMonth()+1; var day = date.getDate(); var hour = date.getHours(); month < 10 ? '0' + month: month; day < 10 ? '0' + day: day; hour < 10 ? '0' + hour: hour; return month+day+hour; //想要絕對性的不重複能夠直接精確到毫秒 } function toZip(name){ compressing.zip.compressDir('dist', `${name}.zip`) .then(() => { console.log( `${name}.zip`+'已保存至項目目錄!'); process.exit() }) .catch(err => { console.error(err); }); } const time = formatDateToString(new Date()); process.stdout.write(`請輸入壓縮文件名:`) process.stdin.resume() process.stdin.on('data', (chunk) => { chunk = chunk.toString().trim(); //輸入的文件名 var name = chunk || prefixName + time; toZip(name) }); process.stdin.on('end', () => { process.stdout.write('結束'); }); //壓縮文件名形如wvue-cli_062110.zip這樣 複製代碼
而後在咱們的package.json添加,使用方式以下
"pack": "node build/zip.js"
npm run pack zipname
作完一項需求或者改完一些bug了咱們須要提交一次代碼,可能得git add
git commit
git push
一頓操做,but咱們懶呀,(請不要跟我講圖形化工具或者編輯器自帶插件,我須要命令行🙄)
這裏咱們須要shelljs,這個插件在vue-cli中是默認安裝在咱們項目的dev環境中的,因此不用本身安裝,實現方式以下
#!/usr/bin/env node var name = process.argv[2] || 'auto-commit'; var shell = require("shelljs"); var exec = shell.exec; var echo = shell.echo; if (exec('git add .').code !== 0) { echo('Error: Git add failed'); exit(1); } if (exec(`git commit -am "${name}"`).code !== 0) { echo('Error: Git commit failed'); exit(1); } if (exec('git push').code !== 0) { echo('Error: Git push failed'); exit(1); } //綠色字體 echo('-e',"\033[0;32m git success \033[0m"+`${name}`); 複製代碼
而後方法相似壓縮文件,在package.json裏添加執行命令的方法.
"push": "node build/push.js",
npm run push "修復了一些bug"
至此,一個比較全面的腳手架plus就擼完了,咱們也實現了那麼些開發過程當中很常見很實用的需求,今後擼代碼也能夠比別人快一步,至少不用把時間浪費在初始化項目這件繁瑣且浪費感情的事情上,由於咱們懶
😏.
文章中部分功能的實現過程因爲篇幅限制不能完整展現,還有一些像自定義全局組件這樣的方法沒有體現到,實屬抱歉,若有交流或者參考能夠去github上拉個人代碼,或者經過npm直接安裝一下腳手架,本人青銅選手若有建議還請同行批評指正~😊
github地址
npm 安裝及使用方法
npm i wwvue-cli -g
wwvue init project-name
最最後,叩謝走過路過的各位開發者花時間看我扯完這麼些有的沒的的東西~🤡
(PS:工具中還有不少文章中沒有說起的彩蛋,可爲新手提供很多解決思路,歡迎你們扒下代碼進行參考哦!)