文章目录
- 小程序开发必备理论知识
- 一、自定义组件
- 1. 自定义组件 - 组件的创建与引用
- 1.1 创建组件
- 1.2 引用组件
- 1.3 局部引用组件
- 1.4 全局引用组件
- 1.5 全局引用 VS 局部引用
- 1.6 组件和页面的区别
- 2. 自定义组件 - 样式
- 2.1 组件样式隔离
- 2.2 组件样式隔离的注意点
- 2.3 修改组件的样式隔离选项
- 2.4 styleIsolation 的可选值
- 3. 自定义组件 - 数据、方法和属性
- 3.1 data 数据
- 3.2 methods 方法
- 3.3 properties 属性
- 3.4 data 和 properties 的区别
- 3.5 使用 setData 修改 properties 的值
- 4. 自定义组件 - 数据监听器
- 4.1 什么是数据监听器
- 4.2 数据监听器的基本用法
- 4.3 监听对象属性的变化
- 5. 自定义组件 - 纯数据字段
- 5.1 什么是纯数据字段
- 5.2 使用规则
- 5.3 使用纯数据字段改造数据监听器案例
- 6. 自定义组件 - 组件的生命周期
- 6.1 组件全部的生命周期函数
- 6.2 组件主要的生命周期函数
- 6.3 lifetimes 节点
- 7. 自定义组件 - 组件所在页面的生命周期
- 7.1 什么是组件所在页面的生命周期
- 7.2 pageLifetimes 节点
- 7.3 生成随机的 RGB 颜色值
- 8. 自定义组件 - 插槽
- 8.1 什么是插槽
- 8.2 单个插槽
- 8.3 启用多个插槽
- 8.4 定义多个插槽
- 8.5 使用多个插槽
- 9. 自定义组件 - 父子组件之间的通信
- 9.1 父子组件之间通信的 3 种方式
- 9.2 属性绑定
- 9.3 事件绑定
- 9.4 获取组件实例
- 10. 自定义组件 - behaviors
- 10.1 什么是 behaviors
- 10.2 behaviors 的工作方式
- 10.3 创建 behavior
- 10.4 导入并使用 behavior
- 10.5 behavior 中所有可用的节点
- 10.6 同名字段的覆盖和组合规则
- 二、使用npm包
- 1. 使用 npm 包 - Vant Weapp
- 1.1 官方文档地址
- 1.2 安装教程
- 1.3 CSS 变量的基本用法MDN文档
- 1.4 Vant 官方配置文件
- 2. 使用 npm 包 - API Promise化
- 2.1 基于回调函数的异步 API 的缺点
- 2.2 什么是 API Promise 化
- 2.3 实现 API Promise 化
- 2.4 调用 Promise 化之后的异步 API
- 三、全局数据共享
- 什么是全局数据共享
- 小程序中的全局数据共享方案
- 1. 全局数据共享 - MobX
- 1.1 安装 MobX 相关的包
- 1.2 创建 MobX 的 Store 实例
- 1.3 将 Store 中的成员绑定到页面中
- 1.4 在页面上使用 Store 中的成员
- 1.5 将 Store 中的成员绑定到组件中
- 1.6 在组件中使用 Store 中的成员
- 四、分包
- 1、分包 - 基础概念
- 1.1 什么是分包
- 1.2 分包的好处
- 1.3 分包前项目的构成
- 1.4 分包后项目的构成
- 1.5 分包的加载规则
- 1.6 分包的体积限制
- 2、分包 - 使用分包
- 2.1 配置方法
- 2.2 打包原则
- 2.3 引用原则
- 3、分包 - 独立分包
- 3.1 什么是独立分包
- 3.2 独立分包和普通分包的区别
- 3.3 独立分包的应用场景
- 3.4 独立分包的配置方法
- 3.5 引用原则
- 4、分包 - 分包预下载
- 4.1 什么是分包预下载
- 4.2 配置分包的预下载
- 4.3 分包预下载的限制
小程序开发必备理论知识
一、自定义组件
1. 自定义组件 - 组件的创建与引用
1.1 创建组件
在小程序中,创建组件需要定义组件的结构、样式和行为。以下是一个简单的组件目录结构:
|- components|- custom-component|- custom-component.js|- custom-component.json|- custom-component.wxml|- custom-component.wxss
1.2 引用组件
引用组件可以通过在页面的 .json
文件中配置 usingComponents
字段,然后在页面的 .wxml
文件中以标签的形式引用组件:
pages/index/index.json:
{"usingComponents": {"custom-component": "/components/custom-component/custom-component"}
}
pages/index/index.wxml:
<view><custom-component></custom-component>
</view>
1.3 局部引用组件
局部引用组件是指将组件引入到某个页面或组件内,而不是全局引用。这样做可以提高代码的灵活性和复用性。
pages/index/index.json:
{"usingComponents": {"custom-component": "/components/custom-component/custom-component"}
}
pages/index/index.wxml:
<view><custom-component></custom-component>
</view>
1.4 全局引用组件
全局引用组件是指在整个小程序中都可以使用该组件,不需要在每个页面或组件内单独引用。
app.json:
{"usingComponents": {"custom-component": "/components/custom-component/custom-component"}
}
pages/index/index.wxml:
<view><custom-component></custom-component>
</view>
1.5 全局引用 VS 局部引用
全局引用和局部引用各有优势,全局引用适用于在整个小程序中都需要使用的组件,而局部引用适用于只在某个页面或组件内使用的组件。
1.6 组件和页面的区别
组件和页面在小程序中有一些区别,包括生命周期函数的执行时机和组件的作用域。理解这些区别有助于更好地利用自定义组件进行开发。
2. 自定义组件 - 样式
2.1 组件样式隔离
小程序中的组件样式是默认隔离的,即组件内部的样式不会影响到外部页面或组件。这种隔离有助于保持代码的独立性。
2.2 组件样式隔离的注意点
在使用组件样式隔离时,需要注意一些细节,例如如何正确引用外部样式。
2.3 修改组件的样式隔离选项
开发者可以根据实际需求修改组件的样式隔离选项,灵活控制样式的作用范围。
2.4 styleIsolation 的可选值
可选值 | 默认值 | 描述 |
---|---|---|
isolated | true | 组件样式仅对组件生效,不影响外部样式。 |
apply-shared | false | 组件样式对组件生效,同时会影响引入组件的外部样式。 |
shared | false | 组件样式对组件生效,同时也会影响引入组件的外部样式,且外部样式对组件也生效。 |
3. 自定义组件 - 数据、方法和属性
3.1 data 数据
组件内部可以定义 data
数据,用于存储组件的状态信息。
custom-component.js:
Component({data: {count: 0},// other properties and methods
})
3.2 methods 方法
methods
字段用于定义组件的方法,这些方法可以在组件内被调用。
custom-component.js:
Component({data: {count: 0},methods: {increaseCount() {this.setData({count: this.data.count + 1});}}// other properties
})
3.3 properties 属性
properties
字段用于定义组件的属性,属性可以由组件外部传入,从而实现组件与外部的数据交互。
custom-component.json:
{"component": true,"properties": {"title": {"type": String,"value": "Default Title"}}
}
3.4 data 和 properties 的区别
理解 data
和 properties
的区别是使用自定义组件的关键,它们分别用于组件内部的状态管理和与外部数据的交互。
3.5 使用 setData 修改 properties 的值
在组件内部可以使用 setData
方法修改 properties
的值,从而实现动态更新组件的属性。
custom-component.js:
Component({properties: {title: {type: String,value: "Default Title",observer: function (newVal, oldVal) {console.log('title changed', newVal, oldVal);}}},methods: {changeTitle() {this.setData({title: "New Title"});}}// other properties
})
4. 自定义组件 - 数据监听器
4.1 什么是数据监听器
数据监听器用于监听组件内部 data
或 properties
的变化,当数据发生变化时触发相应的操作。
custom-component.js:
Component({data: {count: 0},observers: {'count': function (newVal, oldVal) {console.log('count changed', newVal, oldVal);}},// other properties and methods
})
4.2 数据监听器的基本用法
通过定义监听器函数,可以在数据变化时执行自定义的逻辑。
4.3 监听对象属性的变化
数据监听器不仅可以监听基本类型的数据变化,还可以监听对象属性的变化,实现
更精细化的数据控制。
custom-component.js:
Component({data: {user: {name: 'John',age: 25}},observers: {'user.name': function (newVal, oldVal) {console.log('user name changed', newVal, oldVal);}},// other properties and methods
})
5. 自定义组件 - 纯数据字段
5.1 什么是纯数据字段
纯数据字段是一种特殊的数据形式,用于在组件内定义一些纯粹的数据,不参与视图层的渲染。
5.2 使用规则
纯数据字段的使用规则相对简单,只需要在组件的 json
文件中声明即可。
custom-component.json:
{"component": true,"pureData": {"fieldName": "fieldValue"}
}
5.3 使用纯数据字段改造数据监听器案例
通过使用纯数据字段,可以改造数据监听器,使得组件更加清晰和易维护。
custom-component.json:
{"component": true,"pureData": {"isListening": false},"observers": {'isListening': function (newVal) {if (newVal) {console.log('Start listening');// Start listening logic} else {console.log('Stop listening');// Stop listening logic}}}
}
6. 自定义组件 - 组件的生命周期
6.1 组件全部的生命周期函数
小程序中,组件有一系列的生命周期函数,包括 created
、attached
、ready
、moved
、detached
等。
custom-component.js:
Component({lifetimes: {created() {console.log('component created');},attached() {console.log('component attached');},ready() {console.log('component ready');},moved() {console.log('component moved');},detached() {console.log('component detached');}},// other properties and methods
})
6.2 组件主要的生命周期函数
了解组件的主要生命周期函数有助于合理地处理组件的初始化、渲染和销毁过程。
6.3 lifetimes 节点
lifetimes
节点用于定义组件的生命周期函数,包括 created
、attached
、ready
、moved
、detached
等。
7. 自定义组件 - 组件所在页面的生命周期
7.1 什么是组件所在页面的生命周期
组件所在页面的生命周期指的是组件在页面中的生命周期,包括 show
、hide
等。
custom-component.js:
Component({pageLifetimes: {show() {console.log('component show');},hide() {console.log('component hide');}},// other properties and methods
})
7.2 pageLifetimes 节点
通过 pageLifetimes
节点,可以定义组件所在页面的生命周期函数,实现组件与页面的协同工作。
7.3 生成随机的 RGB 颜色值
在页面生命周期函数中,可以实现一些动态的操作,例如生成随机的 RGB 颜色值,为用户提供更丰富的交互体验。
custom-component.js:
Component({pageLifetimes: {show() {const randomColor = `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`;console.log('generated random color', randomColor);}},// other properties and methods
})
8. 自定义组件 - 插槽
8.1 什么是插槽
插槽是一种用于在组件内部承载内容的机制,使得组件可以更加灵活地适应不同的使用场景。
custom-component.wxml:
<view class="container"><view class="header">Header</view><slot></slot><view class="footer">Footer</view>
</view>
8.2 单个插槽
组件可以定义单个插槽,用于承载外部传入的内容。
index.wxml:
<custom-component><view>Content Goes Here</view>
</custom-component>
8.3 启用多个插槽
通过启用多个插槽,可以支持更复杂的内容布局和组合。
custom-component.wxml:
<view class="container"><view class="header">Header</view><slot name="content"></slot><view class="footer">Footer</view><slot name="footer"></slot>
</view>
8.4 定义多个插槽
在组件内部,可以通过定义多个插槽,为不同的内容提供不同的展示方式。
index.wxml:
<custom-component><view slot="content">Content Goes Here</view><view slot="footer">Custom Footer</view>
</custom-component>
8.5 使用多个插槽
在页面中使用组件时,可以根据需要传入不同的内容到不同的插槽中,实现更灵活的布局。
9. 自定义组件 - 父子组件之间的通信
9.1 父子组件之间通信的 3 种方式
父子组件之间可以通过属性绑定、事件绑定和获取组件实例等方式进行通信,实现数据的传递和操作的触发。
9.2 属性绑定
通过属性绑定,父组件可以向子组件传递数据,实现数据的共享。
parent-component.wxml:
<child-component title="{{parentTitle}}"></child-component>
child-component.js:
Component({properties: {title: String},// other properties and methods
})
9.3 事件绑定
通过事件绑定,子组件可以向父组件发送事件,触发父组件中的相应逻辑。
child-component.js:
Component({methods: {onTap() {this.triggerEvent('customEvent', { data: 'Hello from Child' });}}// other properties
})
parent-component.wxml:
<child-component bind:customEvent="onChildEvent"></child-component>
parent-component.js:
Page({onChildEvent(event) {console.log('Received custom event from child:', event.detail.data);}// other methods
})
9.4 获取组件实例
通过获取组件实例,可以直接调用组件的方法,实现更直接的通信方式。
parent-component.js:
Page({onReady() {const childComponent = this.selectComponent('#child');childComponent.doSomething();}// other methods
})
parent-component.wxml:
<child-component id="child"></child-component>
10. 自定义组件 - behaviors
10.1 什么是 behaviors
Behaviors 是一种可复用的代码块,通过引入 behaviors,可以将一组方法、数据和生命周期函数注入到组件中。
10.2 behaviors 的工作方式
Behaviors 通过混入的方式工作,将 behaviors 中的内容合并到组件中,实现代码的复用。
10.3 创建 behavior
在小程序中,可以创建自定义的 behavior,定义其中的方法和数据。
custom-behavior.js:
module.exports = Behavior({data: {behaviorData: 'This is from behavior'},methods: {behaviorMethod() {console.log('Behavior method');}}
})
10.4 导入并使用 behavior
通过在组件的 behaviors
字段中导入并使用 behavior,实现代码的重用和模块化。
custom-component.js:
const customBehavior = require('/path/to/custom-behavior');Component({behaviors: [customBehavior],// other properties and methods
})
10.5 behavior 中所有可用的节点
可用的节点 | 类型 | 是否必填 | 描述 |
---|---|---|---|
created | Function | 否 | 组件生命周期函数,在组件实例刚刚被创建时执行。 |
attached | Function | 否 | 组件生命周期函数,在组件实例进入页面节点树时执行。 |
ready | Function | 否 | 组件生命周期函数,在组件布局完成后执行。 |
moved | Function | 否 | 组件生命周期函数,在组件实例被移动到节点树另一个位置时执行。 |
detached | Function | 否 | 组件生命周期函数,在组件实例被从页面节点树移除时执行。 |
data | Object | 否 | 组件的内部数据,用于页面渲染。 |
methods | Object | 否 | 组件的方法,可以在页面内调用。 |
properties | Object | 否 | 组件的属性,用于接收父组件传递的数据。 |
lifetimes | Object | 否 | 组件的生命周期函数集合,包括 created、attached、ready、moved、detached。 |
pageLifetimes | Object | 否 | 组件所在页面的生命周期函数集合,包括 show、hide。 |
definitionFilter | Function | 否 | 用于过滤 behaviors 中定义的字段,返回 true 表示保留,返回 false 表示过滤。 |
10.6 同名字段的覆盖和组合规则
当组件和 behavior 中存在同名字段时,小程序有一套规则来确定最终的取值,包括覆盖和组合的方式。
二、使用npm包
1. 使用 npm 包 - Vant Weapp
1.1 官方文档地址
Vant Weapp官方文档
1.2 安装教程
Vant Weapp安装教程
1.3 CSS 变量的基本用法MDN文档
CSS 变量的基本用法MDN文档
1.4 Vant 官方配置文件
Vant官方配置文件
2. 使用 npm 包 - API Promise化
2.1 基于回调函数的异步 API 的缺点
传统的异步 API 多采用回调函数的方式,但这种方式存在回调地狱、可读性差等问题。
2.2 什么是 API Promise 化
API Promise 化是指将原本使用回调函数的异步 API 转化为返回 Promise 对象的形式,以更直观、便捷地处理异步操作。
2.3 实现 API Promise 化
使用 miniprogram-api-promise
这个第三方的 npm 包的 promisifyAll
方法,可以实现将小程序原生的异步 API 转化为 Promise 化的形式。
首先,安装 miniprogram-api-promise
:
npm install miniprogram-api-promise
然后,在小程序代码中使用:
//1.在小程序入口文件中调用一次 promisifyAll()方法
import { promisifyAll } from 'miniprogram-api-promise'
//2.声明一个常量,为一个空对象
const wxp = wx.p = {}
//3.调用 promisifyAll()方法
promisifyAll(wx, wxp)
2.4 调用 Promise 化之后的异步 API
- 我们在
wx
全局对象上定义一个属性p
让他和wxp
指向同一个空对象 promisifyAll
: 做的事就是将wx
拥有的属性方法都copy
并改造了一份给了wxp
这个对象- 这样wxp和wx.p就都指向了同一个对象
//使用
async getInfo () {const { data: res } = await wx.p.request({url: 'https://www.escook.cn/api/get',method: 'GET',data: {name: 'zs',age: 19}})// res 处理console.log(res)
}
通过这种方式,可以更清晰、简洁地处理小程序的异步 API 调用。
三、全局数据共享
什么是全局数据共享
全局数据共享是指在小程序中,使数据能够在不同页面或组件之间进行共享,以便实现全局状态的管理和同步更新。
小程序中的全局数据共享方案
在小程序中,有多种全局数据共享方案,其中之一是使用第三方库 MobX。MobX 是一个简单、可扩展的状态管理库,可以帮助实现全局数据的响应式更新和共享。
1. 全局数据共享 - MobX
1.1 安装 MobX 相关的包
首先,安装 MobX 及其相关的包:
npm install mobx mobx-miniprogram
1.2 创建 MobX 的 Store 实例
创建一个 MobX 的 Store 实例,用于管理全局数据:
// store.js
const { observable, action } = require('mobx-miniprogram');class AppStore {@observable globalData = {userInfo: null,// other global data};@action setUserInfo(userInfo) {this.globalData.userInfo = userInfo;}
}module.exports = new AppStore();
1.3 将 Store 中的成员绑定到页面中
在需要使用全局数据的页面中,将 Store 中的成员绑定到页面:
// index.js
const app = getApp();
const store = require('../../store');Page({onLoad() {this.setData({userInfo: app.store.globalData.userInfo,});// 监听 globalData 的变化this.dispose = store.observe(() => {this.setData({userInfo: app.store.globalData.userInfo,});});},onUnload() {// 移除监听this.dispose();},
});
1.4 在页面上使用 Store 中的成员
在页面中可以直接使用 Store 中的成员:
<!-- index.wxml -->
<view>{{ userInfo.nickName }}</view>
1.5 将 Store 中的成员绑定到组件中
在需要使用全局数据的组件中,也可以将 Store 中的成员绑定到组件:
// custom-component.js
const store = require('../../store');Component({lifetimes: {attached() {this.setData({userInfo: store.globalData.userInfo,});// 监听 globalData 的变化this.dispose = store.observe(() => {this.setData({userInfo: store.globalData.userInfo,});});},detached() {// 移除监听this.dispose();},},
});
1.6 在组件中使用 Store 中的成员
在组件中同样可以直接使用 Store 中的成员:
<!-- custom-component.wxml -->
<view>{{ userInfo.nickName }}</view>
通过以上步骤,就实现了在小程序中使用 MobX 进行全局数据的共享和响应式更新。
四、分包
1、分包 - 基础概念
1.1 什么是分包
分包是指将小程序项目划分成不同的子包,每个子包都可以包含页面、组件、资源文件等,实现模块化管理和按需加载。
1.2 分包的好处
- 减小小程序首次启动时的下载体积,提高启动速度。
- 按需加载,优化用户体验。
- 灵活管理项目结构,方便团队协作和代码维护。
1.3 分包前项目的构成
在进行分包前,项目可能是单一的整体,包含全部页面和资源。
1.4 分包后项目的构成
分包后,项目会被划分为主包和多个子包,每个子包可以包含特定的功能模块。
1.5 分包的加载规则
小程序在启动时会先下载主包,然后在需要时再下载子包。子包是按需加载的,用户访问对应的页面或组件时才会下载相关子包。
1.6 分包的体积限制
每个分包的体积不能超过 2MB,超过会导致分包加载失败。
2、分包 - 使用分包
2.1 配置方法
在小程序的 app.json
文件中使用 subpackages
字段配置分包信息,指定每个分包的路径和名字。
{"pages": ["pages/index/index"],"subpackages": [{"root": "subpackage1","pages": ["pages/subpage1/index","pages/subpage1/detail"]},{"root": "subpackage2","pages": ["pages/subpage2/index","pages/subpage2/detail"]}]
}
2.2 打包原则
主包中包含 app.json
、app.js
、app.wxss
、project.config.json
等文件,每个分包下都有一个独立的 package.json
。
2.3 引用原则
在主包中,可以直接引用主包和其他分包的页面和组件。在分包中,只能引用自己分包内的页面和组件。
3、分包 - 独立分包
3.1 什么是独立分包
独立分包是指一个分包中包含了完整的小程序结构,可以独立运行。主包和其他分包可以引用独立分包内的页面和组件。
3.2 独立分包和普通分包的区别
独立分包可以包含完整的小程序结构,具备更强的独立性。普通分包只能包含部分页面和资源。
3.3 独立分包的应用场景
适用于某个功能模块比较独立,可以独立运行的场景。
3.4 独立分包的配置方法
在 app.json
的 subpackages
中配置 "independent": true
:
{"subpackages": [{"root": "independent-package","pages": ["pages/index/index","pages/detail/detail"],"independent": true}]
}
3.5 引用原则
独立分包内的页面和组件可以被主包和其他分包引用。
4、分包 - 分包预下载
4.1 什么是分包预下载
分包预下载是指在小程序启动时,提前加载分包的部分代码和资源,加速分包的加载速度。
4.2 配置分包的预下载
在 app.json
中的 subpackages
中使用 "preloadRule"
配置预下载规则:
{"subpackages": [{"root": "subpackage1","pages": ["pages/subpage1/index"],"preloadRule": {"pages/subpage1/index": {"network": "all","packages": ["subpackage1"]}}}]
}
4.3 分包预下载的限制
- 预下载的代码和资源会占用用户的存储空间。
- 预下载仅在用户打开小程序时生效,离开小程序后失效。
- 预下载的分包大小限制为 2MB。