原创 AI风初
大家好,我是AI风初!今天为大家带来学习小程序开发过程中的一些学习笔记分享。
关注公众号"AI风初",了解更多。
1.wxml、wxss、wx.js、json
这部分和web的html等没太多区别,所以跳过,有欠缺的话建议先学html、css、JavaScript会好些。
目录
2. 事件处理
-
2.1 事件基础
-
2.1.1 事件类型
-
2.1.2 事件冒泡与捕获
-
-
2.2 事件绑定
-
2.2.1 WXML中的事件绑定
-
2.2.2 JS中的事件绑定
-
-
2.3 事件对象
-
2.3.1 常用事件对象属性
-
2.3.2 自定义事件传递数据
-
3. 数据绑定
-
3.1 数据绑定基础
-
3.1.1 数据绑定语法
-
3.1.2 双向数据绑定
-
-
3.2 数据更新机制
-
3.2.1 setData方法
-
3.2.2 局部状态与全局状态
-
-
3.3 列表渲染与条件渲染
-
3.3.1 列表渲染基础
-
3.3.2 条件渲染语法
-
4. 状态管理
-
4.1 状态管理概念
-
4.1.1 状态与组件的关系
-
4.1.2 状态管理的重要性
-
-
4.2 小程序状态管理实践
-
4.2.1 使用全局变量
-
4.2.2 使用Vuex模式
-
-
4.3 状态管理工具
-
4.3.1 状态管理库介绍
-
4.3.2 状态管理库使用示例
-
2. 事件处理
2.1 事件基础
2.1.1 事件类型
在微信小程序中,事件是指用户与页面元素交互时产生的操作,如点击、触摸、表单提交等。小程序支持的事件类型包括但不限于:
-
tap: 点击事件
-
input: 输入事件,常用于表单输入
-
submit: 表单提交事件
-
touchstart: 触摸开始
-
touchmove: 触摸移动
-
touchend: 触摸结束
2.1.2 事件冒泡与捕获
事件冒泡是指当一个元素触发了事件,这个事件会从该元素开始,逐级向上传播到文档的根元素。事件捕获则是事件从文档的根元素开始,逐步向下传播到目标元素。
在小程序中,可以通过catch-
和capture-
前缀来阻止事件冒泡或捕获事件。
2.2 事件绑定
2.2.1 WXML中的事件绑定
在WXML中,通过在元素上添加bind
前缀来绑定事件,例如:
<button bindtap="onTap">点击我</button>
2.2.2 JS中的事件绑定
在JS中,可以通过this.triggerEvent
方法来触发事件:
triggerEvent
是微信小程序框架提供的一个函数,允许开发者在 JavaScript 文件中主动触发一个事件。
基本用法
triggerEvent
函数的基本用法如下:
this.triggerEvent(eventName, eventObject);
-
eventName
: 要触发的事件名称,必须以大写字母开头。 -
eventObject
: 一个对象,包含了事件的详细信息,通常是detail
对象,它可以包含任何自定义数据。
示例
假设我们有一个自定义组件,我们想要在组件内部触发一个名为 customEvent
的事件,并且传递一些自定义数据。
// 假设这是组件的某个方法
triggerCustomEvent: function() {
// 触发事件,eventName 为 'customEvent',传递一个包含自定义数据的 eventObject
this.triggerEvent('customEvent', {
detail: {
message: '这是一个自定义事件',
data: '这里是一些额外的数据'
}
});
}
事件监听
为了监听到这个事件,我们需要在页面的 WXML 文件中为该组件绑定相应的事件处理器:
<your-component bindcustomevent="onCustomEvent"></your-component>
然后在页面的 JS 文件中定义事件处理函数:
Page({
onCustomEvent: function(event) {
console.log(event.detail.message); // 输出: "这是一个自定义事件"
console.log(event.detail.data); // 输出: "这里是一些额外的数据"
}
});
当 triggerCustomEvent
方法被调用时,customEvent
事件将被触发,并且 onCustomEvent
函数将被执行,接收到传递的自定义数据。
学习目标
-
理解
triggerEvent
的作用和基本用法。 -
能够使用
triggerEvent
触发自定义事件并传递数据。 -
知道如何在组件外部监听并响应这些自定义事件。
实践模拟
-
创建组件:创建一个简单的自定义组件,比如一个按钮。
-
绑定事件:在组件的 WXML 文件中,使用
bind
来绑定自定义事件。 -
触发事件:在组件的 JS 文件中,定义一个方法来触发自定义事件。
-
监听事件:在页面的 JS 文件中,定义一个事件处理函数来监听这个自定义事件。
2.3 事件对象
事件对象是当事件触发时,小程序传递给事件处理函数的数据。包含了关于事件的详细信息。
2.3.1 常用事件对象属性
以下是一些常用的事件对象属性:
-
type
: 事件类型 -
target
: 触发事件的元素 -
currentTarget
: 绑定事件的元素 -
detail
: 自定义数据
2.3.2 自定义事件传递数据
在小程序中,可以通过在事件绑定时传递一个对象作为detail
属性,然后在事件处理函数中获取这个对象:
<button bindtap="onTap" data-custom="自定义数据">点击我</button>
Page({
onTap: function(event) {
console.log(event.currentTarget.dataset.custom); // 输出: "自定义数据"
}
});
实践模拟
-
创建一个页面:在小程序项目中创建一个新的页面,比如叫做
eventPage
。 -
编写WXML:在
eventPage.wxml
中添加一个按钮元素,并绑定点击事件。
<view class="container">
<button bindtap="onTap">点击我</button>
</view>
-
3.编写JS:在
eventPage.js
中定义onTap
事件处理函数。
Page({
onTap: function(event) {
console.log('按钮被点击了!');
}
});
3. 数据绑定
3.1 数据绑定基础
3.1.1 数据绑定语法
在微信小程序中,数据绑定允许开发者将页面的数据与视图层的元素进行关联。数据绑定的基本语法是通过在 WXML 中使用两个花括号 {}
将数据包裹起来。
<view>{{ message }}</view>
这里的 message
是一个数据对象,它需要在对应的 JS 文件中被定义,并通过 data
属性进行初始化。
Page({
data: {
message: 'Hello, 小程序!'
}
});
3.1.2 双向数据绑定
微信小程序支持双向数据绑定,即当数据变化时,视图会自动更新;同样,当用户与视图交互(如输入文本)时,数据也会相应地更新。
<input type="text" bindinput="onInput" value="{{ message }}"/>
在这个例子中,当用户在输入框中输入文本时,message
的值会实时更新。
3.2 数据更新机制
3.2.1 setData 方法
在微信小程序中,更新数据的唯一方式是通过调用 setData
方法。setData
接受一个对象作为参数,对象中的键是页面的 data
属性中定义的字段名,值是要更新的新数据。
this.setData({
message: '新的信息'
});
调用 setData
后,页面上与 message
绑定的元素会自动更新。
3.2.2 局部状态与全局状态
-
局部状态:仅在当前页面或组件内有效的状态。
-
全局状态:可以在多个页面或组件之间共享的状态。
全局状态管理通常需要借助于额外的状态管理工具或设计模式,如 Vuex。
3.3 列表渲染与条件渲染
3.3.1 列表渲染基础
在微信小程序中,wx:for
是一个非常重要的指令,它用于对数组进行遍历,从而实现列表的渲染。通过使用 wx:for
,开发者可以基于数组中的每个元素动态生成一系列的视图元素。
基本用法
wx:for
的基本用法如下:
<view wx:for="{{ array }}" wx:key="unique">
{{ item }}
</view>
-
wx:for="{{ array }}"
:指定要遍历的数组。这里的array
是在页面的data
对象中定义的数组。 -
wx:key="unique"
:为每个循环生成的元素指定一个唯一的标识符。unique
是一个变量名,它可以是数组元素中的任意唯一属性,用于提高列表渲染的效率和性能。
item
和 index
在 wx:for
的循环体中,有两个特殊的变量可以使用:
-
item
:表示当前遍历到的数组元素。 -
index
:表示当前元素的索引值。
<view wx:for="{{ array }}" wx:key="unique">
{{ index }}: {{ item }}
</view>
示例
Page({
data: {
products: [
{ name: '商品1', price: '100' },
{ name: '商品2', price: '200' },
// 更多商品...
]
}
});
遍历:
<view class="product-list">
<view wx:for="{{ products }}" wx:key="name" class="product-item">
<view class="product-name">{{ item.name }}</view>
<view class="product-price">{{ item.price }}</view>
</view>
</view>
在这个例子中,products
是要遍历的数组,wx:key="name"
指定了每个商品的唯一标识符,这里使用了商品的 name
属性。item
代表当前遍历到的商品对象,所以可以使用 item.name
和 item.price
来访问商品的名称和价格。
学习目标
-
理解
wx:for
的作用和基本用法。 -
能够使用
wx:for
遍历数组并动态生成视图元素。 -
知道如何在循环中使用
item
和index
变量。
实践模拟
-
定义数组数据:在页面的 JS 文件中定义一个数组类型的数据。
-
使用
wx:for
渲染列表:在 WXML 文件中使用wx:for
指令遍历数组,并为每个元素生成视图。 -
指定唯一 key:为
wx:for
指定一个wx:key
,提高列表渲染的性能。 -
样式和事件:为列表项添加样式,并根据需要绑定事件。
3.3.2 条件渲染语法
条件渲染使用 wx:if
、wx:elif
和 wx:else
指令来实现。在微信小程序中,wx:if
是一个非常有用的指令,它用于条件渲染,即根据条件判断是否需要渲染某个视图元素。wx:if
可以单独使用,也可以与 wx:elif
和 wx:else
结合使用,实现更复杂的条件逻辑。
基本用法
wx:if
的基本用法如下:
<view wx:if="{{ condition }}">需要渲染的内容</view>
-
wx:if="{{ condition }}"
:指定一个条件表达式。这里的condition
是一个布尔值,可以是一个变量或一个表达式的计算结果。如果condition
为true
,则内部的<view>
元素将被渲染。
组合使用
wx:if
可以与 wx:elif
(else-if) 和 wx:else
结合使用,实现多重条件判断:
<view wx:if="{{ condition1 }}">条件1满足时渲染的内容</view> <view wx:elif="{{ condition2 }}">条件2满足时渲染的内容</view> <view wx:else>其他情况渲染的内容</view>
这里的 condition1
、condition2
是布尔值,分别表示不同的条件。
示例
Page({
data: {
isLoggedIn: false
}
});
条件渲染:
<view wx:if="{{ isLoggedIn }}">欢迎回来,您已登录!</view>
<view wx:else>您还未登录,请先登录。</view>
在这个例子中,isLoggedIn
是一个布尔类型的数据,表示用户是否已经登录。根据 isLoggedIn
的值,将渲染不同的提示信息。
学习目标
-
理解
wx:if
的作用和基本用法。 -
能够使用
wx:if
实现条件渲染。 -
知道如何结合使用
wx:if
、wx:elif
和wx:else
来实现多重条件判断。
实践模拟
-
定义条件数据:在页面的 JS 文件中定义一个或多个条件数据。
-
使用
wx:if
进行条件渲染:在 WXML 文件中使用wx:if
指令根据条件渲染不同的视图元素。 -
组合使用
wx:if
、wx:elif
和wx:else
:根据需要实现更复杂的条件逻辑。 -
测试条件渲染:通过改变条件数据的值,观察视图的变化。
4. 状态管理
4.1 状态管理概念
状态管理是前端应用开发中的一个重要概念,特别是在复杂应用中,良好的状态管理是保持应用可维护性和可扩展性的关键。
4.1.1 状态与组件的关系
在小程序中,状态通常指的是应用中的数据,这些数据可以是全局的,也可以是局部的。组件可以拥有自己的局部状态,也可以使用全局状态。
4.1.2 状态管理的重要性
-
数据共享:在多个组件之间共享数据。
-
数据流:确保数据流的一致性和可预测性。
-
性能优化:避免不必要的渲染和性能损耗。
4.2 小程序状态管理实践
4.2.1 使用全局变量
小程序中可以使用全局变量来存储那些需要在不同页面间共享的数据。
// app.js
App({
onLaunch: function () {
// 全局状态
this.globalData = {
userInfo: null
};
}
});
在其他页面或组件中,可以通过 getApp().globalData
来访问这些全局状态。这儿给一个还算全面的事例:
1. 在 app.js
中定义全局状态
首先,我们需要在小程序的根目录下的 app.js
文件中定义全局状态:
App({
onLaunch: function () {
// 初始化全局状态
this.globalData = {
user: null, // 用户信息
themeColor: 'blue' // 主题颜色
};
}
});
2. 在页面或组件中访问全局状态
示例页面:globalDataPage.js
Page({
data: {
// 初始页面数据
userInfo: {},
themeColor: ''
},
onLoad: function() {
// 页面加载时,从全局状态获取数据
this.setData({
userInfo: getApp().globalData.user,
themeColor: getApp().globalData.themeColor
});
}
});
对应的 WXML 文件:globalDataPage.wxml
<view class="userInfo">
<text>用户信息: {{userInfo}}</text>
</view>
<view class="themeColor">
<text>主题颜色: {{themeColor}}</text>
</view>
对应的 WXSS 文件:globalDataPage.wxss
.userInfo text {
/* 样式 */
}
.themeColor text {
/* 样式 */
}
3. 更新全局状态
当需要更新全局状态时,我们可以直接修改 getApp().globalData
中的数据,然后在使用这些数据的页面或组件中调用 this.setData()
来更新视图。
示例:更新用户信息
// 假设这是某个登录成功的回调函数
function loginSuccess(userInfo) {
// 更新全局用户信息
getApp().globalData.user = userInfo;
// 假设我们需要更新使用了 userInfo 的所有页面
const pages = getCurrentPages();//调用 getCurrentPages() 获得当前页面栈的数组,这个数组包含了从当前页面到根页面的所有页面实例。
pages.forEach((page) => {
if (page.setData && page.data.userInfo) {//对于数组中的每个 page 实例,首先检查它是否有 setData 方法和 data 对象中是否有 userInfo 属性。
page.setData({
userInfo: getApp().globalData.user//有则更新
});
}
});
}
#我对获取当前页面栈方法的机制原理比较好奇所以搜了点资料,没有兴趣的话可以自行跳过。
1,页面栈是由用户操作顺序决定的,即用户从首页进入到其他页面,形成的页面序列。这个函数通常用于需要获取当前页面路径或状态的场合。
2,getCurrentPages()
返回值
-
getCurrentPages()
返回的是一个数组,数组中的每个元素都是一个对象,代表一个页面的实例。 -
数组中的页面实例是按照从后往前(即从当前页面到首页)的顺序排列的,即数组的最后一个元素是首页的实例,而第一个元素是当前页面的实例。
3,页面实例对象
页面实例对象包含了该页面的以下信息:
-
setData
方法:用于更新页面的data
对象,从而触发页面的重新渲染。 -
data
对象:包含了页面的初始化数据和通过setData
更新的数据。 -
其他页面特有的属性和方法。
4,注意事项
-
使用
getCurrentPages()
时要注意性能影响,尤其是当页面栈较深时,遍历和更新页面可能会造成性能问题。 -
通常情况下,不推荐在小程序中进行全局的状态更新,因为这可能会导致不可预见的副作用。更推荐的做法是使用局部状态管理,或者使用状态管理库来集中管理状态。
注意事项
-
直接修改
getApp().globalData
并不会触发页面的重新渲染。因此,如果需要更新视图,必须使用this.setData()
方法。 -
全局状态应当用于存储那些不会频繁变动的数据。对于经常变化的数据,更推荐使用页面或组件的局部状态。#所以会限制用户修改个人信息的次数
4.2.2 使用Vuex模式
对于更复杂的状态管理,可以使用 Vuex 模式。虽然目前微信小程序官方没有直接提供 Vuex,但是可以借鉴 Vuex 的理念来组织代码。
-
State:定义状态结构。
-
Getters:从状态派生出一些状态。
-
Mutations:更改状态的方法。
-
Actions:可以是异步的,用于触发 mutations。
4.2.3 使用小程序状态管理库
市面上有一些第三方的状态管理库,如 wechat-weapp-redux
,它们借鉴了 Redux 的概念,可以用于小程序中的状态管理。
4.3 状态管理工具
4.3.1 状态管理库介绍
状态管理库如 Redux 或 MobX 可以用于管理全局状态。虽然这些库不是为小程序专门设计的,但可以借鉴其概念。
4.3.2 状态管理库使用示例
以 Redux 为例,以下是如何在小程序中使用类似 Redux 的状态管理:
// store.js
const initialState = {
count: 0
};
const store = {
state: initialState,
reducers: {
increment(state) {
return { count: state.count + 1 };
}
}
};
export default store;
在页面或组件中,可以使用 store
来管理状态:
import store from './store';
Page({
onShow() {
this.setState({
count: store.state.count
});
},
increment() {
store.reducers.increment();
this.setData({
count: store.state.count
});
}
});
实践模拟
-
定义状态结构:确定需要全局管理的状态数据。
-
创建状态管理逻辑:根据需要选择使用全局变量、Vuex 模式或引入状态管理库。
-
在组件中使用状态:在页面或组件中通过
setData
更新视图,或通过状态管理库的 API 来更改和访问状态。 -
测试状态更新:通过用户交互或异步操作来更改状态,并观察视图的更新。