微信小程序入门(一)

公众号

  • 订阅号
  • 服务号(可以进行支付,订阅号类似报纸,不能支付)
  • 小程序 一种新的开放能力,类似于手机APP的使用体验
  • 企业微信(企业的专业办公管理工具,用于企业员工内部通讯,打卡,审批等)

app:基于手机操作系统提供的API进行开发

小程序:基于微信提供的API进行开发

组件

是视图层的基本组成单元,自带一些功能与微信风格一致的样式

一个组件通常包括 开始标签 和结束标签,属性 用来修饰这个组件内容在两个额标签之内

小程序中 所有的组件名称和属性名称都是小写

最后再进行设置于小程序的基本信息(项目发布阶段再写)

下载开发者文档

app.js全局入口文件

app.json // 第一个就是小程序默认运行的页面(一打开就显示的页面)

可以直接在app.json文件中直接写一个陌路和页面,项目目录就会自动的创建一个目录和4个小程序文件

“pages/user/user”

{
  "pages": [
    "pages/home/home",
    "pages/index/index",
    "pages/logs/logs",
    "pages/user/user"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  }
}

小程序的结构与配置

  • <text>  组件在一行进行显示
    长按选中 selectable
    space属性   设置每一个空格的宽度
    
  • ensp 渲染为英文字符的一个空格
  • emsp 渲染为一个汉字字符的一个空格
  • nbsp 渲染当前文字大小的一个空格

view组件就相当于div,用来进行布局(块级,没有margin和padding)

button按钮(看官网提供的文档)

  • size:按钮的大小(默认情况下按钮是独占一行的,如果设置了size="mini"两个按钮就会在一行显示)
    • size=“mini”
  • type:按钮的样式类型(设置按钮的背景颜色)
    • type=“primary” 颜色是绿色
    • type=“warn” 红色的一个按钮
  • plain按钮是否镂空,背景色透明(默认false)
    • <button size="mini" type="warn" plain>按钮4</button>  
      
    • 按钮边框为空色,里面没有被红色填充
  • disabled:是否禁用(默认false)不可以点击
  • loading:按钮名称前是否带loading图标(默认false)

input输入框

  • 默认是没有任何边框
  • value=“文本框的初始值”
  • type 文本框的类型 默认是text类型
    • text
    • number
    • idcard
    • digit 带小数点的输入框
  • password 是否是密码类型
  • placehoder 输入框为空时的占位符
  • disabled
  • maxlength

image图片(不是img标签!!)

  • src:支持本地和网络上的图片
  • mode:指定图片的裁剪,缩放的模式

注意:image组件默认宽度是300px,高度是225px.即使没有给指定src属性还是会有一个宽高

小程序中的样式

wxss

WXSS(WeiXin Style Sheets)是一套样式语言,用来决定 WXML 的组件应该怎么显示;

WXSS 具有 CSS 大部分特性;

WXSS 对 CSS 进行了扩充以及修改,以适应微信小程序的开发;

与 CSS 相比,WXSS 扩展的特性有:

  • 尺寸单位
  • 样式导入

wxss目前支持的选择器

  • 标签选择器
  • id选择器
  • class选择器
  • 伪类选择器
  • data-*属性选择器(微信小程序中通过属性选择器给组件加样式不会成功!因为在微信小程序中所有的自定义属性必须以data-开头)
    • <view data-color="pink">12312312313</view>
      
      /* 自定义属性,属性选择器  */
      [data-color='pink']{
        background-color: lightblue;
      }
      
  • :nth-of-type() 等常用的 css3 选择器
  • etc…

rpx尺寸单位(类似之前的rem)

rpx(responsive pixel): 是微信小程序独有的、解决屏幕自适应的尺寸单位。

  • 可以根据屏幕宽度进行自适应。不论大小屏幕,规定屏幕宽为750rpx。
  • 通过rpx设置元素和字体的大小,小程序在不同尺寸的屏幕上,可以实现自动适配。

rpx与px之间的换算

以 iPhone6 为例,iPhone6 的屏幕宽度为375px,共有750个物理像素,(把iPhone5上分为750份,750rpx)则750rpx = 375px
= 750物理像素,1rpx = 0.5px = 1物理像素。

在iPhone6上,如果要绘制宽100px,高20px的盒子,换算成rpx单位,宽高分别为 200rpx 和 40rpx。

rpx 和 iPhone6 设计稿的关系

官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准。如果要根据iPhone6的设计稿,绘制小程序页面,可以直接把单位从
px 替换为 rpx 。例如,假设iPhone6设计稿上,要绘制一个宽高为 200px 的盒子,换算为 rpx 为 200rpx。(设计师给的是2倍图,显示到真实手机页面是1倍,然后如果使用rpx作为像素单位,又需要再乘以2)

使用rpx单位可以适配,随着屏幕的大小进行变换(类似rem)

.vv1{
  width: 375rpx;
  height: 375rpx;
  background-color: red;
}

@import 样式导入(一个css文件中导入另外一个样式文件)

  • 语法格式为:@import “wxss样式表的相对路径”;(注意最后的分号一定不能省略)

全局样式与局部样式

  • 全局样式 定义在 app.wxss 中的样式为全局样式,作用于每一个页面。(注意是不需要导入到每个页面的!!!)
  • 局部样式
    • 在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
      注意:当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式效果!

app.json配置文件的作用

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,它决定了页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。

在app.json配置文件中,最主要的配置节点是:

  • pages 数组:配置小程序的页面路径
  • window 对象:用于设置小程序的状态栏、导航条、标题、窗口背景色
  • tabBar 对象:配置小程序的tab栏效果

pages – 配置小程序的页面路径

  • pages 用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径+文件名 信息。
  • 文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json、 .js、 .wxml 和 .wxss 四个文件进行处理。
  • 不需要写文件后缀名

自动创建新页面

  • 打开 app.json ->pages 数组节点 -> 新增页面路径并保存 -> 自动创建路径对应的页面(按钮ctrl+S自动生成4个文件)

设置默认首页

  • 打开 app.json -> pages 数组节点
  • 按需调整数组中路径的顺序,即可修改默认首页
  • 注意:
    ①数组的第一项代表小程序的初始页面(首页)。
    ②小程序中新增/减少页面,都需要对 pages 数组进行修改。(左侧目录树中有几个page页面,就需要在json文件中进行配置)

window节点常用的配置项(小程序的窗口组成部分)

  • navagationBarBackgroundColor 设置颜色时候,不要使用单词,而是要设置十六进制数(只接受十六进制的颜色)
  • navigationBarTextStyle:只接受 black或者 white
  • 全局开启下拉刷新功能
    • 设置步骤:app.json ->window -> 把 enablePullDownRefresh的值设置为 true(注意true外面不要包裹冒号"true" 而是直接写 true就可以)
    •  `"window": {
            "backgroundTextStyle": "light",
            "navigationBarBackgroundColor": "#2b4b6b",
            "navigationBarTitleText": "我的小程序",
            "navigationBarTextStyle": "white",
            "enablePullDownRefresh":true
          }
      
  • 设置下拉刷新窗口的背景色(默认是白色的)
  • backgroundColor(注意要指定十六进制的颜色值)
  • 设置下拉loading的样式
    • backgroundTextStyle:dark(就是下拉刷新显示的三个小圆点的颜色和样式)显示为灰色
    • 这个属性只有两个值(light/dark)
  • 设置上拉触底的距离
    • 概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为;
    • 设置步骤: app.json -> window -> 为 onReachBottomDistance 设置新的数值
    • 注意:默认距离为50px,如果没有特殊需求,建议使用默认值即可;(只要页面距离当前页面的底部不足50像素就会触发上拉触底,上拉加载下一页的数据)一般就使用默认的50px就可以
    • 注意他的值是一个数值,不要带字符串,也不要带像素的单位

tabBar - 配置Tab栏

  • tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换;
    小程序中通常将其分为底部tabBar和顶部tabBar。
  • 注意:tabBar中,只能配置最少2个、最多5个tab页签,当渲染顶部tabBar的时候,不显示icon,只显示文本

backgroundColor:导航条背景色

selectedIconPath:选中时的图片路径

borderStyle:tabBar上边框的颜色

iconPath:未选中时的图片路径

selectedColor:tab 上的文字选中时的颜色

color:tab 上的文字默认(未选中)颜色

  • 在app.json文件和window配置选项平级的位置设置 tabBar

  • tabBar节点中list的配置项(必填项)

案例
tabBar图标切换

  • 把资料中提供的小图标拷贝到项目指定目录中
  • ①在小程序根目录中,新建 assets -> images 目录;
    ②把资料中提供的6个小图标,拷贝到新建的 images 目录中;
    ③将需要用到的小图标分为3组,每组两个,其中图片名称中包含 -active 的是选中之后的图标,不包含 -active 的是默认图标
    配置tabBar选项
    ①打开app.json配置文件,和pages、window平级,新增tabBar节点;
    ②tabBar节点中,新增list数组,这个数组中存放的,是每个tab页的配置对象;
    ③在list数组中,新增每一个tab页的配置对象。对象中包含的属性与作用如下:
    • pagePath 指定当前tab对应的页面路径【必填】

    • text 指定当前tab上按钮的文字【必填】

    • iconPath 指定当前tab未选中时候的图片路径【可选】

    • selectedIconPath 指定当前tab被选中后高亮的图片路径【可选】
      使用页面配置文件page.json(例如我只想要消息页面的顶部颜色变红色。就需要对页面文件进行配置。打开消息文件)
      页面级别和全局级别配置的关系
      小程序中,app.json 中的 window节点,可以全局配置小程序中每个页面的窗口表现;
      如果某些小程序页面,想要拥有特殊的窗口表现,此时,“页面级别的.json配置文件”就可以实现这种需求;
      总结:页面级别配置优先于全局配置生效。
      小程序中的生命周期(时间段)

    • 应用生命周期:特指小程序从启动 -> 运行 -> 销毁的过程;

    • 页面生命周期:特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程;
      其中,页面的生命周期范围较小,应用程序的生命周期范围较大
      生命周期函数:(时间点)
      是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行;
      生命周期函数的作用:允许程序员在特定的生命周期时间点上,执行某些特定的操作。例如,页面刚加载的时候,在生命周期函数中自动发起数据请求,获取当前页面的数据;
      注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
      生命周期函数的分类

    • 应用生命周期函数
      app.js 是小程序执行的入口文件,在 app.js 中必须调用 App() 函数,且只能调用一次。其中,App() 函数是用来注册并执行小程序的。
      App(Object) 函数接收一个Object参数,可以通过这个Object参数,指定小程序的生命周期函数。
      例如:

          App({
            // 小程序初始化完成时,执行此函数,可以做一些初始化的工作。
            onLaunch: function(options) {},
            // 小程序显示到屏幕上的时候,执行此函数。
            onShow  : function(options) {},
            // 小程序被最小化的时候,执行此函数。
            onHide  : function() {}
          })
      
      注意onlaunch只执行一次  其他的是一直会执行
      
    • 页面生命周期函数
      每个小程序页面,必须拥有自己的 .js 文件,且必须调用 Page() 函数,否则报错。其中Page() 函数用来注册小程序页面。
      Page(Object) 函数接收一个Object参数,可以通过这个Object参数,指定页面的生命周期函数。
      例如:(定义的顺序也是函数加载的顺序)

      Page({
        onLoad  : function(options) {}, // 监听页面加载
        onShow  : function() {},        // 监听页面显示
        onReady : function() {},        // 监听页面初次渲染完成
        onHide  : function() {},        // 监听页面隐藏
        onUnload: function() {}         // 监听页面卸载
      })
      

      注意:onLoad与onReady,onUnload只显示一次,onHide与onShow循环执行

数据绑定

如何定义页面的数据

小程序中每个页面,由4部分组成,其中 .js 文件内可以定义页面的数据、生命周期函数、其它业务逻辑

如果要在.js文件内定义页面的数据,只需把数据定义到 data 节点下即可;

示例代码如下:

Page({
  data: {
    info: 'init data', // 字符串类型的数据
    array: [{msg: '1'}, {msg: '2'}] // 数组类型的数据
  }
})

Mustache语法格式 (差值表达式)(既可以用在内容节点,也可以用在属性节点)

把data中的数据绑定到页面中渲染,使用 Mustache 语法(双大括号)将变量包起来即可;

语法格式为:

<view> {{ 要绑定的数据名称 }} </view>

Mustache 语法的主要应用场景:

  • 绑定内容
  • 绑定属性(需要在双引号之内)

页面结构:

<view id="item-{{id}}"> </view>

页面数据:

Page({
  data: {
    id: 0
  }
})
  • 运算(三元表达式、算术运算、逻辑判断、字符串运算、数据路径运算)

页面结构:

<view> {{ flag ? ‘条件为真’ : ‘条件为假’ }} </view>

页面数据:

Page({
  data: {
    flag: true
  }
})

事件

事件是视图层到逻辑层的通讯方式。

事件可以将用户的行为反馈到逻辑层进行处理。

事件可以绑定在组件上,当组件触发事件,就会执行逻辑层中对应的事件处理函数。

事件对象可以携带额外信息,如 id, dataset, touches。

bindtap绑定触摸事件

在小程序中,不存在网页中的 onclick 鼠标点击事件,而是通过 tap 事件来响应触摸行为;

通过 bindtap,可以为组件绑定触摸事件,语法如下:

<view bindtap=“tapName”> Click me! <view>

2.在相应的Page定义中写上相应的事件处理函数,事件参数是event:

Page({
  tapName: function(event) {
    console.log(event)
  }
})

**bindinput绑定文本框输入事件(只要input框中内容发生改变就会出发这个事件)

在小程序中,通过 input 事件来响应文本框的输入事件;

\1. 通过 bindinput,可以为文本框绑定输入事件,语法如下:

<input bindinput=“inputName”><input>

在相应的Page定义中写上相应的事件处理函数,事件参数是event:

Page({
  inputName: function(event) {
    console.log(event)
  }
})

**data和文本框之间的数据同步(相当于vue中的数据双向绑定)

监听文本框的数据变化

在文本框的 input 事件处理函数中,通过事件参数 event,能够访问到文本框的最新值:

语法:event.detail.value

示例代码如下:

inputName: function (event) {
// 获取到文本框中最新的内容
console.log(event.detail.value)
}

通过 this.setData(dataObject) 方法,可以给页面中的 data 数据重新赋值。

例如:监听文本框的数据变化,并把最新的值赋值给 data 中的 msg

示例代码如下:

inputName: function (event) {
this.setData({
msg: event.detail.value // 为 data 中的 msg 重新赋值
})
}

总代码如下:

inputEvent:function(e){
    // 1.获取到最新的值
    console.log(e.detail.value)
    // 2,。调用this.setData({})为data中数据重新赋值
    this.setData({
      info: e.detail.value
    })
  },

事件传参(小程序中华不支持事件传参方式,因为小程序会把 bindtap 后指定的值,统一当作事件名称来处理;)

不能在绑定事件的同时传递参数

小程序中的事件传参比较特殊,不能在为组件绑定事件的同时,为事件处理函数传递参数。

例如,下面的代码将不能正常工作:

<button type="primary" bindtap='btnHandler(123)'>事件传参</button>

通过data-*自定义属性传参

如果要在组件触发事件处理函数的时候,传递参数,可以为组件提供 data-* 自定义属性传参。

示例代码如下:

<button bindtap='btnHandler’ data-info=“{{123}}”>事件传参</button>

其中,info 会被当作参数名,数值 123 会被当作参数值。

接收传递的参数

通过e.target.dataset来接收

结构:

<button bindtap="inputEvent2" data-msg="123" type="primary">按钮</button>

数据:

inputEvent2:function(e){
    console.log('ok')
    console.log(e)
    console.log(e.target.dataset.msg)

  },

wxs 脚本

wxs(WeiXinScript)是小程序的一套脚本语言,结合WXML,可以构建出页面的结构

  • 没有兼容性:wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行(基础库版本:微信开发者工具中的详情按钮—本地设置—调试基础库。小程序从发布到至今,里面的API一直在迭代更新,某些API在新版本中可以使用,旧版本就会不支持,会存在兼容性问题。但是wxs与版本库之间不存在版本的兼容性问题)
  • 与 javascript 不同:wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致
  • 隔离性:wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的函数,也不能调用小程序提供的API(不要在wxs中调用javascript代码,也不要在js中调用wxs代码)
  • 不能作为事件回调:wxs 函数不能作为组件的事件回调(事件处理函数只能定义到.js文件中,不能定义到.wxs中去。所以wxs中不能声明事件的回调函数)
  • iOS设备上比 javascript 运行快:由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异(所以某些功能如果能写到wxs中就尽量写到wxs中去)

wxs遵循CommonJS模块化规范(和node语法一样)

CommonJS 是 javascript 的模块化规范之一,小程序的脚本语言 wxs 遵循了 CommonJS 规范,因此,使用 wxs 时的体验和使用 node.js 的体验比较相似。

在 wxs 中,可以使用 CommonJS 中规定的如下成员:

  • module 对象:每个 wxs 都是独立的模块,每个模块均有一个内置的 module 对象,每个模块都有自己独立的作用域。
  • module.exports:由于 wxs 拥有独立作用域,所以在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见,通过 module.exports 属性,可以对外共享本模块的私有变量与函数。
  • require函数:在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。

wxs 基础语法

使用module.exports 向外共享成员

通过 module.exports 属性,可以对外共享本模块的私有变量与函数。示例代码如下:

var foo = “‘hello world’ from wxs”; // 定义私有变量 foo
var bar = function (d) {            // 定义私有函数 bar
  return d;
}
module.exports = { // 通过 modules.exports 向外共享私有成员
  FOO: foo, // 向外共享私有变量 foo
  bar: bar, // 向外共享私有函数 bar
};
module.exports.msg = “some msg”; // 额外向 module.exports 中挂载 msg 变量

使用

require 引入其它wxs 模块

假设有两个wxs模块,路径分别为/pages/tools.wxs 和/pages/logic.wxs,如果要在logic.wxs中引入tools.wxs
脚本,则示例代码如下:

// 使用 require 导入 tools.wxs 脚本
var tools = require("./tools.wxs");
// 得到的 tools 对象,可以直接访问到 tools.wxs 中向外暴露的变量和方法

在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。

引用的时候,要注意如下几点:

①只能引用 .wxs 文件模块,且必须使用相对路径。

②wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。(节省了内存。内存中值占一份的内存,但是可以多次使用)

③如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。s

支持的数据类型

WXS 语言目前共有以下8种数据类型:

number 数值类型、string 字符串类型、boolean 布尔类型、object 对象类型、

function 函数类型、array 数组类型、 date 日期类型、 regexp 正则

详细的类型说明文档,请翻阅如下网址:

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/06datatype.html

注意:由于wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致,所以在使用以上8种数据类型的时候,一定要先翻阅官方文档,再进行使用!

内嵌 wxs 脚本

wxs 代码可以编写在 wxml 文件中的标签内,就像 javascript 代码可以编写在 html 文件中的 标签内一样。

wxml 文件中的每个 标签,必须提供一个 module 属性,用来指定当前 标签的模块名。在单个 wxml 文件内,建议其值唯一。

module 属性值的命名必须符合下面两个规则:

  • 首字符必须是:字母(a-zA-Z),下划线(_)
  • 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)

外联 wxs 脚本

wxs 代码还可以编写在以 .wxs 为后缀名的文件内,就像 javascript 代码可以编写在以 .js 为后缀名的文件中一样。

在微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

示例代码如下:

// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
}
module.exports = {
  FOO: foo,
  bar: bar,
};
module.exports.msg = "some msg";

wxml 内引用外联的 wxs 脚本

在 wxml 中如果要引入外联的 wxs 脚本,必须为 标签添加 module 和 src 属性。

  • module 用来为 标签指定模块名,作为当前页面访问这个模块的标识名称;
  • src 用来指定当前 标签要引入的脚本路径,必须是相对路径;

示例代码如下:

<!-- page/index/index.wxml -->
<wxs src="./../tools.wxs" module="tools" />
<view> {{tools.msg}} </view>
<view> {{tools.bar(tools.FOO)}} </view>

注意:在wxs中尽量不要使用高级的es5,es6语法(wxs和js是不一样的,不要想当然的就使用,就使用之前的语法,不要使用es5,es6新语法)

页面渲染

条件渲染wx:if

在.js文件的data中设置好length的值,然后再.wxml文件中写:

<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>

elif 就是 else-if(vue中)

blockwx:if

因为wx:if是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用wx:if 控制属性。

<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>

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

hidden

在小程序中,直接使用
hidden="{{condition}}" 也能控制元素的显示与隐藏:

<view hidden="{{condition}}"> 条件为 true 隐藏,条件为 false 显示 </view>

wx:if与hidden的对比(类比vue中的 v-if v-show 是一样的作用)

  • 被 wx:if 控制的区域,框架有一个局部渲染的过程,会根据控制条件的改变,动态创建或销毁对应的UI结构。
  • 同时, wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
  • 相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
  • 总结:wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。

wx:for

绑定一个数组

<view wx:for="{{array}}">

  索引是:{{index}} 当前项是:{{item}}

</view>

手动指定索引和当前项的变量名

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

l使用 wx:for-index 可以指定数组当前下标的变量名,示例代码如下:

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  索引是:{{idx}} 当前项是:{{itemName}}
</view>

blockwx:for

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

列表渲染中的 key

作用:

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

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

<view wx:for="{{list}}" wx:key="index">
  id:{{item.id}}
  name:{{item.name}}
</view>

js文件中

data: {
    length:4,
    contation:false,
    array:[1,2,3,4,5],
    list:[
      { id: 0, name: '张三' },
      { id: 1, name: '张三1' },
      { id: 2, name: '张三2' },
     {id:3,name:'张三3'}
    ]
  },

添加数据到列表中案例分析

<view>
  <input  value="{{name}}" bindinput="iptHandler"></input>
  <button type="primary" bindtap="add">添加</button>
</view>
<view wx:for="{{list}}" wx:key="index">
<checkbox></checkbox>
  id:{{item.id}}
  name:{{item.name}}
</view>

main.js文件

  data: {
    length:4,
    contation:false,
    array:[1,2,3,4,5],
    list:[
      { id: 0, name: '张三' },
      { id: 1, name: '张三1' },
      { id: 2, name: '张三2' },
     {id:3,name:'张三3'}
    ],
    name:'',
    
  },

  iptHandler:function(e){
    // console.log(e.detail.value)
    this.setData({
      name:e.detail.value
    })
    // console.log(this.data.name)
  },
  add:function(){
    console.log(this.data.name)
    const userInfo = {id:this.data.list.length,name:this.data.name}
    console.log(userInfo)
    const arr = this.data.list;
    arr.unshift(userInfo);
    // 重新把新的数组赋值给 list
    this.setData({
      list:arr
    })

  },

双向绑定input框中的数据 bindinput=""

函数中的操作,想要改变data中的数据值,必须使用 this.setData({ name:e.detail.value }) 这种方式

一个bug:如果在添加的每条数据列表前加上 checkbox选项。选中当前序号为1的数据,如果再添加一条数据,之前选中的序号为1的数据就会发生变化(不会始终都选中,选择的序号不唯一)这是因为没有为其绑定唯一的值来标识他。

解决方案:将绑定的标识换成当前数据的id值(每个数据的id是唯一的)wx:key=“id”

注意:这里和vue中不太一样,不能写item.id ,而是直接写 id

<view>
  <input  value="{{name}}" bindinput="iptHandler"></input>
  <button type="primary" bindtap="add">添加</button>
</view>
<view wx:for="{{list}}" wx:key="id">
<checkbox></checkbox>
  id:{{item.id}}
  name:{{item.name}}
</view>

key值的注意点

①key 值必须具有唯一性,且不能动态改变

②key 的值必须是数字或字符串

③保留关键字 *this 代表在 for 循环中的 item 本身,它也可以充当 key 值,但是有以下限制:需要 item 本身是一个唯一的字符串或者数字。(就是在数组中的值不能有重复的值出现)

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

key值的两种使用方式

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

①字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。

②保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。

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

<!-- 也可使用  *this 来为每一条数据绑定唯一的标识值,前提是必须数组里面的值是唯一的,不能有重复的值 -->
<!-- <view wx:for="{{list0}}" wx:key="*this">{{item}}
</view> -->
<!-- 默认就是索引值变量是 index,上面如果是 对象中,可以用 item.id -->
<view wx:for="{{list0}}" wx:key="index">{{item}}</view>s

下拉刷新

启用下拉刷新

两种方式:

①需要在 app.json 的 window 选项中或页面配置中开启 enablePullDownRefresh。但是,一般情况下,推荐在页面配置中为需要的页面单独开启下拉刷新行为。

②可以通过 wx.startPullDownRefresh() 触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。(前提是在json文件中开启了 “enablePullDownRefresh”:true)

配置下拉刷新窗口的样式

需要在 app.json 的 window 选项中或页面配置中修改 backgroundColor 和 backgroundTextStyle 选项。

  • backgroundColor 用来配置下拉刷新窗口的背景颜色,仅支持16进制颜色值

  • backgroundTextStyle 用来配置下拉刷新 loading 的样式,仅支持 dark 和 light

    {
    “usingComponents”: {},
    “enablePullDownRefresh”:true,
    “backgroundColor”:"#ccc",
    “backgroundTextStyle”:“light”
    }

onPullDownRefresh() 函数,可以监听用户在当前页面的下拉刷新事件。

stopPullDownRefresh()自动监听到刷新完毕,关闭下拉刷新

注意写在onPullDownRefresh函数里面

onPullDownRefresh: function () {
    // 监听用户的下拉刷新操作
    console.log('触发了下拉刷新操作!!')
    // 触发下拉刷新按钮,触发下拉刷新函数,为页面中的数值重新赋值或者修改数据
    this.setData({
      list0:['zs','ls']
    })

    // 关闭下拉刷新
    wx.stopPullDownRefresh()
  },

上拉加载更多(原理就是分页加载)

可以在 app.json 的 window 选项中或页面配置中设置触底距离
onReachBottomDistance。单位为px,默认触底距离为 50px。

为页面添加onReachBottom()函数,可以监听用户在当前页面的上拉触底事件,从而实现上拉加载更多列表数据的效果。

onPageScroll(Object)

在main.js文件中直接写这个函数参数默认是 obj,就可以打印出当前的移动的距离

 onPageScroll: function (obj){
    console.log(obj.scrollTop)
  },

onShareAppMessage(Object)

监听用户点击页面内转发按钮(组件open-type=“share”)或右上角菜单“转发”按钮的行为,并自定义转发内容。其中Object参数说明如下:

两种方式进行转发

  • 点击微信上右上角的转发按钮 触发的是menu,也就是事件来源是menu(三个圆点。默认显示的页面就是当前页面的预览)

    // 点击默认的转发按钮触发事件
    onShareAppMessage:function(obj){
      console.log(obj)
    }
    打印出的对象是 from:menu target:undefined,还有一个原型对象
    
  • 自定义一个按钮,点击此按钮,转发(open-type=“share”)

    转发按钮
    打印出一个对象 from:button target值是一个对象(描述当前按钮的所有信息,如果按钮上有一个自定义属性 data-info=“aaa” ,则可以通过 target.dataset.info 得到值 aaa)

自定义转发之前的页面预览结果页面

同时,此转发事件需要 return 一个 Object,用于自定义转发内容,返回内容如下:

 // 点击默认的转发按钮触发事件
  onShareAppMessage:function(obj){
    console.log(obj)
    return{
      title:"测试转发标题",
      path:"/pages/main/main",//这个路径是  当把转发给别人看的时候,别人在一打开页面的时候就显示这个路径页面中的内容(一般都是转发当前页面的路径)
      imageUrl:"https://www.baidu.com/img/bd_logo1.png?where=super"
    }
  }

注意:转发的路径之前一定不要忘了加/

上拉触底案例:

上拉加载,当前页面值加一

新旧数组的追加(新数据追加到就数组中,一起赋值给旧的数组)

this.setData({
      msgList: [...this.data.msgList,...newArr]
    })

  onReachBottom: function () {
    console.log('触底了!')
    // 先让页码值加一
    this.setData({
      page:this.data.page + 1
    })
    // 获取下一页的数据
    // 先定义一个数组,然后没加载一页,数值一直自增
    const newArr = []
    for(let i = 1;i<=10;i++){
      const c = (this.data.page - 1 ) * 10 + i;
      newArr.push(c)

    }
    // 在页面快要触底的时候才会触发这个函数,然后打印一下下一页的数据
    // console.log(newArr)
    // 为旧数组重新赋值
    this.setData({
      msgList: [...this.data.msgList,...newArr]
    })
  },

onTabItemTap(Object)(只要tab栏被点击的时候就会触发这个函数)

在全局的app.json文件中写上,配置tabBar。默认position是bottom,设置为top

  "tabBar": {
    "position":"top",
    "list": [{
      "pagePath": "pages/main/main",
      "text": "main"
    },{
      "pagePath": "pages/home/home",
      "text": "home"
    }]
  },

在点击跳转到哪个页面的时候监听,那就在哪个页面中设置 onTabItemTap(obj)事件

打印出一个对象,对象里面就是上面表格中列举出的三个属性(index,pagePath,text)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值