最近公司接了一个订制小程序,是从APP改成微信小程序,考虑用mpvue
框架来开发,发现还是有些坑的,下面说一下这两天使用下来的感受。
template
中不支持methods
中的函数,也没有filter过滤器,数据要预先处理比较麻烦
突然想到可以用组件来预处理数据,比如项目中图片url的拼接和替换域名
创建新页面比较繁琐
每次创建新页面按常规流程是:
新建页面文件夹 → 新建index.vue
,main.js
,main.json
并填入页面基本内容 → 在项目app.json
中添加页面信息。
最开始我的解决方法是创建了一个模板页面,每次新建页面的时候复制一份,重命名。
但是还是很麻烦,需要手动向app.json
中添加页面路径,干脆用node写了一个快速添加页面的小工具
将工具文件addpage.js
放在mpvue项目根目录,运行node addpage
目前有一个参数可以配置新增页面的属性,是设置vue文件中用到的预处理器类型
用法:node addpage wxss
,node addpage sass
src/pages/
下创建页面,包含三个基本文件,并自动向app.json
中写入本次创建的路径
支持多级目录页面的创建,方便分类页面,如demo/demo1
,demo/demo2
要注意的是,输入的路径下有其他页面时,会创建失败,比如创建了demo/demo1
后,再创建demo
就会失败
如果改变了目录结构请删除dist
文件夹重新构建
下面是addpage.js的全部代码
const fs = require('fs')
const readline = require('readline')
const path = require('path')
const colors = require('colors')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
//获取运行时附带参数,目前只定义了vue文件中的css语言类型和页面标题
let arguments = process.argv.splice(2);
let caaLang = arguments[0]
let appJson = JSON.parse(fs.readFileSync('./src/app.json', 'utf8').toString())
rl.question(' 请输入页面路径: '.bgBlue, (pathStr) => {
rl.question(' 请输入页面标题: '.bgBlue, (title) => {
pageTitle = title
pageCreate(pathStr)
})
})
function pageCreate(pathStr){
let jsonPush = `pages/${pathStr}/main`
let stop = false
appJson.pages.forEach((item) => {
let pathArr = item.split('/')
let pathStrArr = pathStr.split('/')
if (pathArr.length > 3 && pathStrArr.length === 1 && pathArr.indexOf(pathStrArr[0]) !== -1) {
stop = true
}
})
if (stop) {
console.log(' 此路径下有其他页面,不可直接作为页面路径 '.bgRed);
rl.close()
return
}
if (appJson.pages.indexOf(jsonPush) !== -1) {
console.log(' 此页面已存在 '.bgRed)
rl.close()
return
}
//app.json pages数组中没有,项目结构中有,此时已有的文件夹会被删除
deleteFolder('./src/pages/' + pathStr)
try {
mkdirsSync('./src/pages/' + pathStr)
} catch (error) {
console.log(error);
}
if (writePage('./src/pages/' + pathStr)) {
//加入本次创建的页面路径
appJson.pages.push(jsonPush)
//写入app.json
fs.writeFile('./src/app.json', JSON.stringify(appJson, null, "\t"), function (err) {
if (err) {
console.error(err)
}
console.log(' ----------新增成功---------- '.bgGreen)
rl.close()
})
}
}
//删除文件夹
function deleteFolder(path) {
var files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach(function (file, index) {
var curPath = path + "/" + file;
if (fs.statSync(curPath).isDirectory()) { // recurse
deleteFolder(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
}
//创建多级目录
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
}
//写入目标页面的三个文件
function writePage(path) {
try {
fs.writeFileSync(path + '/index.vue', `<template>
<div class="page-container">
</div>
</template>
<script>
export default {
data() {
return {}
}
}
</script>
<style lang="${caaLang?caaLang:'scss'}" scoped>
.page-container {
min-height: 100vh;
background-color: #f5f5f5;
background-image: linear-gradient(to bottom, #00d164, #00d164);
background-repeat: no-repeat;
background-size: 100% 170rpx;
background-position: top center;
padding-bottom: 65rpx;
}
</style>`, 'utf8');
fs.writeFileSync(path + '/main.js', `import Vue from 'vue'
import App from './index'
const app = new Vue(App)
app.$mount()`, 'utf8')
fs.writeFileSync(path + '/main.json', `{
"navigationBarTitleText": "${pageTitle}"
}`, 'utf8')
return true
} catch (error) {
//写入错误删除该文件夹
deleteFolder(path)
console.log(' 创建页面失败 '.bgRed);
throw error
}
}
个人博客【花喵电台】