做小程序开发已有快一年,写下自己的心得,希望多大家有帮助!微信开放文档
小程序Dom元素使用的是view而不是div。
小程序中block元素不渲染在页面中,只用来作为逻辑容器 
-
小程序使用wx:if和wx:for语法
-
小程序绑定事件使用 bindtap和catchtap,bindtap会事件冒泡 而catchTap不会事件冒泡。
小程序动态绑定样式或类名
一、动态绑定样式
通过 style 属性可以动态设置元素的内联样式。你可以将样式值绑定到数据中,并根据逻辑动态更新。
<view style="width: {{width}}px; height: {{height}}px; background: {{color}};"></view>
<button bindtap="changeStyle">改变样式</button>
Page({
data: {
width: 100,
height: 100,
color: 'red'
},
changeStyle() {
this.setData({
width: 200,
height: 200,
color: 'blue'
});
}
});
说明:style 属性中的值使用双大括号 {{}} 绑定到数据。
调用 setData 更新数据后,视图会自动刷新
二、动态拼接样式
如果需要拼接多个样式,可以在 JavaScript 中生成完整的样式字符串:
基本用法 :
<view style="{{dynamicStyle}}"></view>
<button bindtap="updateStyle">更新样式</button>
Page({
data: {
dynamicStyle: 'width: 100px; height: 100px; background: red;'
},
updateStyle() {
this.setData({
dynamicStyle: 'width: 200px; height: 200px; background: green;'
});
}
});
.active {
color: green;
}
.inactive {
color: red;
}
说明:
- 使用三元运算符 {{condition ? 'classA' : 'classB'}} 动态切换类名。
- 在 CSS 文件中定义 active 和 inactive 类
多个类名的拼接:
如果需要同时应用多个类名,可以使用数组或字符串拼接的方式:
<view class="base-class {{extraClass}}">内容</view>
<button bindtap="addExtraClass">添加额外类名</button>
Page({
data: {
extraClass: ''
},
addExtraClass() {
this.setData({
extraClass: 'highlight'
});
}
});
.base-class {
font-size: 16px;
}
.highlight {
color: blue;
font-weight: bold;
}
条件组合类名
如果需要根据多个条件动态组合类名,可以使用模板语法:
<view class="item {{isBold ? 'bold' : ''}} {{isRed ? 'red' : ''}}">内容</view>
<button bindtap="toggleBold">切换加粗</button>
<button bindtap="toggleRed">切换红色</button>
Page({
data: {
isBold: false,
isRed: false
},
toggleBold() {
this.setData({
isBold: !this.data.isBold
});
},
toggleRed() {
this.setData({
isRed: !this.data.isRed
});
}
});
.bold {
font-weight: bold;
}
.red {
color: red;
}
动态绑定样式与类名结合
可以同时动态绑定样式和类名,以实现更复杂的效果,如获取设备的宽高来设置导航栏位置等:
<view class="{{isActive ? 'active' : 'inactive'}}" style="font-size: {{fontSize}}px;">内容</view>
<button bindtap="toggleActive">切换状态</button>
<button bindtap="increaseFontSize">增大字体</button>
Page({
data: {
isActive: true,
fontSize: 16
},
toggleActive() {
this.setData({
isActive: !this.data.isActive
});
},
increaseFontSize() {
this.setData({
fontSize: this.data.fontSize + 2
});
}
});
.active {
color: green;
}
.inactive {
color: red;
}
总结
- 动态绑定样式:通过 style 属性绑定数据,支持动态更新样式值。
- 动态绑定类名:通过 class 属性绑定数据,支持条件切换或多类名拼接。
- 数据驱动:尽量避免直接操作 DOM,而是通过 setData 更新数据,触发视图刷新。
小程序获取Dom元素的方法
在小程序中,获取 DOM 元素的方式与传统的 Web 开发有所不同。由于小程序的视图层和逻辑层是分离的,因此无法直接使用 document.querySelector 或类似的方法来操作 DOM。以下是小程序中获取 DOM 元素的常见方法:
使用 SelectorQuery
基本用法
Page({
data: {},
onReady() {
// 创建 SelectorQuery 实例
const query = wx.createSelectorQuery();
// 查询指定选择器的节点
query.select('#myElement').boundingClientRect((rect) => {
console.log(rect); // 输出元素的位置和尺寸信息
}).exec();
}
});
获取多个元素
如果需要获取多个元素,可以使用 selectAll 方法:
Page({
data: {},
onReady() {
const query = wx.createSelectorQuery();
// 查询所有匹配的选择器的节点
query.selectAll('.myClass').boundingClientRect((rects) => {
console.log(rects); // 输出所有匹配元素的位置和尺寸信息
}).exec();
}
});
获取滚动位置
如果需要获取某个滚动容器的滚动位置,可以使用 scrollOffset 方法:
Page({
data: {},
onReady() {
const query = wx.createSelectorQuery();
query.select('#scrollView').scrollOffset((res) => {
console.log(res.scrollTop, res.scrollLeft); // 输出滚动位置
}).exec();
}
});
使用 NodesRef 的其他方法
SelectorQuery 返回的 NodesRef 对象支持多种方法,用于获取不同的节点信息。
获取节点的字段信息
fields 方法可以获取节点的特定字段信息,例如大小、位置、数据集等:
Page({
data: {},
onReady() {
const query = wx.createSelectorQuery();
query.select('#myElement').fields({
size: true, // 获取宽高
scrollOffset: true, // 获取滚动位置
dataset: true // 获取自定义数据
}, (res) => {
console.log(res.width, res.height); // 宽高
console.log(res.dataset); // 自定义数据
}).exec();
}
});
获取上下文信息
如果需要获取 Canvas 或视频等组件的上下文,可以使用 context 方法:
Page({
data: {},
onReady() {
const query = wx.createSelectorQuery();
query.select('#myCanvas').context((res) => {
console.log(res.context); // 输出 Canvas 上下文
}).exec();
}
});
注意事项:
- 异步性:SelectorQuery 是异步的,必须调用 .exec() 才会执行查询。
- 时机问题:确保在页面或组件渲染完成后再调用 SelectorQuery,通常可以在 onReady 生命周期中执行。
- 性能优化:避免频繁调用 SelectorQuery,尤其是在高频事件(如滚动或触摸事件)中。
- 兼容性:不同平台的小程序(如微信、支付宝、百度等)可能对 SelectorQuery 的支持略有差异,请参考对应平台的文档
小程序父子组件传参和事件调用
一、父组件向子组件传参
父组件可以通过 properties 向子组件传递参数。这是最常见的一种通信方式。
1.子组件定义接收参数
在子组件的 properties 中定义需要接收的参数:
// 子组件(child-component.js)
Component({
properties: {
// 接收父组件传递的参数
title: {
type: String,
value: '默认标题'
},
count: {
type: Number,
value: 0
}
}
});
2.父组件传递参数
在父组件的 WXML 中通过属性绑定的方式传递参数:
<!-- 父组件 -->
<child-component title="父组件传递的标题" count="{{parentCount}}"></child-component>
// 父组件(parent-component.js)
Page({
data: {
parentCount: 42
}
});
3.子组件使用参数
在子组件中可以直接通过 this.properties 访问传递过来的参数(虽然使用this.data也能访问,但更推荐使用this.properties):
console.log(this.properties.title); // 输出:父组件传递的标题
console.log(this.properties.count); // 输出:42
二、子组件向父组件传递事件
子组件可以通过触发自定义事件向父组件传递数据。父组件需要监听这些事件并处理。
1.子组件触发事件
在子组件中使用 triggerEvent 方法触发事件,并传递数据:
// 子组件(child-component.js)
Component({
methods: {
sendDataToParent() {
const data = { message: '来自子组件的消息', value: 123 };
this.triggerEvent('customEvent', data);
}
}
});
2.父组件监听事件
在父组件的 WXML 中通过 bind 或 catch 监听子组件触发的事件:
<!-- 父组件 -->
<child-component bind:customEvent="handleCustomEvent"></child-component>
在父组件的 JS 文件中定义事件处理函数:
// 父组件(parent-component.js)
Page({
handleCustomEvent(event) {
console.log(event.detail.message); // 输出:来自子组件的消息 无论子组件传递的是一个简单数据类型还是复杂数据类型 父组件接受event永远是一个对象
console.log(event.detail.value); // 输出:123
}
});
三、父组件主动调用子组件的方法
父组件可以通过 selectComponent 获取子组件实例,然后直接调用子组件的方法(也可以获取子组件属性)。
1.子组件定义方法
在子组件中定义一个方法供父组件调用:
// 子组件(child-component.js)
Component({
methods: {
sayHello() {
console.log('Hello from child component!');
}
}
});
2.父组件调用子组件方法
在父组件中使用 this.selectComponent 获取子组件实例,并调用其方法:
// 父组件(parent-component.js)
Page({
callChildMethod() {
const child = this.selectComponent('#myChild');
if (child) {
child.sayHello(); // 调用子组件的方法
}
}
});
注意:在父组件的 WXML 中为子组件设置唯一的 id
<!-- 父组件 -->
<child-component id="myChild"></child-component>
<button bindtap="callChildMethod">调用子组件方法</button>
四、使用全局状态管理(可选,一般用于存储和更新全局数据如用户手机号等)
如果父子组件之间层级较深,或者需要频繁通信,可以考虑使用全局状态管理工具(如 getApp() 或第三方库 mobx-miniprogram)来共享数据。
用 getApp() 共享全局数据
在 app.js 中定义全局数据:
// app.js
App({
globalData: {
sharedValue: '全局共享数据'
}
});
在父组件或子组件中访问全局数据:
const app = getApp();
console.log(app.globalData.sharedValue); // 输出:全局共享数据
修改全局数据
在任何组件都可以修改全局数据,每次访问全局数据最好都在onshow的时候获取,避免在当前页面修改了数据,返回上一页的时候使用的data里的全局数据还未同步:
const app = getApp();
app.globalData.sharedValue = '新的全局数据';