问题
在我们开发小程序过程中,如果想像 vue 一样使用全局组件是不行的,必须将组件一个一个引入到响应的页面,这是因为小程序每个页面都是一个线程,没有像 vue 那种有顶级的 dom。
那么如果我们想做一个全局组件又不想每个页面都分别引入该怎么办呢,那就只能尽可能的让我们引入的过程自动化了。
实践
比如我们做一个全局的 loading,不想每个页面都手动引入,可以写相关的自动化脚本,来将代码引入到 .wxml 里面。
代码结构
- generator
- index.js
- template
- components
- custom-loading
- index.js
- index.wxml
- index.wxss
- index.json
template 文件中使我们的模板,也就是我们的 custom-loading 组件(这个我就不代码演示了),然后我们可以把这个模板直接注入到我们的代码中,并且自动化的加上引入组件的代码。
那么接下来我们主要看看 index.js 做了什么,主要分为两个部分:
- 把
template 中的文件注入到项目中 - 给 app.json 中引入全局组件
custom-loading - 在每个 pages 的
index.wxml 引入组件
先来看看 2 的代码:
const fs = require('fs')
const entryFilePath = './app.json'
if (fs.statSync(entryFilePath)) {
const { EOL } = require('os')
const contentMain = fs.readFileSync(api.resolve(entryFilePath), { encoding: 'utf-8' })
const customLoadingReg = /['"]?custom-loading['"]?:/
const contentMainLines = contentMain.split(/\r?\n/g)
const usingComponentsStartReg = /['"]?usingComponents['"]?:/
const usingComponentLineNum = contentMainLines.findIndex(line => line.match(usingComponentsStartReg))
const tabBarStartReg = /['"]?tabBar['"]?:/
if (!customLoadingReg.test(contentMain)) {
if(usingComponentLineNum < 0) {
const tabBarLineNum = contentMainLines.findIndex(line => line.match(tabBarStartReg))
contentMainLines[tabBarLineNum - 1] += `${EOL} usingComponents: { "custom-loading": "./components/custom-loading/index" },`
} else {
contentMainLines[usingComponentLineNum] += `${EOL} "custom-loading": "./components/custom-loading/index",`
}
fs.writeFileSync(path.resolve(entryFilePath), contentMainLines.join(EOL), { encoding: 'utf-8' })
}
} else {
log(`app.wpy 不存在`)
}
接下来是 3 相关代码:
const contentMain = fs.readFileSync(api.resolve(entryFilePath), { encoding: 'utf-8' })
const pageConfigReg = /['"]?pages['"]?: \[([^\]]+)\],/
const pageList = pageConfigReg.exec(contentMain)[1].replace(/\s+/, '').replace(/\n\s+/g, '').split(',')
pageList.forEach((pagePath) => {
})
总结
当我们遇到一些需要重复工作的问题,可以尝试用 node 文件读写的这个思路来解决。
|