应用场景
由于经常使用vue开发移动端项目,每次需要vuex和移动端适配,每次需要自己手动新建vuex所需的js文件,使用vw进行移动端适配也需要安装一大堆依赖,感觉很麻烦,所以考虑自己写了一个简单的插件,可以自动新建vuex需要的文件和适配所需的相关配置,顺便熟悉一下新学的node。
使用方法
直接npm install ly-vue-util -g安装依赖,在vue项目中直接输入vue-util,就可以选择是否需要vuex还有是否需要使用单位vw; git地址: github.com/lyaaaa/ly-v…
相关代码展示
首先新建了一个src文件,由于插件内容不是很多,所以就只有一个Index.js和一个util.js一个放插件的核心代码,一个是所需要的功能方法; 然后,安装了几个依赖 inquirer.js 和 shell.js。inquirer.js 是一个用户与命令行交互的工具,因为这个插件是需要用户来选择相关的选项的,而且inquirer.js个人感觉用起来比较简单,下面是与用户交互的相关代码:
inquirer
.prompt([{
type: 'confirm',
message: 'install vuex ?',
name: 'vuex',
default: 'Y'
},
{
type: 'list',
message: 'choose your unit ?',
name: 'units',
choices: ['px', 'vw']
},
{
type: 'input',
message: 'please input your width and height, eg: 375,667 ?',
name: 'flexWH',
default: '375,667',
when: function (answers) {
return answers.units === 'vw'
}
}
])
.then(answers => {
});
复制代码
现在,基本上就可以实现交互效果,answers中会返回一些用户选择的相关选项,然后再根据相关的选择执行相关代码; 这里先说下 vuex的相关代码,使用shell.js可以直接执行shell命令,所以当用户选择使用vuex中,肯定是先通过shell.js安装一下vuex,但是只有这个肯定是不行的,还需要将我之前说的vuex相关的文件导入到Vue项目中的对应位置,这里就用到了node的path和fs模块,刚开始的时候我是直接手动写了每个js需要的内容,直接for循环然后新建js文件,fs模块写入相关代码,但是这样有个问题就是,代码虽然写入了,但是文件没有自动格式化,中间会有很多空格,后来又想到了一个更好的方法,就是又新建了一个template文件夹,然后写了一个store文件夹,里面把需要的action.js mutation.js等等都直接写入,然后直接将文件全部写入对应位置,下面是处理vuex相关代码
// index.js __root__: process.cwd()
if (answers.vuex) {
shell.exec('npm install vuex --save');
var url = path.join(__root__, '/src/store');
var src = path.join(__dirname, '../template/store');
existsFile(src, url, copyFile);
}
// util.js
// 复制文件夹到指定目录下
copyFile: function (src, dst) {
// 读取目录中的所有文件/目录
fs.readdir(src, function (err, paths) {
if (err) {
throw err;
}
paths.forEach(function (path) {
var _src = src + '/' + path,
_dst = dst + '/' + path,
readable, writable;
stat(_src, function (err, st) {
if (err) {
throw err;
}
// 判断是否为文件
if (st.isFile()) {
readable = fs.createReadStream(_src);
writable = fs.createWriteStream(_dst);
readable.pipe(writable);
}
// 如果是目录则递归调用自身
else if (st.isDirectory()) {
exists(_src, _dst, copyFile);
}
});
});
});
},
// 判断文件夹是否存在,不存在需要先创建目录
existsFile: function (src, dst, callback) {
fs.exists(dst, function (exists) {
if (exists) {
callback(src, dst);
} else {
fs.mkdir(dst, function () {
callback(src, dst);
});
}
});
},
复制代码
这里要注意 process.cwd() 和 __dirname 的区别,一个是项目的当前运行目录,一个是代码的目录. 这个功能实现后,完成vw的适配代码就相对简单了很多,原理也是一样,通过Node读取并修改css配置文件,通过shell安装所需依赖。相关代码如下:
// index.js __root__: process.cwd()
if (answers.units === 'vw') {
var wh = answers.flexWH.split(',')
shell.exec('npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S');
shell.exec('npm install cssnano-preset-advanced --save-dev');
flexUtilVW(parseFloat(wh[0]), parseFloat(wh[1]))
}
// util.js
// 配置 vw 单位
flexUtilVW: function (width, height) {
var url = path.join(__root__, '/.postcssrc.js');
var test = require(url);
var plugins = test.plugins;
var obj = {
"postcss-px-to-viewport": {
viewportWidth: width,
viewportHeight: height,
unitPrecision: 3,
viewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false
},
"cssnano": {
preset: "advanced",
autoprefixer: false,
"postcss-zindex": false
}
}
test.plugins = Object.assign({}, plugins, obj);
console.log(test)
fs.writeFile(url, 'module.exports=' + JSON.stringify(test), 'utf8', (err) => {
if (err) throw err;
console.log('done');
});
}
复制代码
总结
上面基本是这个简单插件的核心思路与代码,目前还有一个问题就是vw配置只是可以在vue-cli 2的版本搭建的vue项目可以使用 vue-cli3的由于配置路径不同,所以不可以使用,这也是我第一次写的node相关的项目,代码和思路肯定有很多不足的地方,还希望大神们能给我更合理的建议。