最近公司接了一个订制小程序,是从 APP 改成微信小程序,考虑用mpvue框架来开发,发现还是有些坑的,下面说一下这两天使用下来的感受。

template中不支持methods中的函数,也没有 filter 过滤器,数据要预先处理比较麻烦

突然想到可以用组件来预处理数据,比如项目中图片 url 的拼接和替换域名

创建新页面比较繁琐

每次创建新页面按常规流程是:

新建页面文件夹 → 新建index.vuemain.jsmain.json并填入页面基本内容 → 在项目app.json中添加页面信息。

最开始我的解决方法是创建了一个模板页面,每次新建页面的时候复制一份,重命名。

但是还是很麻烦,需要手动向app.json中添加页面路径,干脆用 node 写了一个快速添加页面的小工具

将工具文件addpage.js放在 mpvue 项目根目录,运行node addpage

目前有一个参数可以配置新增页面的属性,是设置 vue 文件中用到的预处理器类型

用法:node addpage wxssnode addpage sass

addpage演示2.png
addpage演示3.png
填入需要创建的页面路径和标题就会在src/pages/下创建页面,包含三个基本文件,并自动向app.json中写入本次创建的路径
支持多级目录页面的创建,方便分类页面,如demo/demo1,demo/demo2

要注意的是,输入的路径下有其他页面时,会创建失败,比如创建了demo/demo1后,再创建demo就会失败

如果改变了目录结构请删除dist文件夹重新构建

下面是 addpage.js 的全部代码,不需要安装任何依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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
}
}

上几张正在开发中的截图

微信图片_20190515223516.png微信图片_20190515223454.png微信图片_20190515223509.png