一个不够“懒”的程序员不是好程序员。 --------鲁迅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:工具中还有不少文章中没有说起的彩蛋,可为新手提供很多解决思路,欢迎你们扒下代码进行参考哦!)