当前位置: 首页 > news >正文

动态的魔法:列表与条件渲染

动态的魔法:列表与条件渲染

所属专栏:《微信小程序-实战笔记30讲》
作者:码力无边

前言

到目前为止,我们构建的页面大多是“写死的”。一个按钮,一段文字,一张图片,它们都在WXML代码中清晰可见。但真实的应用世界远非如此。新闻列表的文章数量是不固定的,商品列表的商品种类是动态变化的,用户的个人中心会根据是否登录显示不同的内容。

如何让我们的页面根据数据的变化,动态地“生长”出不同的结构?

今天,我们将学习小程序中实现这一目标的两大“魔法”:

  1. wx:for 列表渲染:像施展“分身术”一样,根据一个数组,批量生成重复的页面结构。
  2. wx:if / wx:else 条件渲染:如同拥有“变身”能力,根据一个条件,决定某块内容是否应该出现在页面上。

掌握了这两个指令,你的WXML将不再是僵硬的模板,而是能够响应数据、富有生命力的动态画布。

一、wx:for:列表渲染的“分身术”

wx:for是小程序中用于循环渲染一个组件的指令。它能接收一个数组,并对数组中的每个成员,都渲染一次该组件。

1. 基础用法

wx:for的基本语法非常直观:

<view wx:for="{{array}}">第 {{index}} 个元素:{{item}}
</view>
  • wx:for="{{array}}"array是你在页面.js文件的data中定义的一个数组。
  • item:在循环过程中,item当前数组元素的值的默认变量名。
  • index:在循环过程中,index当前数组元素的下标的默认变量名。

动手实践 - 渲染一个简单的水果列表:
JS (准备数据):

// pages/list/list.js
Page({data: {fruits: ['苹果', '香蕉', '橙子', '葡萄']}
})

WXML (循环渲染):

<!-- pages/list/list.wxml -->
<view class="title">我喜欢的水果:</view>
<view wx:for="{{fruits}}" class="fruit-item">{{index + 1}}. {{item}}
</view>

保存后,模拟器上会清晰地渲染出四行水果名称。如果你去修改.jsfruits数组的内容(增加或删除),页面也会自动更新,这就是数据驱动的魅力。

2. 自定义变量名

如果你觉得itemindex这两个名字不够清晰,或者在嵌套循环中容易混淆,可以使用wx:for-itemwx:for-index来指定新的变量名。

<view wx:for="{{fruits}}" wx:for-item="fruit" wx:for-index="idx">{{idx + 1}}. {{fruit}}
</view>
3. wx:key:为循环项指定唯一的“身份证”

在进行列表渲染时,小程序框架需要一种方式来识别每个循环项,以便在数据变化时,能高效地更新DOM(只更新变化的部分,而不是重新渲染整个列表)。这个识别的凭证就是wx:key

wx:key的重要性:

  • 提升性能:有了key,小程序可以精确地知道哪个项是新增的、哪个是删除的、哪个只是移动了位置,从而进行最小化的渲染操作。
  • 维持状态:如果你的循环项中包含<input><switch>等有自身状态的组件,正确使用key可以确保在列表更新后,这些组件的状态(如输入的内容)不会错乱。

如何设置wx:key
key的值必须是列表中唯一的字符串或数字。通常有两种方式:

  1. 使用 *this: 如果你的数组是一个简单的字符串或数字数组(成员本身就是唯一的),你可以用 wx:key="*this"

    <view wx:for="{{['a', 'b', 'c']}}" wx:key="*this">{{item}}</view>
    
  2. 使用对象中的唯一属性: 如果你的数组是对象数组,强烈推荐使用对象中具有唯一性的属性(如id)作为key

    JS (准备数据):

    Page({data: {users: [{ id: 1001, name: 'Alice' },{ id: 1002, name: 'Bob' },{ id: 1003, name: 'Charlie' }]}
    })
    

    WXML (使用id作为key):

    <view wx:for="{{users}}" wx:key="id">ID: {{item.id}}, 姓名: {{item.name}}
    </view>
    

最佳实践:始终为你的wx:for循环提供一个明确且唯一的wx:key。如果你不提供,开发者工具会给出一个警告。

二、wx:if vs hidden:条件渲染的抉择

条件渲染允许我们根据条件来决定是否渲染某段WXML代码。小程序提供了两种方式来实现:wx:ifhidden

1. wx:if:真正的“条件编译”

wx:if, wx:elif, wx:else 构成了一套完整的条件判断逻辑,类似于JavaScript中的if...else if...else

  • wx:if="{{condition}}":当conditiontrue时,渲染该组件。
  • wx:elif="{{condition2}}":当前一个wx:iffalse时,判断condition2
  • wx:else:当所有前面的wx:ifwx:elif都为false时,渲染该组件。

工作原理
wx:if惰性的。如果条件为false,小程序框架根本不会创建这块WXML对应的DOM节点。当条件由false变为true时,才会动态地创建并插入DOM。

动手实践 - 根据用户登录状态显示不同内容:
JS:

Page({data: {isLoggedIn: false},toggleLogin: function() {this.setData({ isLoggedIn: !this.data.isLoggedIn });}
})

WXML:

<button bindtap="toggleLogin">切换登录状态</button><view wx:if="{{isLoggedIn}}"><image src="/path/to/avatar.png"/><text>欢迎回来,尊贵的用户!</text>
</view>
<view wx:else><text>您当前未登录,请先登录。</text>
</view>
2. hidden:简单的显示/隐藏切换

hidden="{{condition}}"也用于控制组件的显隐。

  • conditiontrue时,组件被隐藏
  • conditionfalse时,组件被显示

工作原理
wx:if不同,带有hidden属性的组件始终会被渲染到页面中。hidden只是简单地通过类似display: none;的CSS样式来控制它的显示和隐藏。

3. wx:if vs hidden:我该用哪个?

这是一个非常经典的面试题,也是开发中需要权衡的选择。

特性wx:ifhidden
初始渲染如果条件为false,不渲染,初始开销小始终渲染,初始开销大
切换开销切换时涉及DOM的创建和销毁,切换开销大切换时只改变CSS属性,切换开销小
适用场景运行时条件不常改变的场景需要频繁切换显示/隐藏的场景

总结一下

  • 如果一个组件在应用的生命周期中,可能永远不会被显示(比如管理员才有的按钮),或者切换频率非常低(比如登录/未登录状态的切换),用wx:if更合适,因为它可以节省初始的渲染开销。
  • 如果一个组件需要频繁地在显示和隐藏之间切换(比如一个加载中的提示、一个可折叠的面板),用hidden性能会更好,因为它避免了反复创建和销毁组件的开销。

三、<block>:逻辑的“隐形”容器

有时候,你需要使用wx:for循环渲染多个平级的标签,或者使用wx:if控制多个标签的显隐。这时,如果你用一个<view>来包裹它们,会多出一个不必要的DOM节点,可能会影响样式。

<block>标签就是为了解决这个问题而生的。它是一个逻辑包裹容器,可以承载wx:forwx:if等属性,但它本身不会被渲染成任何实际的UI元素

示例:

<block wx:for="{{products}}" wx:key="id"><view class="product-title">{{item.name}}</view><view class="product-price">¥{{item.price}}</view>
</block>

上面的代码会渲染出一系列的<view>对,但不会有一个额外的<block>标签包裹它们。

结语

今天,我们掌握了小程序页面动态化的两大核心魔法:列表渲染和条件渲染。我们知道了:

  • 使用wx:forwx:key来高效地渲染列表数据。
  • 根据场景,在wx:if(控制渲染)和hidden(控制显隐)之间做出明智的选择。
  • 利用<block>标签来组织复杂的渲染逻辑,而不引入多余的UI结构。

现在,你的小程序已经具备了根据数据动态构建界面的能力,这是从简单页面走向复杂应用的一大步。

我们的应用已经能在一个页面内玩出很多花样了,但一个完整的应用绝不可能只有一个页面。那么,如何在多个页面之间跳转?如何传递参数?下一讲,我们将学习页面路由与导航,打通小程序内部的“任督二脉”。

我们下篇见!

http://www.dtcms.com/a/405949.html

相关文章:

  • 乐清联科网站建设wordpress divi 数据
  • ARM单片机中断及中断优先级管理详解
  • python软件操作
  • c++_day2
  • 数据通信与计算机网络-交换
  • 2026考研时间,定了
  • 转:Ubuntu20.04安装NVIDIA驱动+CUDA超详细安装指南
  • 软件系统设计课程-Day1-从用户投诉到系统需求
  • 飞浪网站建设网站开发毕业设计任务书
  • JavaScript学习笔记(十二):call、apply和bind使用指南
  • Java外功基础(1)——Spring Web MVC
  • 【双机位A卷】华为OD笔试之【DP】双机位A-构建数列【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
  • 基于PyTorch深度学习无人机遥感影像目标检测、地物分类及语义分割实践技术应用
  • 基于PyTorch深度学习遥感影像地物分类与目标检测、分割及遥感影像问题深度学习优化实践技术应用
  • Kafka如何保证消息可靠性
  • 前端面经-高级开发(华为od)
  • 网站建设与 维护实训报告范文wordpress 上传网站吗
  • 基于深度学习神经网络协同过滤模型(NCF)的视频推荐系统
  • 网站建立时间软件开发5个过程
  • 【微实验】激光测径系列(六)MATLAB 实现 CCD 图像像素与实际距离标定
  • 设计模式之代理模式-骆驼与巴巴羊的故事
  • Linux安全机制--系统层安全机制
  • 大模型之bert变种
  • 华为HCIE认证-“天花板”级考试的难度解析
  • 【网络协议】数字签名与证书
  • LinkedList模拟实现
  • 如何自己做淘宝网站网页设计策划
  • 神奇的位运算——力扣136.只出现一次的数字
  • 【征文计划】深度剖析 Rokid SLAM 算法:从传感器融合到空间重建的完整技术链路
  • Pygame中实现图像旋转效果-高级2-2