首页IT科技微信小程序框架模板(微信小程序框架)

微信小程序框架模板(微信小程序框架)

时间2025-06-18 23:21:04分类IT科技浏览4524
导读:框架 小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。...

框架

小程序开发框架的目标是通过尽可能简单             、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务               。

整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)                   。小程序提供了自己的视图层描述语言 WXML 和 WXSS               ,以及基于 JavaScript 的逻辑层框架                   ,并在视图层与逻辑层间提供了数据传输和事件系统        ,让开发者能够专注于数据与逻辑        。

响应的数据绑定

框架的核心是一个响应的数据绑定系统            ,可以让数据与视图非常简单地保持同步            。当做数据修改的时候                   ,只需要在逻辑层修改数据           ,视图层就会做相应的更新                   。

通过这个简单的例子来看:

在开发者工具中预览效果

<!-- This is our View --> <view> Hello {{name}}! </view> <button bindtap="changeName"> Click me! </button> // This is our App Service. // This is our data. var helloData = { name: Weixin } ​ // Register a Page. Page({ data: helloData, changeName: function(e) {   // sent data change to view   this.setData({     name: MINA   }) } })

开发者通过框架将逻辑层数据中的 name 与视图层的 name 进行了绑定        ,所以在页面一打开的时候会显示 Hello Weixin!;

当点击按钮的时候                    ,视图层会发送 changeName 的事件给逻辑层              ,逻辑层找到并执行对应的事件处理函数;

回调函数触发后    ,逻辑层执行 setData 的操作                     ,将 data 中的 name 从 Weixin 变为 MINA                 ,因为该数据和视图层已经绑定了,从而视图层会自动改变为 Hello MINA!           。

页面管理

框架 管理了整个小程序的页面路由                  ,可以做到页面间的无缝切换                    ,并给以页面完整的生命周期        。开发者需要做的只是将页面的数据                       、方法      、生命周期函数注册到 框架 中    ,其他的一切复杂的操作都交由 框架 处理                    。

基础组件

框架 提供了一套基础的组件               ,这些组件自带微信风格的样式以及特殊的逻辑                   ,开发者可以通过组合基础组件        ,创建出强大的微信小程序               。

丰富的 API

框架 提供丰富的微信原生 API            ,可以方便的调起微信提供的能力                   ,如获取用户信息           ,本地存储        ,支付功能等    。

逻辑层 App Service

小程序开发框架的逻辑层使用 JavaScript 引擎为小程序提供开发者 JavaScript 代码的运行环境以及微信小程序的特有功能                     。

逻辑层将数据进行处理后发送给视图层                    ,同时接受视图层的事件反馈                 。

开发者写的所有代码最终将会打包成一份 JavaScript 文件              ,并在小程序启动的时候运行    ,直到小程序销毁。这一行为类似 ServiceWorker                     ,所以逻辑层也称之为 App Service                  。

在 JavaScript 的基础上                 ,我们增加了一些功能,以方便小程序的开发:

增加 App 和 Page 方法                  ,进行程序注册和页面注册                    。

增加 getApp 和 getCurrentPages 方法                    ,分别用来获取 App 实例和当前页面栈    。

提供丰富的 API    ,如微信用户数据               ,扫一扫                   ,支付等微信特有能力               。

提供模块化能力        ,每个页面有独立的作用域                   。

注意:小程序框架的逻辑层并非运行在浏览器中            ,因此 JavaScript 在 web 中一些能力都无法使用                   ,如 window           ,document 等        。

小程序的生命周期

每个小程序都需要在 app.js 中调用 App 方法注册小程序实例        ,绑定生命周期回调函数         、错误监听和页面不存在监听函数等            。

详细的参数含义和使用请参考 App 参考文档                   。

// app.js App({  onLaunch (options) {    // Do something initial when launch. },  onShow (options) {    // Do something when show. },  onHide () {    // Do something when hide. },  onError (msg) {    console.log(msg) },  globalData: I am global data })

整个小程序只有一个 App 实例                    ,是全部页面共享的           。开发者可以通过 getApp 方法获取到全局唯一的 App 实例              ,获取 App 上的数据或调用开发者注册在 App 上的函数        。

// xxx.js const appInstance = getApp() console.log(appInstance.globalData) // I am global data

前台                       、后台定义: 当用户点击左上角关闭    ,或者按了设备 Home 键离开微信                     ,小程序并没有直接销毁                 ,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台                    。

只有当小程序进入后台一定时间                  ,或者系统资源占用过高                    ,才会被真正的销毁              。

注意:

1.不要在定义于 App() 内的函数中调用 getApp()     ,使用 this 就可以拿到 app 实例    。

2.不要在 onLaunch 的时候调用 getCurrentPage()               ,此时 page 还没有生成                     。

3.通过 getApp() 获取实例之后                   ,不要私自调用生命周期函数                 。

注册页面

对于小程序中的每个页面        ,都需要在页面对应的 js 文件中进行注册            ,指定页面的初始数据          、生命周期回调      、事件处理函数等。

使用 Page 构造器注册页面

简单的页面可以使用 Page() 进行构造                  。

代码示例:

//index.js Page({  data: {    text: "This is page data." },  onLoad: function(options) {    // 页面创建时执行 },  onShow: function() {    // 页面出现在前台时执行 },  onReady: function() {    // 页面首次渲染完毕时执行 },  onHide: function() {    // 页面从前台变为后台时执行 },  onUnload: function() {    // 页面销毁时执行 },  onPullDownRefresh: function() {    // 触发下拉刷新时执行 },  onReachBottom: function() {    // 页面触底时执行 },  onShareAppMessage: function () {    // 页面被用户分享时执行 },  onPageScroll: function() {    // 页面滚动时执行 },  onResize: function() {    // 页面尺寸变化时执行 },  onTabItemTap(item) {    // tab 点击时执行    console.log(item.index)    console.log(item.pagePath)    console.log(item.text) },  // 事件响应函数  viewTap: function() {    this.setData({      text: Set some data for updating view.   }, function() {      // this is setData callback   }) },  // 自由数据  customData: {    hi: MINA } })

详细的参数含义和使用请参考 Page 参考文档                     。

在页面中使用 behaviors

基础库 2.9.2 开始支持                   ,低版本需做兼容处理    。

页面可以引用 behaviors                。 behaviors 可以用来让多个页面有相同的数据字段和方法                   。

// my-behavior.js module.exports = Behavior({  data: {    sharedText: This is a piece of data shared between pages. },  methods: {    sharedMethod: function() {      this.data.sharedText === This is a piece of data shared between pages.   } } }) // page-a.js var myBehavior = require(./my-behavior.js) Page({  behaviors: [myBehavior],  onLoad: function() {    this.data.sharedText === This is a piece of data shared between pages. } })

具体用法参见 behaviors         。

使用 Component 构造器构造页面

基础库 1.6.3 开始支持           ,低版本需做兼容处理            。

Page 构造器适用于简单的页面                   。但对于复杂的页面        , Page 构造器可能并不好用           。

此时                    ,可以使用 Component 构造器来构造页面        。 Component 构造器的主要区别是:方法需要放在 methods: { } 里面                    。

代码示例:

Component({  data: {    text: "This is page data." },  methods: {    onLoad: function(options) {      // 页面创建时执行   },    onPullDownRefresh: function() {      // 下拉刷新时执行   },    // 事件响应函数    viewTap: function() {      // ...   } } })

这种创建方式非常类似于 自定义组件               ,可以像自定义组件一样使用 behaviors 等高级特性              。

具体细节请阅读 Component 构造器 章节    。

页面的生命周期

下图说明了页面 Page 实例的生命周期                     。

写微信小程序    ,他的生命周期不能不知道                     ,不知道小程序就会出现各种bug而无法解决                 。

小程序由两大线程组成:负责界面的线程(view thread)和服务线程(appservice thread)                 ,各司其职由互相配合

页面路由

在小程序中所有页面的路由全部由框架进行管理。

页面栈

框架以栈的形式维护了当前的所有页面                  。 当发生路由切换的时候,页面栈的表现如下:

路由方式 页面栈表现 初始化 新页面入栈 打开新页面 新页面入栈 页面重定向 当前页面出栈                  ,新页面入栈 页面返回 页面不断出栈                    ,直到目标返回页 Tab 切换 页面全部出栈    ,只留下新的 Tab 页面 重加载 页面全部出栈               ,只留下新的页面

开发者可以使用 getCurrentPages() 函数获取当前页面栈                    。

路由方式

对于路由的触发方式以及页面生命周期函数如下:

路由方式 触发时机 路由前页面 路由后页面 初始化 小程序打开的第一个页面 onLoad, onShow 打开新页面 调用 API wx.navigateTo 使用组件 `` onHide onLoad, onShow 页面重定向 调用 API wx.redirectTo 使用组件 `` onUnload onLoad, onShow 页面返回 调用 API wx.navigateBack 使用组件`` 用户按左上角返回按钮 onUnload onShow Tab 切换 调用 API wx.switchTab 使用组件 `` 用户切换 Tab 各种情况请参考下表 重启动 调用 API wx.reLaunch 使用组件 `` onUnload onLoad, onShow

Tab 切换对应的生命周期(以 A                      、B 页面为 Tabbar 页面                   ,C 是从 A 页面打开的页面        ,D 页面是从 C 页面打开的页面为例):

当前页面 路由后页面 触发的生命周期(按顺序) A A Nothing happend A B A.onHide(), B.onLoad(), B.onShow() A B(再次打开) A.onHide(), B.onShow() C A C.onUnload(), A.onShow() C B C.onUnload(), B.onLoad(), B.onShow() D B D.onUnload(), C.onUnload(), B.onLoad(), B.onShow() D(从转发进入) A D.onUnload(), A.onLoad(), A.onShow() D(从转发进入) B D.onUnload(), B.onLoad(), B.onShow()

注意事项

navigateTo, redirectTo 只能打开非 tabBar 页面    。

a--navigateTo--c, c-->redirectTo-->d

switchTab 只能打开 tabBar 页面               。

reLaunch 可以打开任意页面                   。

页面底部的 tabBar 由页面决定            ,即只要是定义为 tabBar 的页面                   ,底部都有 tabBar        。

调用页面路由带的参数可以在目标页面的onLoad中获取            。

模块化

模块化

可以将一些公共的代码抽离成为一个单独的 js 文件           ,作为一个模块                   。模块只有通过 module.exports 或者 exports 才能对外暴露接口           。

注意:

exports 是 module.exports 的一个引用        ,因此在模块里边随意更改 exports 的指向会造成未知的错误        。所以更推荐开发者采用 module.exports 来暴露模块接口                    ,除非你已经清晰知道这两者的关系                    。

小程序目前不支持直接引入 node_modules , 开发者需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中              ,或者使用小程序支持的 npm 功能              。

// common.js function sayHello(name) {  console.log(`Hello ${name} !`) } function sayGoodbye(name) {  console.log(`Goodbye ${name} !`) } ​ module.exports.sayHello = sayHello exports.sayGoodbye = sayGoodbye 在需要使用这些模块的文件中    ,使用 require 将公共代码引入;也可以使用import导入 var common = require(common.js) Page({  helloMINA: function() {    common.sayHello(MINA) },  goodbyeMINA: function() {    common.sayGoodbye(MINA) } })

文件作用域

在 JavaScript 文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数                     ,不会互相影响    。

通过全局函数 getApp 可以获取全局的应用实例                 ,如果需要全局的数据可以在 App() 中设置,如:

// app.js App({  globalData: 1 }) // a.js // The localValue can only be used in file a.js. var localValue = a // Get the app instance. var app = getApp() // Get the global data and change it. app.globalData++ // b.js // You can redefine localValue in file b.js, without interference with the localValue in a.js. var localValue = b // If a.js it run before b.js, now the globalData shoule be 2. console.log(getApp().globalData)

API

小程序开发框架提供丰富的微信原生 API                  ,可以方便的调起微信提供的能力                    ,如获取用户信息    ,本地存储               ,支付功能等                     。详细介绍请参考 API 文档                 。

通常                   ,在小程序 API 有以下几种类型:

事件监听 API

我们约定        ,以 on 开头的 API 用来监听某个事件是否触发            ,如:wx.onSocketOpen                   ,wx.onCompassChange 等。

这类 API 接受一个回调函数作为参数           ,当事件触发时会调用这个回调函数        ,并将相关数据以参数形式传入                  。

代码示例

wx.onCompassChange(function (res) {  console.log(res.direction) })

同步 API

我们约定                    ,以 Sync 结尾的 API 都是同步 API              , 如 wx.setStorageSync    ,wx.getSystemInfoSync 等                    。此外                     ,也有一些其他的同步 API                 ,如 wx.createWorker,wx.getBackgroundAudioManager 等                  ,详情参见 API 文档中的说明    。

同步 API 的执行结果可以通过函数返回值直接获取                    ,如果执行出错会抛出异常               。

代码示例

try {  wx.setStorageSync(key, value) } catch (e) {  console.error(e) }

异步 API

大多数 API 都是异步 API    ,如 wx.request               ,wx.login 等                   。这类 API 接口通常都接受一个 Object 类型的参数                   ,这个参数都支持按需指定以下字段来接收接口调用结果:

Object 参数说明

参数名 类型 必填 说明 success function 否 接口调用成功的回调函数 fail function 否 接口调用失败的回调函数 complete function 否 接口调用结束的回调函数(调用成功              、失败都会执行) 其他 Any - 接口定义的其他参数

回调函数的参数

success        ,fail            ,complete 函数调用时会传入一个 Object 类型参数                   ,包含以下字段:

属性 类型 说明 errMsg string 错误信息           ,如果调用成功返回 ${apiName}:ok errCode number 错误码        ,仅部分 API 支持                    ,具体含义请参考对应 API 文档              ,成功时为 0        。 其他 Any 接口返回的其他数据

异步 API 的执行结果需要通过 Object 类型的参数中传入的对应回调函数获取            。部分异步 API 也会有返回值    ,可以用来实现更丰富的功能                     ,如 wx.request                 ,wx.connectSocket 等                   。

代码示例

wx.login({  success(res) {    console.log(res.code) } })

异步 API 返回 Promise

基础库 2.10.2 版本起,异步 API 支持 callback & promise 两种调用方式           。当接口参数 Object 对象中不包含 success/fail/complete 时将默认返回 promise                  ,否则仍按回调方式执行                    ,无返回值        。

注意事项

部分接口如 downloadFile, request, uploadFile, connectSocket, createCamera(小游戏)本身就有返回值    , 它们的 promisify 需要开发者自行封装                    。

当没有回调参数时               ,异步接口返回 promise              。此时若函数调用失败进入 fail 逻辑                   , 会报错提示 Uncaught (in promise)        ,开发者可通过 catch 来进行捕获    。

wx.onUnhandledRejection 可以监听未处理的 Promise 拒绝事件                     。

代码示例

// callback 形式调用 wx.chooseImage({  success(res) {    console.log(res:, res) } }) ​ // promise 形式调用 wx.chooseImage().then(res => console.log(res: , res))

视图层 View

框架的视图层由 WXML 与 WXSS 编写            ,由组件来进行展示                 。

将逻辑层的数据反映成视图                   ,同时将视图层的事件发送给逻辑层。

WXML(WeiXin Markup language) 用于描述页面的结构                  。

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

WXSS(WeiXin Style Sheet) 用于描述页面的样式    。

组件(Component)是视图的基本组成单元               。

WXML

WXML(WeiXin Markup Language)是框架设计的一套标签语言                    ,结合基础组件   、事件系统              ,可以构建出页面的结构                   。

要完整了解 WXML 语法    ,请参考WXML 语法参考        。

用以下一些简单的例子来看看 WXML 具有什么能力:

数据绑定

<!--wxml--> <view> {{message}} </view> // page.js Page({ data: {   message: Hello MINA! } })

列表渲染

<!--wxml--> <view wx:for="{{array}}"> {{item}} </view> // page.js Page({ data: {   array: [1, 2, 3, 4, 5] } })

条件渲染

<!--wxml--> <view wx:if="{{view == WEBVIEW}}"> WEBVIEW </view> <view wx:elif="{{view == APP}}"> APP </view> <view wx:else="{{view == MINA}}"> MINA </view> // page.js Page({ data: {   view: MINA } })

模板

<!--wxml--> <template name="staffName">  <view>   FirstName: {{firstName}}, LastName: {{lastName}}  </view> </template><template is="staffName" data="{{...staffA}}"></template> <template is="staffName" data="{{...staffB}}"></template> <template is="staffName" data="{{...staffC}}"></template> // page.js Page({ data: {   staffA: {firstName: Hulk, lastName: Hu},   staffB: {firstName: Shang, lastName: You},   staffC: {firstName: Gideon, lastName: Lin} } })

具体的能力以及使用方式在以下章节查看:

数据绑定                     、列表渲染                  、条件渲染、模板                 、引用

WXSS

WXSS (WeiXin Style Sheets)是一套样式语言                     ,用于描述 WXML 的组件样式            。

WXSS 用来决定 WXML 的组件应该怎么显示                   。

为了适应广大的前端开发者                 ,WXSS 具有 CSS 大部分特性           。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改        。

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

尺寸单位

样式导入

尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应                    。规定屏幕宽为750rpx              。如在 iPhone6 上                    ,屏幕宽度为375px    ,共有750个物理像素               ,则750rpx = 375px = 750物理像素                   ,1rpx = 0.5px = 1物理像素    。

设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度) iPhone5 1rpx = 0.42px 1px = 2.34rpx iPhone6 1rpx = 0.5px 1px = 2rpx iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx

建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准                     。

注意: 在较小的屏幕上不可避免的会有一些毛刺        ,请在开发时尽量避免这种情况                 。

样式导入

使用@import语句可以导入外联样式表            ,@import后跟需要导入的外联样式表的相对路径                   ,用;表示语句结束。

示例代码:

/** common.wxss **/ .small-p {  padding:5px; } /** app.wxss **/ @import "common.wxss"; .middle-p {  padding:15px; }

内联样式

框架组件上支持使用 style                      、class 属性来控制组件的样式                  。

style:静态的样式统一写到 class 中                    。style 接收动态的样式           ,在运行时会进行解析        ,请尽量避免将静态的样式写进 style 中                    ,以免影响渲染速度    。

<view style="color:{{color}};" />

class:用于指定样式规则              ,其属性值是样式规则中类选择器名(样式类名)的集合    ,样式类名不需要带上.                     ,样式类名之间用空格分隔               。

<view class="normal_view" />

选择器

目前支持的选择器有:

选择器 样例 样例描述 .class .intro 选择所有拥有 class="intro" 的组件 #id #firstname 选择拥有 id="firstname" 的组件 element view 选择所有 view 组件 element, element view, checkbox 选择所有文档的 view 组件和所有的 checkbox 组件 ::after view::after 在 view 组件后边插入内容 ::before view::before 在 view 组件前边插入内容

全局样式与局部样式

定义在 app.wxss 中的样式为全局样式                 ,作用于每一个页面                   。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面                  ,并会覆盖 app.wxss 中相同的选择器        。

WXS

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

示例

新建一个wxs文件

var toDecimal2 = function (x) {   var f = parseFloat(x);   if (isNaN(f)) {     return 0.00   }   var f = Math.round(x * 100) / 100;   var s = f.toString();   var rs = s.indexOf(.);   if (rs < 0) {     rs = s.length;     s += .;   }   while (s.length <= rs + 2) {     s += 0;   }   return s; } //module.exports = toDecimal2 module.exports = {   toDecimal2:toDecimal2 }

在wxml中使用

<!--pages/c/c.wxml--> <wxs src="../../wxs/PageUtils.wxs" module="PageUtils"></wxs> <wxs module="m1"> var msg = "hello world"; ​ module.exports.message = msg; </wxs> <view>   <text>pages/c/c.wxml,</text>   <text>{{m1.message}}</text>   <view>       <text>{{PageUtils.toDecimal2(123.453)}}</text>   </view>   <view>       <button type="primary" bindtap="jump">跳转到D页面</button>   </view> </view>

注意事项

WXS 不依赖于运行时的基础库版本               ,可以在所有版本的小程序中运行                   。

WXS 与 JavaScript 是不同的语言                   ,有自己的语法        ,并不和 JavaScript 一致           。

WXS 的运行环境和其他 JavaScript 代码是隔离的            ,WXS 中不能调用其他 JavaScript 文件中定义的函数                   ,也不能调用小程序提供的API        。

WXS 函数不能作为组件的事件回调                    。

由于运行环境的差异           ,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍              。在 android 设备上二者运行效率无差异    。

以下是一些使用 WXS 的简单示例        ,要完整了解 WXS 语法                    ,请参考WXS 语法参考                     。

页面渲染

<!--wxml--> <wxs module="m1"> var msg = "hello world"; ​ module.exports.message = msg; </wxs><view> {{m1.message}} </view>

页面输出:

hello world

数据处理

// page.js Page({  data: {    array: [1, 2, 3, 4, 5, 1, 2, 3, 4] } }) <!--wxml--> <!-- 下面的 getMax 函数              ,接受一个数组    ,且返回数组中最大的元素的值 --> <wxs module="m1"> var getMax = function(array) {  var max = undefined;  for (var i = 0; i < array.length; ++i) {    max = max === undefined ?      array[i] :     (max >= array[i] ? max : array[i]); }  return max; } ​ module.exports.getMax = getMax; </wxs><!-- 调用 wxs 里面的 getMax 函数                     ,参数为 page.js 里面的 array --> <view> {{m1.getMax(array)}} </view>

页面输出:

5

事件

什么是事件

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

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

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

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

事件的使用方式

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

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

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

<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>

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

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

可以看到 log 出来的信息大致如下:

{  "type":"tap",  "timeStamp":895,  "target": {    "id": "tapTest",    "dataset": {      "hi":"Weixin"   } },  "currentTarget": {    "id": "tapTest",    "dataset": {      "hi":"Weixin"   } },  "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 }] }

使用 WXS 函数响应事件

基础库 2.4.4 开始支持               ,低版本需做兼容处理        。

从基础库版本2.4.4开始                   ,支持使用 WXS 函数绑定事件        ,WXS函数接受2个参数            ,第一个是event                   ,在原有的 event 的基础上加了event.instance对象           ,第二个参数是ownerInstance        ,和event.instance一样是一个ComponentDescriptor对象            。具体使用如下:

在组件中绑定和注册事件处理的 WXS 函数                   。

<wxs module="wxs" src="./test.wxs"></wxs> <view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> Click me! </view> **注:绑定的 WXS 函数必须用{{}}括起来** test.wxs文件实现 tapName 函数 function tapName(event, ownerInstance) { console.log(tap Weixin, JSON.stringify(event)) } module.exports = { tapName: tapName }

ownerInstance包含了一些方法                    ,可以设置组件的样式和class              ,具体包含的方法以及为什么要用 WXS 函数响应事件    ,请点击查看详情           。

事件详解

事件分类

事件分为冒泡事件和非冒泡事件:

冒泡事件:当一个组件上的事件被触发后                     ,该事件会向父节点传递        。

非冒泡事件:当一个组件上的事件被触发后                 ,该事件不会向父节点传递                    。

WXML的冒泡事件列表:

类型 触发条件 最低版本 touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒                  ,弹窗 touchend 手指触摸动作结束 tap 手指触摸后马上离开 longpress 手指触摸后                    ,超过350ms再离开    ,如果指定了事件回调函数并触发了这个事件               ,tap事件将不被触发 1.5.0 longtap 手指触摸后                   ,超过350ms再离开(推荐使用 longpress 事件代替) transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 animationstart 会在一个 WXSS animation 动画开始时触发 animationiteration 会在一个 WXSS animation 一次迭代结束时触发 animationend 会在一个 WXSS animation 动画完成时触发 touchforcechange 在支持 3D Touch 的 iPhone 设备        ,重按时会触发 1.9.90

注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件            ,如 form 的submit事件                   ,input 的input事件           ,scroll-view 的scroll事件        ,(详见各个组件)

普通事件绑定

事件绑定的写法类似于组件的属性                    ,如:

<view bindtap="handleTap">   Click here! </view>

如果用户点击这个 view               ,则页面的 handleTap 会被调用              。

事件绑定函数可以是一个数据绑定    ,如:

<view bindtap="{{ handlerName }}">   Click here! </view>

此时                     ,页面的 this.data.handlerName 必须是一个字符串                 ,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)    。

自基础库版本 1.5.0 起                  ,在大多数组件和自定义组件中                    , bind 后可以紧跟一个冒号    ,其含义不变               ,如 bind:tap                      。基础库版本 2.8.1 起                   ,在所有组件中开始提供这个支持                 。

绑定并阻止事件冒泡

除 bind 外        ,也可以用 catch 来绑定事件。与 bind 不同            , catch 会阻止事件向上冒泡                  。

例如在下边这个例子中                   ,点击 inner view 会先后调用handleTap3和handleTap2(因为 tap 事件会冒泡到 middle view           ,而 middle view 阻止了 tap 事件冒泡        ,不再向父节点传递)                    ,点击 middle view 会触发handleTap2              ,点击 outer view 会触发handleTap1                    。

<view id="outer" bindtap="handleTap1"> outer view  <view id="middle" catchtap="handleTap2">   middle view    <view id="inner" bindtap="handleTap3">     inner view    </view>  </view> </view>

互斥事件绑定

自基础库版本 2.8.2 起    ,除 bind 和 catch 外                     ,还可以使用 mut-bind 来绑定事件    。一个 mut-bind 触发后                 ,如果事件冒泡到其他节点上,其他节点上的 mut-bind 绑定函数不会被触发                  ,但 bind 绑定函数和 catch 绑定函数依旧会被触发               。

换而言之                    ,所有 mut-bind 是“互斥               ”的    ,只会有其中一个绑定函数被触发                   。同时               ,它完全不影响 bind 和 catch 的绑定效果        。

例如在下边这个例子中                   ,点击 inner view 会先后调用 handleTap3 和 handleTap2         ,点击 middle view 会调用 handleTap2 和 handleTap1             。

<view id="outer" mut-bind:tap="handleTap1"> outer view  <view id="middle" bindtap="handleTap2">   middle view    <view id="inner" mut-bind:tap="handleTap3">     inner view    </view>  </view> </view>

事件的捕获阶段

自基础库版本 1.5.0 起            ,触摸类事件支持捕获阶段                   。捕获阶段位于冒泡阶段之前                   ,且在捕获阶段中           ,事件到达节点的顺序与冒泡阶段恰好相反           。需要在捕获阶段监听事件时        ,可以采用capture-bind   、capture-catch关键字                    ,后者将中断捕获阶段和取消冒泡阶段        。

在下面的代码中              ,点击 inner view 会先后调用handleTap2             、handleTap4                       、handleTap3      、handleTap1                    。

<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2"> outer view  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">   inner view  </view> </view>

如果将上面代码中的第一个capture-bind改为capture-catch    ,将只触发handleTap2              。

<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2"> outer view  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">   inner view  </view> </view>

事件对象

如无特殊说明                     ,当组件触发事件时                 ,逻辑层绑定该事件的处理函数会收到一个事件对象    。

BaseEvent 基础事件对象属性列表:

属性 类型 说明 基础库版本 type String 事件类型 timeStamp Integer 事件生成时的时间戳 target Object 触发事件的组件的一些属性值集合 currentTarget Object 当前组件的一些属性值集合 mark Object 事件标记数据 2.7.1

CustomEvent 自定义事件对象属性列表(继承 BaseEvent):

属性 类型 说明 detail Object 额外的信息

TouchEvent 触摸事件对象属性列表(继承 BaseEvent):

属性 类型 说明 touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组 changedTouches Array 触摸事件                  ,当前变化的触摸点信息的数组

特殊事件: canvas 中的触摸事件不可冒泡                    ,所以没有 currentTarget                     。

type

代表事件的类型                 。

timeStamp

页面打开到触发事件所经过的毫秒数。

target

触发事件的源组件                  。

属性 类型 说明 id String 事件源组件的id dataset Object 事件源组件上由data-开头的自定义属性组成的集合

currentTarget

事件绑定的当前组件                    。

属性 类型 说明 id String 当前组件的id dataset Object 当前组件上由data-开头的自定义属性组成的集合

说明: target 和 currentTarget 可以参考上例中    ,点击 inner view 时               ,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner                   ,而 handleTap2 收到的事件对象 target 就是 inner        ,currentTarget 就是 middle    。

dataset

在组件节点中可以附加一些自定义数据               。这样            ,在事件中可以获取这些自定义的节点数据                   ,用于事件的逻辑处理                   。

在 WXML 中           ,这些自定义数据以 data- 开头        ,多个单词由连字符 - 连接        。这种写法中                    ,连字符写法会转换成驼峰写法              ,而大写字符会自动转成小写字符            。如:

data-element-type     ,最终会呈现为 event.currentTarget.dataset.elementType ;

data-elementType                      ,最终会呈现为 event.currentTarget.dataset.elementtype                   。

示例:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view> Page({ bindViewTap:function(event){   event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法   event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写 } })

mark

在基础库版本 2.7.1 以上                 ,可以使用 mark 来识别具体触发事件的 target 节点           。此外, mark 还可以用于承载一些自定义数据(类似于 dataset )        。

当事件触发时                  ,事件冒泡路径上所有的 mark 会被合并                    ,并返回给事件回调函数                    。(即使事件不是冒泡事件    ,也会 mark               。)

代码示例:

在开发者工具中预览效果

<view mark:myMark="last" bindtap="bindViewTap">  <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button> </view>

在上述 WXML 中               ,如果按钮被点击                   ,将触发 bindViewTap 和 bindButtonTap 两个事件        ,事件携带的 event.mark 将包含 myMark 和 anotherMark 两项    。

Page({  bindViewTap: function(e) {    e.mark.myMark === "last" // true    e.mark.anotherMark === "leaf" // true } })

mark 和 dataset 很相似            ,主要区别在于: mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值                     。

细节注意事项:

如果存在同名的 mark                   ,父节点的 mark 会被子节点覆盖                 。

在自定义组件中接收事件时           , mark 不包含自定义组件外的节点的 mark 。

不同于 dataset         ,节点的 mark 不会做连字符和大小写转换                  。

touches

touches 是一个数组                    ,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)                    。 表示当前停留在屏幕上的触摸点    。

Touch 对象

属性 类型 说明 identifier Number 触摸点的标识符 pageX, pageY Number 距离文档左上角的距离              ,文档的左上角为原点     ,横向为 X 轴                     ,纵向为 Y 轴 clientX, clientY Number 距离页面可显示区域(屏幕除去导航条)左上角距离                 ,横向为 X 轴,纵向为 Y 轴

CanvasTouch 对象

属性 类型 说明 特殊说明 identifier Number 触摸点的标识符 x, y Number 距离 Canvas 左上角的距离                  ,Canvas 的左上角为原点                     ,横向为 X 轴    ,纵向为 Y 轴

changedTouches

changedTouches 数据格式同 touches               。 表示有变化的触摸点               ,如从无变有(touchstart)                   ,位置变化(touchmove)        ,从有变无(touchend         、touchcancel)                   。

detail

自定义事件所携带的数据            ,如表单组件的提交事件会携带用户的输入                   ,媒体的错误事件会携带错误信息           ,详见组件定义中各个事件的定义        。

点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离            。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
“毕业设计”(毕业设计学习锋迷商城的的笔记(手写后台商品管理,分类管理,用户,地址管理系统))