작은 프로그램에서 모듈화를 우아하게 구현하는 방법에 대한 간략한 분석은 무엇입니까?
미니 프로그램에서 우아하게 모듈화하는 방법은 무엇입니까? 이 글은 여러분에게 작은 프로그램을 우아하게 모듈화하는 방법을 가르쳐 줄 것입니다. 여러분에게 도움이 되기를 바랍니다.
이 기사에서는 WeChat 미니 프로그램에서 모듈식 처리를 우아하게 구현하는 방법에 대해 설명합니다. 최근 개발 경험의 요약을 통해 WeChat 애플릿 개발의 효율성을 높이고 정신적 부담을 줄일 수 있는 몇 가지 방법을 탐색해 보겠습니다.
ES6과 commonJS의 선택
우선 위챗 애플릿에서는 ES6
이든 commonJS
이든 모듈식 구문을 지원합니다. 개인적으로 저는 개발을 위해 ES6
모듈식 구문을 사용하는 데 익숙합니다. ES6
或者是 commonJS
模块化语法都是支持的,在传统的web项目中我个人是习惯统一使用 ES6
模块化语法进行开发的。
在最初我也是将小程序中所有的通用方法抽离成单独的文件,并使用export
或 export default
导出,使用 import
引入。
注意点
但是!在实际开发中,小程序的js文件是不支持绝对路径引入的!这意味着如果你需要在你的页面中引入一个公用方法,你必须使用 ../../../xxx/xxx.js
的方式,当你同一个页面引入多个模块时,这种写法绝对会极大的打击你的开发热情。
解决方式
那我们该如何解决这么长的引入路径呢,在web项目中,我们常常会使用路径别名的方式,例如 webpack或vite 中的 resolve.alias
来缩短引入的路径。
alias: {"@src":path.resolve("src"),
但是在原生微信小程序中,虽然可以通过 gulp 或者 webpack 等一些前端工程化的工具对小程序进行一些改造,但是作为一个开源项目我希望它的启动过程不需要太多额外配置。最好是能够使用原生的语法去实现。
最终我选择了在 app.js中新增一个require
方法用于引入模块,这样在页面内引入模块时,我们只需要使用app的实例来进行模块引入,这样可以实现使用与app.js
文件的相对路径来引入文件.
// app.js App({ require(path){ return path } })
使用方式
// 使用基于app.js的相对路径来引入文件,这样就避免了写很多"../" const app = getApp() const upload = app.require("lib/upload")
当然这样做也不是特别方便,首先是代码提示的不健全,使用以上方式的话可能对于参数或者一些返回值的提示不到位,但是影响不大。如果之后我摸索出了其他比较好的实现方式再写一篇文章解析。其次是必须使用全局统一使用commonJS 的模块化语法啦,不过这一点的话问题不大。
单页面模块化
小程序中并没有提供特殊的模块化方式,比较常用的就是将一些方法抽离为单独的js文件,然后再引入。想要避免一个页面文件代码太长的话最好的方式是组件化,但是在小程序中,认为写组件真的是一件很不爽的事情。
小程序组件拥有自己的生命周期,而且引入时必须在页面json中提前定义,由于组件是挂在在shadow root节点上,如果想要和页面共享样式例如colorUI的全局样式还需要写入单独的配置项styleIsolation。整体开发体验相比vue而言比较割裂。
基于以上的一些个人看法,我在写小程序时比较少使用组件,如果是需要抽离wxml或者是js我通常使用以下的方法。
wxml模块化
在小程序中我通常使用 模板template
进行抽离复用,微信小程序模板文档 ,模板相较于组件抽离的仅仅是部分的页面,不包含功能部分的抽离。
以下是我抽离的一个模板,这是一个文章的列表项,它并没有什么单独的功能,但是代码很长并且却在很多页面中复用到,于是我将它进行了一个抽离。把样式都通过行内样式的方式写上,这样在哪里引入都是一样的样式。
<!-- 文章列表项 --> <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>
在页面中使用的时候需要提前引入,由于可以引入多个模板,因此使用时需要使用 is属性
声明使用的是哪一个template,数据的话可以通过data
처음에는 애플릿에 있는 공통 메서드도 모두 별도의 파일로 추출하고 export
또는 export default
를 사용하여 내보내고 import<를 사용했습니다. /코드> 소개. </strong></p><p></p>조심하세요<p><strong><span style="font-size: 18px;"></span>하지만! 실제 개발시 미니프로그램의 js파일은 절대경로</strong> 도입을 지원하지 않습니다! 즉, 페이지에 공개 메소드를 도입해야 하는 경우 동일한 페이지에 여러 메소드를 도입할 때 <code>../../../xxx/xxx.js
를 사용해야 합니다. 모듈을 작성할 때 이런 방식으로 작성하면 개발에 대한 열정이 크게 약화될 것입니다.
resolve in 🎜webpack🎜 또는 🎜vite🎜 .alias
와 같은 경로 별칭을 자주 사용합니다. 가져온 경로를 단축합니다. 🎜<!-- 某个页面 --> <import src='../../template/post-item' /> <template data="{{...item}}" is="post-item" />🎜하지만 기본 WeChat 미니 프로그램에서는 🎜gulp🎜 또는 🎜webpack🎜과 같은 일부 프런트 엔드 엔지니어링 도구를 사용하여 미니 프로그램을 일부 수정할 수 있지만 오픈 소스 프로젝트로서 시작 프로세스가 추가 구성이 너무 많이 필요하지 않습니다. 이를 구현하려면 기본 구문을 사용하는 것이 가장 좋습니다. 🎜🎜결국 모듈을 소개하기 위해 app.js에
require
메소드를 추가하기로 결정했습니다. 이런 식으로 페이지에 모듈을 소개할 때 해당 인스턴스만 사용하면 됩니다. 이 방법으로 app.js
파일에 대한 상대 경로를 사용하여 파일을 가져옵니다.🎜// lib/upload.js // 上传方法 module.exports = async function upload(path) { return await wx.cloud.uploadFile({ cloudPath: new Date().getTime() + path.substring(path.lastIndexOf(".")), filePath: path, }) }🎜Usage method🎜
// 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) } // ...其他业务代码 } })🎜물론 이는 별로 편리하지 않습니다. 우선, 코드 프롬프트가 완벽하지 않습니다🎜, 위의 방법을 사용하세요. 그렇다면 매개변수나 일부 반환 값에 대한 프롬프트가 제자리에 있지 않을 수 있지만 영향은 크지 않습니다. 앞으로 다른 더 나은 구현 방법을 찾으면 이를 분석하는 기사를 작성하겠습니다. 둘째, 🎜commonJS🎜의 모듈식 구문을 전역적으로 균일하게 사용해야 하지만 이는 큰 문제가 되지 않습니다. 🎜
🎜단일 페이지 모듈화🎜🎜🎜미니 프로그램은 특별한 모듈화 방법을 제공하지 않습니다. 가장 일반적인 방법은 일부 메서드를 별도의 js 파일로 추출한 다음 소개하는 것입니다. 코드가 너무 긴 페이지 파일을 피하려면 가장 좋은 방법은 이를 컴포넌트화하는 것입니다. 그러나 작은 프로그램에서는 컴포넌트를 작성하는 것이 정말 불편합니다. 🎜🎜애플릿 구성 요소에는 자체 수명 주기가 있으며 소개할 때 🎜페이지 json🎜에서 미리 정의해야 합니다. 구성 요소가 🎜섀도 루트 노드🎜에 걸려 있기 때문에 페이지와 스타일을 공유하려면 다음과 같이 하세요. colorUI의 전역 스타일로 별도의 구성 항목 styleIsolation🎜을 작성해야 합니다. 전반적인 개발 경험은 vue에 비해 상대적으로 단편화되어 있습니다. 🎜🎜위의 개인적인 의견에 따르면, 저는 작은 프로그램을 작성할 때 컴포넌트를 거의 사용하지 않습니다. wxml이나 js를 추출해야 하는 경우에는 다음과 같은 방법을 주로 사용합니다. 🎜🎜🎜🎜wxml 모듈화🎜🎜🎜🎜작은 프로그램에서는 추상화와 재사용을 위해 보통 템플릿
을 사용합니다. WeChat Mini 프로그램 템플릿 문서는 구성 요소에 비해 템플릿은 페이지의 일부만 추출하며 그렇지 않습니다. 기능적인 부분의 추출을 포함합니다. 🎜🎜다음은 제가 추출한 템플릿입니다. 기사의 목록 항목입니다. 독립적인 기능은 없지만, 코드가 매우 길고 여러 페이지에서 재사용되므로 분리를 수행합니다. 모든 스타일은 🎜인라인 스타일🎜을 사용하여 작성하여 어디서든 동일한 스타일이 도입되도록 합니다. 🎜// 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)
}
🎜는 페이지에서 사용할 때 미리 소개해야 합니다. 여러 템플릿을 소개할 수 있으므로 is 속성
을 사용하여 어떤 템플릿을 사용할지 선언해야 합니다. code>data 속성이 전달됩니다. 여기의 예는 탐색된 항목🎜을 분해한 다음 여기에 할당하는 것입니다. 🎜// app.js
require("./mixins.js")
App({
// ...其他代码
})
🎜물론, 모듈화 및 추출을 위해 템플릿을 사용하는 템플릿 코드에는 너무 많은 기능적 논리가 포함될 수 없습니다. 구체적인 용도는 여전히 비즈니스에 기반해야 합니다. 🎜🎜🎜🎜js 모듈식🎜🎜🎜
在小程序中最基本的js模块化就是直接抽离js文件,例如一些全局通用的方法,下面展示一个全局上传方法的封装
// 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) } // ...其他业务代码 } })
当然以上的办法对于通用方法来说很方便,但是对于与 页面操作的逻辑耦合性 很高的一些业务代码,这样子抽离并不方便。
在vue2中我们可以使用mixin的方法模块化代码,在vue3中我们可以使用hook的方式模块化代码,但是在小程序中并没有以上两者的支持,最初我想仿照 vue3的hook 方式进行页面js封装改造,但最终实现的效果不理想,于是选择了实现一个模仿vue2 mixin 的方法来实现模块化。
具体代码其他博主有实现过,因此我就直接拿来使用了,具体代码如下。如果不了解vue中mixin的使用方法的可以自行去官网看文档,这里不做过多介绍。
// 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()函数,小程序的每一个页面都是通过调用Page({option})
方法来实现的,在option
参数中传入页面相关的data和声明周期函数及其他方法。
我们通过在Page方法的参数option
中增加一个mixin
属性,这个属性可以传入一个数组,数组即是每一个要混入的模块,每一个模块的结构其实与参数option
是一样的,我们只需要将所有混入的模块与页面自身的option进行一个参数和方法的合并就能实现一个mixin
的功能。
使用的方法是现在app.js中引入mixin.js
// app.js require("./mixins.js") App({ // ...其他代码 })
然后我们写一个常规页面的js,业务代码大家不用看,主要关注Page的属性中多了一个mixins选项,而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中同样的问题就是变量及方法的来源不好追溯,变量是在那个位置定义的比较难以定位,这时就更加依赖开发者的开发规范以及命名方式了,再不济也可以每一个方法写一个独有的注释嘛~
【相关学习推荐:小程序开发教程】
위 내용은 작은 프로그램에서 모듈화를 우아하게 구현하는 방법에 대한 간략한 분석은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undress AI Tool
무료로 이미지를 벗다

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제

모바일 인터넷 기술과 스마트폰의 대중화로 인해 WeChat은 사람들의 삶에 없어서는 안될 애플리케이션이 되었습니다. WeChat 미니 프로그램을 사용하면 사람들은 애플리케이션을 다운로드하고 설치하지 않고도 미니 프로그램을 직접 사용하여 몇 가지 간단한 요구 사항을 해결할 수 있습니다. 이 기사에서는 Python을 사용하여 WeChat 애플릿을 개발하는 방법을 소개합니다. 1. 준비 Python을 사용하여 WeChat 애플릿을 개발하기 전에 관련 Python 라이브러리를 설치해야 합니다. 여기서는 wxpy와 itchat 두 라이브러리를 사용하는 것이 좋습니다. wxpy는 위챗 머신입니다

WeChat 미니 프로그램에서 카드 뒤집기 효과 구현 WeChat 미니 프로그램에서 카드 뒤집기 효과를 구현하는 것은 사용자 경험과 인터페이스 상호 작용의 매력을 향상시킬 수 있는 일반적인 애니메이션 효과입니다. 다음은 WeChat 애플릿에서 카드 뒤집기 효과를 구현하는 방법을 자세히 소개하고 관련 코드 예제를 제공합니다. 먼저, 미니 프로그램의 페이지 레이아웃 파일에 두 개의 카드 요소를 정의해야 합니다. 하나는 앞면 내용을 표시하기 위한 것이고 다른 하나는 뒷면 내용을 표시하기 위한 것입니다. <--index.wxml- ->&l

10월 31일 이 사이트의 소식에 따르면 올해 5월 27일 Ant Group은 '한자 선택 프로젝트'를 시작한다고 발표했으며 최근 새로운 진전을 보였습니다. Alipay는 '한자 선택 - 흔하지 않은 문자' 미니 프로그램을 출시했습니다. 희귀 캐릭터는 희귀 캐릭터 라이브러리를 보완하고 희귀 캐릭터에 대한 다양한 입력 경험을 제공하여 Alipay의 희귀 캐릭터 입력 방법을 개선하는 데 도움을 줍니다. 현재 사용자는 "한자픽업", "희귀문자" 등의 키워드를 검색하여 "특수문자" 애플릿에 진입할 수 있습니다. 미니 프로그램에서 사용자는 시스템에서 인식 및 입력되지 않은 희귀 문자의 사진을 제출할 수 있으며 확인 후 Alipay 엔지니어가 글꼴 라이브러리에 추가 항목을 작성합니다. 이 웹사이트에서는 미니 프로그램에서도 최신 문자 분할 입력 방식을 경험할 수 있다고 밝혔습니다. 이 입력 방식은 발음이 불분명한 희귀 문자를 위해 설계되었습니다. 사용자 해체

미니 프로그램은 반응을 사용할 수 있습니다. 사용 방법: 1. "react-reconciler"를 기반으로 렌더러를 구현하고 DSL을 생성합니다. 2. DSL을 구문 분석하고 렌더링하기 위한 미니 프로그램 구성 요소를 만듭니다. 3. npm을 설치하고 개발자를 실행합니다. 도구에서 npm을 빌드합니다. 4. 자신의 페이지에 패키지를 소개한 다음 API를 사용하여 개발을 완료합니다.

유니앱이 미니 프로그램과 H5 사이를 빠르게 전환하려면 구체적인 코드 예제가 필요합니다. 최근 모바일 인터넷의 발전과 스마트폰의 대중화로 인해 미니 프로그램과 H5는 필수 애플리케이션 형태가 되었습니다. 크로스 플랫폼 개발 프레임워크인 uniapp은 코드 세트를 기반으로 작은 프로그램과 H5 간의 변환을 신속하게 실현하여 개발 효율성을 크게 향상시킬 수 있습니다. 이 기사에서는 uniapp이 미니 프로그램과 H5 간의 신속한 변환을 달성하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. 유니앱 유니아 소개

이번 글은 위챗 미니 프로그램과 관련된 몇 가지 이슈를 주로 소개하며, 미니 프로그램에서 공개 계정 템플릿 메시지를 사용하는 방법을 함께 살펴보겠습니다.

구현 아이디어 x01 서버 구축 먼저, 서버 측에서는 소켓을 사용하여 메시지를 수락합니다. 소켓 요청이 수락될 때마다 새 스레드가 열려 메시지 배포 및 수락을 관리합니다. 모든 스레드를 관리하여 채팅방의 다양한 기능 처리를 실현합니다. x02 클라이언트의 설정은 서버보다 훨씬 간단합니다. 클라이언트의 기능은 메시지를 보내고 받는 것뿐이며 특정 문자를 입력하는 것뿐입니다. 따라서 다양한 기능을 사용하려면 클라이언트 측에서 두 개의 스레드만 사용해야 합니다. 하나는 메시지 수신 전용이고 다른 하나는 메시지 전송 전용입니다. 왜냐하면, 오직

PHP 및 미니 프로그램의 지리적 위치 확인 및 지도 표시 지리적 위치 확인 및 지도 표시는 현대 기술에서 필요한 기능 중 하나가 되었습니다. 모바일 장치의 인기로 인해 위치 확인 및 지도 표시에 대한 사람들의 요구도 증가하고 있습니다. 개발 과정에서 PHP와 애플릿은 두 가지 일반적인 기술 선택입니다. 이 기사에서는 PHP 및 미니 프로그램에서 지리적 위치 측위 및 지도 표시 구현 방법을 소개하고 해당 코드 예제를 첨부합니다. 1. PHP의 위치정보 PHP에서는 타사 위치정보를 사용할 수 있습니다.
