微信小程序理解进阶

1 data

data 是页面第一次渲染使用的初始数据。页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。

wxml里的代码:

<view>{% raw %}{{% endraw %}{text}}</view>
<view>{% raw %}{{% endraw %}{array[0].msg}}</view>

js里的data模型:

Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

2 生命周期函数

  • onLoad(Object query)
    页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。

  • onShow()
    页面显示/切入前台时触发。

  • onReady()
    页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。

  • onHide()
    页面隐藏/切入后台时触发。 如 navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。

  • onUnload()
    页面卸载时触发。如redirectTo或navigateBack到其他页面时。

需要注意的是:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady之后进行。

可以通过一个简单的例子来测试执行顺序:

Page({
  /**
   * 页面的初始数据
   */
  data: {
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log("页面加载时触发")
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    console.log("onReady:监听页面初次渲染完成");
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    console.log("onShow:页面显示时触发");
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
      console.log("页面隐藏时触发");
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
	 console.log("页面卸载时触发");
  }
})

3 模块化

官网地址:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/module.html

uitls文件用来存放一些js文件,这些js文件里包含了一些用在全局的js共用方法等,通常也被工具包,我们根据项目需要在里面添加工具类,将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。

举例说明:

  • 第一步:我们在uitls里自顶一个commen.js文件,并书写两个方法:

在这里插入图片描述

  • 第二步:在一个页面里来使用这两个方法,在使用这个模块方法之前,需要使用使用 require(path) 将公共代码引入,比如我们可以在pages/notice/notice.js 里Page({})里进行测试。
// pages/notice/notice.js
var commonjs=require("../../utils/common.js")

Page({
  /**
   * 页面的初始数据
   */
  data: {},
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    commonjs.fn1("hello!")
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    commonjs.fn2("bye!")
  }
})

页面的控制台里显示:

在这里插入图片描述

4 全局变量的使用

全局js配置文件,小程序加载时先运行这个文件,这里定义的变量为全局变量,可在页面内通过 getApp() 获取,现在通过一个例子来进行说明:

第一步:在app.js 里的globalData里定义一个空变量

在这里插入图片描述

第二步:在pages/notice/notice.js 里书写代码

// pages/notice/notice.js
var commonjs=require("../../utils/common.js")
var app=getApp();
Page({
  /**
   * 页面的初始数据
   */
  data: {},
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    commonjs.fn1("hello!");
    app.globalData.appName="完美校园";
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    commonjs.fn2("bye!");
    console.log(app.globalData.appName);
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {}
})

5. 数据绑定

数据绑定使用 Mustache 语法(双大括号)将变量包起来,用法和Vuejs非常相似:

5.1 内容

<view>{% raw %}{{% endraw %}{ message }}</view>
Page({
  data: {
    message: 'Hello world!'
  }
})

5.2 组件属性(需要在双引号之内)

<view id="item-{% raw %}{{% endraw %}{id}}"></view>
Page({
  data: {
    id: 0
  }
})

5.3 控制属性(需要在双引号之内)

<view wx:if="{% raw %}{{% endraw %}{condition}}"></view>
Page({
  data: {
    condition: true
  }
})

5.4 关键字(需要在双引号之内)

true:boolean 类型的 true,代表真值。

false: boolean 类型的 false,代表假值。

<checkbox checked="{% raw %}{{% endraw %}{false}}"></checkbox>

特别注意:不要直接写 checked=“false”,其计算结果是一个字符串,转成 boolean 类型后代表真值。

5.5 运算

可以在{ { } }内进行简单的运算,支持的有如下几种方式:

  • 三元运算
<view hidden="{% raw %}{{% endraw %}{flag ? true : false}}">Hidden</view>
  • 算术运算
<view>{% raw %}{{% endraw %}{a + b}} + {% raw %}{{% endraw %}{c}} + d</view>
Page({
  data: {
    a: 1,
    b: 2,
    c: 3
  }
})

view中的内容为 3 + 3 + d

  • 逻辑判断
<view wx:if="{% raw %}{{% endraw %}{length > 5}}"></view>
  • 字符串运算
<view>{% raw %}{{% endraw %}{"hello" + name}}</view>
Page({
  data: {
    name: 'MINA'
  }
})
  • 数据路径运算
<view>{% raw %}{{% endraw %}{object.key}} {% raw %}{{% endraw %}{array[0]}}</view>
Page({
  data: {
    object: {
      key: 'Hello '
    },
    array: ['MINA']
  }
})
  • 组合

也可以在 Mustache 内直接进行组合,构成新的对象或者数组。

  • 数组
<view wx:for="{% raw %}{{% endraw %}{[zero, 1, 2, 3, 4]}}">{% raw %}{{% endraw %}{item}}</view>
Page({
  data: {
    zero: 0
  }
})

最终组合成数组[0, 1, 2, 3, 4]

  • 对象
<template is="objectCombine" data="{% raw %}{{% endraw %}{for: a, bar: b}}"></template>
Page({
  data: {
    a: 1,
    b: 2
  }
})

最终组合成的对象是{for: 1, bar: 2}

也可以用扩展运算符 ... 来将一个对象展开

<template is="objectCombine" data="{% raw %}{{% endraw %}{...obj1, ...obj2, e: 5}}"></template>
Page({
  data: {
    obj1: {
      a: 1,
      b: 2
    },
    obj2: {
      c: 3,
      d: 4
    }
  }
})

最终组合成的对象是 {a: 1, b: 2, c: 3, d: 4, e: 5}。

如果对象的 key 和 value 相同,也可以间接地表达。

<template is="objectCombine" data="{% raw %}{{% endraw %}{foo, bar}}"></template>
Page({
  data: {
    foo: 'my-foo',
    bar: 'my-bar'
  }
})

最终组合成的对象是 {foo: ‘my-foo’, bar:‘my-bar’}。

注意:上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面,如:

<template is="objectCombine" data="{% raw %}{{% endraw %}{...obj1, ...obj2, a, c: 6}}"></template>
Page({
  data: {
    obj1: {
      a: 1,
      b: 2
    },
    obj2: {
      b: 3,
      c: 4
    },
    a: 5
  }
})

最终组合成的对象是 {a: 5, b: 3, c: 6}

注意: 花括号和引号之间如果有空格,将最终被解析成为字符串

<view wx:for="{% raw %}{{% endraw %}{[1,2,3]}} ">
  {% raw %}{{% endraw %}{item}}
</view>

等同于

<view wx:for="{% raw %}{{% endraw %}{[1,2,3] + ' '}}">
  {% raw %}{{% endraw %}{item}}
</view>

6. 条件渲染

  • wx:if
    在框架中,使用 wx:if="{% raw %}{{% endraw %}{condition}}" 来判断是否需要渲染该代码块:
<view wx:if="{% raw %}{{% endraw %}{condition}}">True</view>
  • 也可以用 wx:elif 和 wx:else 来添加一个 else 块:
<view wx:if="{% raw %}{{% endraw %}{length > 5}}">1</view>
<view wx:elif="{% raw %}{{% endraw %}{length > 2}}">2</view>
<view wx:else>3</view>
  • block wx:if
    因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{% raw %}{{% endraw %}{true}}">
  <view>view1</view>
  <view>view2</view>
</block>

注意: <block/>并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

7. 列表渲染

7.1 wx:for

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。

默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

<view wx:for="{% raw %}{{% endraw %}{array}}">
  {% raw %}{{% endraw %}{index}}: {% raw %}{{% endraw %}{item.message}}
</view>
Page({
  data: {
    array: [{
      message: 'foo',
    }, {
      message: 'bar'
    }]
  }
})

使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:

<view wx:for="{% raw %}{{% endraw %}{array}}" wx:for-index="idx" wx:for-item="itemName">
  {% raw %}{{% endraw %}{idx}}: {% raw %}{{% endraw %}{itemName.message}}
</view>

wx:for 也可以嵌套,下边是一个九九乘法表

<view wx:for="{% raw %}{{% endraw %}{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
  <view wx:for="{% raw %}{{% endraw %}{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
    <view wx:if="{% raw %}{{% endraw %}{i <= j}}">
      {% raw %}{{% endraw %}{i}} * {% raw %}{{% endraw %}{j}} = {% raw %}{{% endraw %}{i * j}}
    </view>
  </view>
</view>

7.2 block wx:for

类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:

<block wx:for="{% raw %}{{% endraw %}{[1, 2, 3]}}">
  <view>{% raw %}{{% endraw %}{index}}:</view>
  <view>{% raw %}{{% endraw %}{item}}</view>
</block>

7.3 wx:key

如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input>中的输入内容,<switch>的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。

wx:key 的值以两种形式提供

  1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  2. 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。

示例代码:

<switch wx:for="{% raw %}{{% endraw %}{objectArray}}" wx:key="unique" style="display: block;">
  {% raw %}{{% endraw %}{item.id}}
</switch>
<button bindtap="switch">Switch</button>
<button bindtap="addToFront">Add to the front</button>

<switch wx:for="{% raw %}{{% endraw %}{numberArray}}" wx:key="*this" style="display: block;">
  {% raw %}{{% endraw %}{item}}
</switch>
<button bindtap="addNumberToFront">Add to the front</button>
Page({
  data: {
    objectArray: [
      {id: 5, unique: 'unique_5'},
      {id: 4, unique: 'unique_4'},
      {id: 3, unique: 'unique_3'},
      {id: 2, unique: 'unique_2'},
      {id: 1, unique: 'unique_1'},
      {id: 0, unique: 'unique_0'},
    ],
    numberArray: [1, 2, 3, 4]
  },
  switch(e) {
    const length = this.data.objectArray.length
    for (let i = 0; i < length; ++i) {
      const x = Math.floor(Math.random() * length)
      const y = Math.floor(Math.random() * length)
      const temp = this.data.objectArray[x]
      this.data.objectArray[x] = this.data.objectArray[y]
      this.data.objectArray[y] = temp
    }
    this.setData({
      objectArray: this.data.objectArray
    })
  },
  addToFront(e) {
    const length = this.data.objectArray.length
    this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)
    this.setData({
      objectArray: this.data.objectArray
    })
  },
  addNumberToFront(e) {
    this.data.numberArray = [this.data.numberArray.length + 1].concat(this.data.numberArray)
    this.setData({
      numberArray: this.data.numberArray
    })
  }
})

注意:

wx:for 的值为字符串时,会将字符串解析成字符串数组

<view wx:for="array">
  {% raw %}{{% endraw %}{item}}
</view>

等同于

<view wx:for="{% raw %}{{% endraw %}{['a','r','r','a','y']}}">
  {% raw %}{{% endraw %}{item}}
</view>

注意: 花括号和引号之间如果有空格,将最终被解析成为字符串

<view wx:for="{% raw %}{{% endraw %}{[1,2,3]}} ">
  {% raw %}{{% endraw %}{item}}
</view>

等同于

<view wx:for="{% raw %}{{% endraw %}{[1,2,3] + ' '}}">
  {% raw %}{{% endraw %}{item}}
</view>

8. 事件

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如 id, dataset, touches。

在小程序中,用户使用的最多的操作几种事件分别是点击、拖动、双击、输入

【举例说明】:

  • 在组件中绑定一个事件处理函数。

bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

<view id="tapTest" data-hi="微信" bindtap="tapName">点我</view>
  • 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({
  tapName(event) {
    console.log(event)
  }
})
  • 可以看到log出来的信息大致如下:
{
  "type": "tap",
  "timeStamp": 895,
  "target": {
    "id": "tapTest",
    "dataset": {
      "hi": "WeChat"
    }
  },
  "currentTarget": {
    "id": "tapTest",
    "dataset": {
      "hi": "微信"
    }
  },
  "detail": {
    "x": 53,
    "y": 14
  },
  "touches": [
    {
      "identifier": 0,
      "pageX": 53,
      "pageY": 14,
      "clientX": 53,
      "clientY": 14
    }
  ],
  "changedTouches": [
    {
      "identifier": 0,
      "pageX": 53,
      "pageY": 14,
      "clientX": 53,
      "clientY": 14
    }
  ]
}

9. 和后台数据进行交互

官网地址:https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html

在index.wxml 文件中添加两个组件

<view>{% raw %}{{% endraw %}{ msg }}</view>
<button bindtap="bindViewTap">点击我</button>

在js文件里书写bindViewTap方法

Page({
  data: {},
  //事件处理函数
   bindViewTap1: function () {
    var _this = this;
    var msgFromBack = "";
      wx.request({
        url: 'http://localhost:3004/index', // 仅为示例,并非真实的接口地址
        data: {},
        header: {
          'content-type': 'application/json' // 默认值
        },
        success(res) {
          console.log(res.data);
          //查看官方api方法
          msgFromBack = res.data.comments;
          _this.setData(res.data);//统一赋值
          _this.setData({
            msg: msgFromBack
        });//单属性赋值
      }
    })
  }
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JTZ001

你的鼓励是我创作的最大动力?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值