微信小程序入门学习教程,从入门到精通,微信小程序页面交互 —— 知识点详解与案例实现(3)

微信小程序页面交互 ------ 知识点详解与案例实现


一、Page() 函数

1.1 语法说明

Page() 是微信小程序用于注册页面的函数,接收一个对象作为参数,该对象包含页面的初始数据、生命周期函数、事件处理函数等。

javascript 复制代码
Page({
  data: { /* 页面初始数据 */ },
  onLoad() { /* 页面加载时执行 */ },
  onShow() { /* 页面显示时执行 */ },
  // 自定义方法
  handleClick() { }
})

1.2 案例:页面初始化数据

javascript 复制代码
// pages/index/index.js
Page({
  data: {
    title: '欢迎使用小程序',
    count: 0
  },
  onLoad() {
    console.log('页面加载完成');
  }
})
xml 复制代码
<!-- pages/index/index.wxml -->
<view>{{title}}</view>
<view>计数:{{count}}</view>

二、数据绑定

2.1 语法说明

使用双大括号 {``{}} 在 WXML 中绑定 JS 中 data 的数据。

2.2 案例:动态显示用户名

javascript 复制代码
Page({
  data: {
    userName: '张三'
  }
})
xml 复制代码
<view>你好,{{userName}}!</view>

三、事件绑定

3.1 语法说明

在 WXML 中使用 bindcatch 绑定事件,如 bindtap 表示点击事件。

3.2 案例:点击按钮增加计数

javascript 复制代码
Page({
  data: {
    count: 0
  },
  increment() {
    this.setData({
      count: this.data.count + 1
    });
  }
})
xml 复制代码
<view>当前计数:{{count}}</view>
<button bindtap="increment">+1</button>

四、事件对象

4.1 语法说明

事件处理函数会自动接收一个 event 对象,包含事件信息,如 target.dataset

4.2 案例:获取按钮自定义数据

javascript 复制代码
Page({
  handleClick(e) {
    console.log('按钮ID:', e.currentTarget.dataset.id);
  }
})
xml 复制代码
<button data-id="btn1" bindtap="handleClick">按钮1</button>

五、this 关键字

5.1 说明

在 Page 对象的方法中,this 指向当前页面实例,可用于访问 data 或调用 setData()

注意:在回调函数中(如 setTimeout),this 可能丢失,需用箭头函数或缓存 this

5.2 案例:正确使用 this

javascript 复制代码
Page({
  data: { msg: 'Hello' },
  showMsg() {
    console.log(this.data.msg); // 正确
  },
  delayedMsg() {
    const that = this; // 缓存 this
    setTimeout(function() {
      that.setData({ msg: 'Delayed Hello' });
    }, 1000);
  }
})

六、setData() 方法

6.1 语法说明

用于修改 data 中的数据并触发页面重新渲染。不能直接修改 this.data

javascript 复制代码
this.setData({
  key: newValue
})

6.2 案例:更新用户输入

javascript 复制代码
Page({
  data: {
    inputVal: ''
  },
  onInput(e) {
    this.setData({
      inputVal: e.detail.value
    });
  }
})
xml 复制代码
<input bindinput="onInput" value="{{inputVal}}" />
<view>你输入了:{{inputVal}}</view>

七、条件渲染(wx:if / wx:elif / wx:else)

7.1 语法说明

根据条件决定是否渲染某块内容。

7.2 案例:根据分数显示等级

javascript 复制代码
Page({
  data: {
    score: 85
  }
})
xml 复制代码
<view wx:if="{{score >= 90}}">优秀</view>
<view wx:elif="{{score >= 70}}">良好</view>
<view wx:else>需努力</view>

八、<block> 标签

8.1 说明

<block> 是一个逻辑容器,不会被渲染为真实节点,常用于包裹多个元素进行条件或列表渲染。

8.2 案例:条件渲染多个元素

xml 复制代码
<block wx:if="{{showDetails}}">
  <view>姓名:张三</view>
  <view>年龄:25</view>
</block>

九、hidden 属性

9.1 说明

hidden="{``{true}}" 会隐藏元素,但元素仍存在于 DOM 中 (与 wx:if 不同)。

9.2 案例:切换显示/隐藏

javascript 复制代码
Page({
  data: {
    isHidden: false
  },
  toggle() {
    this.setData({
      isHidden: !this.data.isHidden
    });
  }
})
xml 复制代码
<view hidden="{{isHidden}}">这段文字可被隐藏</view>
<button bindtap="toggle">切换显示</button>

十、data-* 自定义属性

10.1 说明

在元素上定义 data-xxx 属性,可在事件对象中通过 e.currentTarget.dataset.xxx 获取。

10.2 案例:计算器按钮传递操作符

xml 复制代码
<button data-op="+" bindtap="handleOp">+</button>
<button data-op="-" bindtap="handleOp">-</button>
javascript 复制代码
Page({
  handleOp(e) {
    const op = e.currentTarget.dataset.op;
    console.log('操作符:', op);
  }
})

十一、模块(module.exports / require)

11.1 说明

小程序支持 CommonJS 模块系统,可将工具函数封装为模块。

11.2 案例:数学工具模块

javascript 复制代码
// utils/math.js
function add(a, b) {
  return a + b;
}
module.exports = { add };
javascript 复制代码
// pages/index/index.js
const math = require('../../utils/math.js');
Page({
  onLoad() {
    console.log(math.add(2, 3)); // 5
  }
})

十二、列表渲染(wx:for)

12.1 语法说明

使用 wx:for 遍历数组或对象,wx:key 用于提升性能。

12.2 案例:美食列表

javascript 复制代码
Page({
  data: {
    foods: [
      { id: 1, name: '红烧肉', price: 38 },
      { id: 2, name: '宫保鸡丁', price: 28 }
    ]
  }
})
xml 复制代码
<view wx:for="{{foods}}" wx:key="id">
  {{index + 1}}. {{item.name}} - ¥{{item.price}}
</view>

十三、网络请求(wx.request)

13.1 案例:获取远程美食数据

javascript 复制代码
Page({
  onLoad() {
    wx.request({
      url: 'https://api.example.com/foods',
      success: (res) => {
        this.setData({ foods: res.data });
      },
      fail: () => {
        wx.showToast({ title: '加载失败', icon: 'none' });
      }
    });
  }
})

十四、提示框(wx.showToast / wx.showModal)

14.1 案例:提交问卷后提示

javascript 复制代码
wx.showToast({
  title: '提交成功',
  icon: 'success',
  duration: 1500
});

十五、WXS(WeiXin Script)

15.1 说明

WXS 是小程序的脚本语言,用于在 WXML 中处理逻辑(类似过滤器)。

15.2 案例:格式化价格

javascript 复制代码
// utils/format.wxs
var formatPrice = function(price) {
  return '¥' + price.toFixed(2);
}
module.exports = { formatPrice };
xml 复制代码
<wxs src="./utils/format.wxs" module="fmt" />
<view wx:for="{{foods}}" wx:key="id">
  {{item.name}} - {{fmt.formatPrice(item.price)}}
</view>

十六、上拉触底(onReachBottom)

16.1 案例:加载更多美食

javascript 复制代码
Page({
  data: {
    page: 1,
    foods: []
  },
  onLoad() {
    this.loadFoods();
  },
  onReachBottom() {
    this.setData({ page: this.data.page + 1 });
    this.loadFoods();
  },
  loadFoods() {
    // 模拟请求
    const newFoods = [...Array(5)].map((_, i) => ({
      id: this.data.page * 5 + i,
      name: `美食${this.data.page * 5 + i}`,
      price: 20 + i
    }));
    this.setData({ foods: [...this.data.foods, ...newFoods] });
  }
})

十七、下拉刷新(onPullDownRefresh)

17.1 配置与使用

json 复制代码
// pages/food/food.json
{
  "enablePullDownRefresh": true
}
javascript 复制代码
Page({
  onPullDownRefresh() {
    this.setData({ foods: [], page: 1 });
    this.loadFoods();
    wx.stopPullDownRefresh(); // 停止刷新动画
  }
})

十八、双向数据绑定(model:)

18.1 说明

小程序支持 model:value 实现类似 Vue 的双向绑定(需基础库 2.9.3+)。

18.2 案例:调查问卷输入

javascript 复制代码
Page({
  data: {
    answer: ''
  }
})
xml 复制代码
<input model:value="{{answer}}" placeholder="请输入答案" />
<view>你输入的是:{{answer}}</view>

注意:传统方式仍需 bindinput + setDatamodel:value 是语法糖。


综合性案例

案例1:【比较数字大小】完整实现

javascript 复制代码
// pages/compare/compare.js
Page({
  data: {
    num1: '',
    num2: '',
    result: ''
  },
  onInput1(e) {
    this.setData({ num1: e.detail.value });
  },
  onInput2(e) {
    this.setData({ num2: e.detail.value });
  },
  compare() {
    const n1 = parseFloat(this.data.num1);
    const n2 = parseFloat(this.data.num2);
    if (isNaN(n1) || isNaN(n2)) {
      wx.showToast({ title: '请输入有效数字', icon: 'none' });
      return;
    }
    let res = '';
    if (n1 > n2) res = '第一个数大';
    else if (n1 < n2) res = '第二个数大';
    else res = '两数相等';
    this.setData({ result: res });
  }
})
xml 复制代码
<!-- compare.wxml -->
<input placeholder="输入第一个数字" bindinput="onInput1" value="{{num1}}" />
<input placeholder="输入第二个数字" bindinput="onInput2" value="{{num2}}" />
<button bindtap="compare">比较</button>
<view wx:if="{{result}}">结果:{{result}}</view>

案例2:【简易计算器】

javascript 复制代码
Page({
  data: {
    display: '0',
    firstNum: null,
    operator: null,
    waitingForOperand: false
  },
  inputDigit(e) {
    const digit = e.currentTarget.dataset.digit;
    if (this.data.waitingForOperand) {
      this.setData({ display: digit, waitingForOperand: false });
    } else {
      this.setData({ display: this.data.display === '0' ? digit : this.data.display + digit });
    }
  },
  inputOperator(e) {
    const nextOperator = e.currentTarget.dataset.op;
    const inputValue = parseFloat(this.data.display);
    if (this.data.firstNum === null) {
      this.setData({ firstNum: inputValue });
    } else if (this.data.operator) {
      const result = this.calculate(this.data.firstNum, inputValue, this.data.operator);
      this.setData({ display: String(result), firstNum: result });
    }
    this.setData({ waitingForOperand: true, operator: nextOperator });
  },
  calculate(first, second, op) {
    switch (op) {
      case '+': return first + second;
      case '-': return first - second;
      case '*': return first * second;
      case '/': return first / second;
      default: return second;
    }
  },
  clear() {
    this.setData({ display: '0', firstNum: null, operator: null, waitingForOperand: false });
  },
  equals() {
    const inputValue = parseFloat(this.data.display);
    if (this.data.firstNum !== null && this.data.operator) {
      const result = this.calculate(this.data.firstNum, inputValue, this.data.operator);
      this.setData({ display: String(result), firstNum: null, operator: null, waitingForOperand: true });
    }
  }
})
xml 复制代码
<view class="display">{{display}}</view>
<view class="row">
  <button bindtap="clear">C</button>
  <button data-op="*" bindtap="inputOperator">×</button>
  <button data-op="/" bindtap="inputOperator">÷</button>
</view>
<view class="row">
  <button data-digit="7" bindtap="inputDigit">7</button>
  <button data-digit="8" bindtap="inputDigit">8</button>
  <button data-digit="9" bindtap="inputDigit">9</button>
  <button data-op="-" bindtap="inputOperator">−</button>
</view>
<view class="row">
  <button data-digit="4" bindtap="inputDigit">4</button>
  <button data-digit="5" bindtap="inputDigit">5</button>
  <button data-digit="6" bindtap="inputDigit">6</button>
  <button data-op="+" bindtap="inputOperator">+</button>
</view>
<view class="row">
  <button data-digit="1" bindtap="inputDigit">1</button>
  <button data-digit="2" bindtap="inputDigit">2</button>
  <button data-digit="3" bindtap="inputDigit">3</button>
  <button bindtap="equals">=</button>
</view>

案例3:【美食列表 + 下拉刷新 + 上拉加载】

(结合前面"列表渲染"、"网络请求"、"上拉触底"、"下拉刷新"知识点)

可参考第十二至十六节代码组合实现。


案例4:【调查问卷 + 双向绑定】

javascript 复制代码
Page({
  data: {
    questions: [
      { id: 1, text: '你喜欢吃辣吗?', answer: '' },
      { id: 2, text: '你最喜欢的菜系?', answer: '' }
    ]
  },
  submit() {
    const unanswered = this.data.questions.some(q => !q.answer.trim());
    if (unanswered) {
      wx.showToast({ title: '请填写所有问题', icon: 'none' });
      return;
    }
    wx.showToast({ title: '提交成功!', icon: 'success' });
    console.log('问卷结果:', this.data.questions);
  },
  onAnswer(e) {
    const index = e.currentTarget.dataset.index;
    const value = e.detail.value;
    const questions = this.data.questions;
    questions[index].answer = value;
    this.setData({ questions });
  }
})
xml 复制代码
<view wx:for="{{questions}}" wx:key="id" class="question">
  <text>{{item.text}}</text>
  <input model:value="{{item.answer}}" bindinput="onAnswer" data-index="{{index}}" />
</view>
<button bindtap="submit">提交问卷</button>

本章小结

本章围绕页面交互展开,涵盖:

  • 页面注册(Page)
  • 数据驱动(data + setData)
  • 用户交互(事件绑定、事件对象)
  • 动态渲染(条件、列表、block、hidden)
  • 实用功能(网络请求、提示框、上拉/下拉)
  • 高级特性(WXS、双向绑定、模块化)

掌握这些知识点,可构建功能完整、交互流畅的小程序页面。

相关推荐
charlie1145141912 小时前
精读C++20设计模式——结构型设计模式:代理模式
c++·学习·设计模式·代理模式·c++20·概论
石小石Orz2 小时前
思考许久,我还是提交了离职申请
前端
m0_616188492 小时前
CSS中的伪类和伪元素
前端·javascript·css
一个小潘桃鸭2 小时前
组件抽离:el-upload支持图片粘贴上传并添加预览
前端
武昌库里写JAVA2 小时前
Java 设计模式在 Spring 框架中的实践:工厂模式与单例模式
java·vue.js·spring boot·sql·学习
快乐就好ya2 小时前
React基础到进阶
前端·javascript·react.js
峥嵘life2 小时前
Android16 adb投屏工具Scrcpy介绍
android·开发语言·python·学习·web安全·adb
tiankongdeyige2 小时前
Unity学习之垃圾回收GC
学习
家里有只小肥猫3 小时前
react 初体验
react.js