Bagaimana untuk memodulasi secara elegan dalam program kecil? Artikel ini akan mengajar anda cara memodulasi program kecil dengan elegan. Saya harap ia akan membantu anda!
Artikel ini membincangkan cara untuk melaksanakan pemprosesan modular secara elegan dalam program mini WeChat. Melalui ringkasan ringkas beberapa pengalaman pembangunan terkini, kami akan meneroka beberapa kaedah yang boleh meningkatkan kecekapan pembangunan applet WeChat dan mengurangkan beban mental.
Pertama sekali, dalam applet WeChat, kedua-dua sintaks modular ES6
dan commonJS
disokong dalam projek web tradisional, saya secara peribadi sudah terbiasa menggunakan ES6
sintaks modular untuk pembangunan.
Pada mulanya, saya juga mengekstrak semua kaedah biasa dalam applet ke dalam fail berasingan, dan menggunakan export
atau export default
untuk mengeksportnya dan menggunakan import
untuk mengimportnya.
Berhati-hati
Tetapi! Dalam pembangunan sebenar, fail js program mini tidak menyokong pengenalan laluan mutlak ! Ini bermakna jika anda perlu memperkenalkan kaedah awam ke dalam halaman anda, anda mesti menggunakan kaedah ../../../xxx/xxx.js
Apabila anda memperkenalkan berbilang modul pada halaman yang sama, kaedah penulisan ini pasti akan melemahkan semangat anda untuk pembangunan.
Penyelesaian
Jadi bagaimana kita menyelesaikan laluan import yang begitu panjang Dalam projek web, kita sering menggunakan Kaedah alias laluan, seperti pak web atau undang untuk memendekkan laluan yang diimport. resolve.alias
alias: {"@src":path.resolve("src"),
gulp atau webpack boleh digunakan untuk membuat beberapa pengubahsuaian kepada program mini, Sebagai projek sumber terbuka saya berharap proses permulaannya tidak memerlukan banyak konfigurasi tambahan. Adalah lebih baik untuk menggunakan sintaks asli untuk melaksanakannya.
Akhirnya, saya memilih untuk menambah kaedah baharu dalam app.js untuk memperkenalkan modul Dengan cara ini, apabila memperkenalkan modul ke dalam halaman, kita hanya perlu menggunakan contoh apl untuk mengimport modul Ini boleh dicapai Gunakan laluan relatif ke fail require
untuk mengimport fail app.js
// app.js App({ require(path){ return path } })
// 使用基于app.js的相对路径来引入文件,这样就避免了写很多"../" const app = getApp() const upload = app.require("lib/upload")
commonJS mesti digunakan secara global, tetapi ini bukan masalah besar. Pemodulasi halaman tunggal
dalam
halaman json apabila diperkenalkan Memandangkan komponen digantung padanod akar bayang, jika anda ingin berkongsi gaya dengan halaman, seperti gaya global colorUI, anda juga perlu menulis gaya item konfigurasi berasingan Pengasingan. Pengalaman pembangunan keseluruhan agak berpecah-belah berbanding dengan vue. Berdasarkan pendapat peribadi di atas, saya jarang menggunakan komponen semasa menulis program kecil Jika saya perlu memisahkan wxml atau js, saya biasanya menggunakan kaedah berikut.
modulariti wxmlDalam program mini, saya biasanya menggunakan untuk pengabstrakan dan penggunaan semula,
Templat program mini WeChat Dokumen, berbanding dengan komponen, templat hanya mengekstrak sebahagian daripada halaman, dan tidak termasuk pengekstrakan bahagian berfungsi. 模板template
Berikut ialah templat yang saya ekstrak Ini ialah item senarai artikel Ia tidak mempunyai fungsi bebas
kodnya sangat panjang dan. ia telah digunakan semula dalam banyak halaman, jadi saya mengekstraknya. Tulis semua gaya menggunakan gaya sebaris, supaya gaya yang sama diperkenalkan di mana-mana sahaja ia diperkenalkan. perlu diperkenalkan lebih awal apabila digunakan dalam halaman Memandangkan berbilang templat boleh diperkenalkan, anda perlu menggunakan untuk mengisytiharkan templat yang digunakan Untuk data, anda boleh lulus
atribut Lulus, contoh di sini ialah saya menyahbina item<!-- 文章列表项 --> <import src='./avatar' /> <template name="post-item"> <view class="margin padding-sm bg-white radius flex shadow " style="position: relative;height: 350rpx;border-radius: 10rpx;"> <!-- 背景蒙版 --> <view style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;border-radius: 10rpx;"> <image style="filter:blur(2px) grayscale(80%) opacity(80%)" lazy-load="{{true}}" src="{{imgList[0]}}" mode="aspectFill"></image> </view> <view style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(30, 30, 30, 0.8);border-radius: 10rpx;"> </view> <view style="z-index: 10;width: 100%;" class="text-white"> <!-- 文章标题 --> <view class="text-xl "> <text class="cu-tag margin-right-sm bg-color radius">{{topic}}</text> <text class="text-bold">{{title}}</text> </view> <!-- 文章内容 --> <view class="margin-top-xs text-sm text-cut">{{content}}</view> <view class="flex align-end justify-between margin-top"> <!-- 文章图片 --> <view class="flex align-center"> <view class="margin-xs" style="width: 120rpx;height: 120rpx;" wx:for="{{imgList}}" wx:key="{{index}}" wx:if="{{index < 3}}"> <image class="radius" src="{{item}}" mode="aspectFill"></image> </view> </view> <!-- 浏览量-点赞数 --> <view class="bg-color flex align-center text-white text-sm radius" style="padding: 4px 12px;"> <view class="cuIcon-attention "></view> <view class="margin-left-xs">{{viewNum||0}}</view> <view class="cuIcon-like margin-left"></view> <view class="margin-left-xs">{{favorNum||0}}</view> </view> </view> <!-- 发布时间 --> <view class="margin-top-xs flex align-center text-sm text-gray justify-between padding-lr-xs"> <view class="flex align-center"> <template is="avatar" data="{{size:45,avatarUrl:user.avatarUrl}}" /> <view class="margin-left-xs">{{user.nickName}}</view> </view> <view>{{createTime}}</view> </view> </view> </view> </template>
dan kemudian menetapkannya kepadanya. is属性
data
Sudah tentu, kod templat yang menggunakan templat untuk modularisasi dan pengekstrakan tidak boleh mengandungi terlalu banyak logik berfungsi. Penggunaan khusus masih perlu berdasarkan perniagaan.
<!-- 某个页面 --> <import src='../../template/post-item' /> <template data="{{...item}}" is="post-item" />
modulariti js
在小程序中最基本的js模块化就是直接抽离js文件,例如一些全局通用的方法,下面展示一个全局上传方法的封装 当然以上的办法对于通用方法来说很方便,但是对于与 页面操作的逻辑耦合性 很高的一些业务代码,这样子抽离并不方便。 在vue2中我们可以使用mixin的方法模块化代码,在vue3中我们可以使用hook的方式模块化代码,但是在小程序中并没有以上两者的支持,最初我想仿照 vue3的hook 方式进行页面js封装改造,但最终实现的效果不理想,于是选择了实现一个模仿vue2 mixin 的方法来实现模块化。 具体代码其他博主有实现过,因此我就直接拿来使用了,具体代码如下。如果不了解vue中mixin的使用方法的可以自行去官网看文档,这里不做过多介绍。 实现的原理是改造小程序中的Page()函数,小程序的每一个页面都是通过调用 我们通过在Page方法的参数 使用的方法是现在app.js中引入mixin.js 然后我们写一个常规页面的js,业务代码大家不用看,主要关注Page的属性中多了一个mixins选项,而 由于 注意点 但是使用 【相关学习推荐:小程序开发教程】 Atas ialah kandungan terperinci Analisis ringkas tentang cara melaksanakan modularisasi secara elegan dalam program kecil?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!// lib/upload.js
// 上传方法
module.exports = async function upload(path) {
return await wx.cloud.uploadFile({
cloudPath: new Date().getTime() + path.substring(path.lastIndexOf(".")),
filePath: path,
})
}
// pages/form/form.js
const app = getApp()
const upload = app.require("lib/upload")
Page({
async submit() {
wx.showLoading({
mask: true,
title: "发布中"
})
const imgList = []
for (let img of this.data.form.imgList) {
const uploadRes = await upload(img)
imgList.push(uploadRes.fileID)
}
// ...其他业务代码
}
})
// mixin.js
// 保存原生的 Page 函数
const originPage = Page
// 定义小程序内置的属性/方法
const prop = ['data', 'properties', 'options']
const methods = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap']
Page = (options) => {
if (Array.isArray(options.mixins)) {
const mixins = options.mixins
delete options.mixins
mixins.forEach((mixin) => {
for (let [key, value] of Object.entries(mixin)) {
if (prop.includes(key)) {
// 混入属性
options[key] = {
...value,
...options[key]
}
} else if (methods.includes(key)) {
// 混入原生方法
const originFunc = options[key]
options[key] = function (...args) {
value.call(this, ...args)
return originFunc && originFunc.call(this, ...args)
}
} else {
// 混入普通方法
options = {
...mixin,
...options
}
}
}
})
}
originPage(options)
}
Page({option})
方法来实现的,在option
参数中传入页面相关的data和声明周期函数及其他方法。option
中增加一个mixin
属性,这个属性可以传入一个数组,数组即是每一个要混入的模块,每一个模块的结构其实与参数option
是一样的,我们只需要将所有混入的模块与页面自身的option进行一个参数和方法的合并就能实现一个mixin
的功能。// app.js
require("./mixins.js")
App({
// ...其他代码
})
mixins
数组中有一个topic
模块。// pages/form/form.js
const app = getApp()
const upload = app.require("lib/upload")
const to = app.require("lib/awaitTo")
const db = wx.cloud.database()
Page({
mixins: [require("./mixins/topic")],
data: {
user: wx.getStorageSync('user'),
form: {
title: "",
topic: "",
content: "",
imgList: []
}
},
chooseImg() {
wx.chooseImage({
count: 9 - this.data.form.imgList.length,
sizeType: ['original'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], //从相册选择
success: (res) => {
res.tempFilePaths = res.tempFilePaths
if (this.data.form.imgList.length != 0) {
this.setData({ "form.imgList": this.data.form.imgList.concat(res.tempFilePaths) })
} else {
this.setData({ "form.imgList": res.tempFilePaths })
}
}
});
},
async delImg(e) {
const index = e.currentTarget.dataset.index
const temp = this.data.form.imgList
temp.splice(index, 1)
this.setData({ "form.imgList": temp })
}
})
topic
内都是关联性较强的属性与方法,因此就可以抽离出来,这样页面的js就会更加精简啦,如果有更多的代码就根据自己对于功能的判断进行抽离,然后放在页面对于mixin目录中即可!// // pages/form/mixin/topic.js
const db = wx.cloud.database()
module.exports = {
data:{
topic:{
flag:false,
list:[]
},
},
onLoad(options) {
this.getTopic()
},
async getTopic(){
const res = await db.collection("topic").get()
this.setData({"topic.list":res.data})
},
clearTopic(){
this.setData({"form.topic":""})
},
toggleTopic(e){
console.log(e.currentTarget.dataset)
const flag = e.currentTarget.dataset.flag
this.setData({"topic.flag":flag})
},
}
mixin
也有着与vue中同样的问题就是变量及方法的来源不好追溯,变量是在那个位置定义的比较难以定位,这时就更加依赖开发者的开发规范以及命名方式了,再不济也可以每一个方法写一个独有的注释嘛~