wxs

作者: 达文西_Huong | 来源:发表于2020-06-17 10:41 被阅读0次

WXS函数响应事件

从官方文档所描述:

在WXS函数接受2个参数,
第一个是event,在event的基础上加event.instance对象。
第二个参数是ownerInstance,和event.instance一样是一个ComponentDescriptor对象。

具体的使用如下:

  • 在组件中绑定和注册事件处理的WXS函数
    <wxs module="wxs"  src="./test.wxs"></wxs>
    <view id="tapTest" data-hi="hi" bind:tap="{{wxs.tapName}}">
        Click me
    </view>
    // 调用wxs中的方法的时候必须要用{{}}括起来
  • test.wxs文件实现tapName函数
    function tapName(event, ownerInstance) {
        console.log('tap wechat', JSON.stringify(event))
    }
    module.exports = {
        tapName:tapName
    }

ownerInstance包含了一些方法,可以设置组件的样式和class,具体包含的方法以及为什么要用WXS函数响应事件,如下:

背景

有频繁的用户交互的效果在小程序上表现是比较卡顿的,例如页面有 2 个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动,movable-view 就是一个典型的例子。
一次touchmove事件的响应过程如下:

a、touchmove事件从渲染层(WebVew) 抛到逻辑层(APP Service)
b、逻辑层(App Service)处理touchmove事件,再通过setData来改变B的位置
一次touchmove的响应需要经过2次逻辑层和渲染层的通信。以及一次渲染,通信耗时比较大。而且setData渲染也会阻塞其他脚本的执行,导致了用户交互的动画过程会有延迟。

于是官方就提出了以下方案

实现方案

本方案的思路就是减少通信的次数,让事件在视图层(Web View)响应。小程序的框架是双线程结构。而这个方案的实现就是让开发者的代码运行在视图层(Web View),如下图:

image

使用WXS函数响应小程序事件,目前仅支持响应内置组件的事件,不支持自定义组件事件。WXS函数的除了纯逻辑的运算,还可以通过封装好的ComponentDescriptor实例访问以及设置组件的class和样式。

   var wxsfunction = function(event, ownerInstance) {
       var instance = ownerInstance.selectComponent('.classSelector')  // 返回选中的组件的实例
       instance.setStyle({
           "font-size":"14px" // 支持rpx
       })
       instance.getDataset()
       instance.setClass(className)
       // ...
       return false    // 这一句是为了不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault
   }

其中event是小程序事件对象基础上多了event.instance来表示触发事件的组件的ComponentDescriptor实例。ownerInstance表示的是触发事件的组件所在的组件的ComponentDescriptor实例,例如,如果触发事件的组件是在页面内的,ownerInstance表示的是页面实例
ComponentDescriptor的定义如下:

方法 参数 描述
selectComponent selector对象 返回组件的ComponentDescriptor实例
selectAllComponents selector对象数组 返回组件的 ComponentDescriptor 实例组
setStyle Object/string 设置组件样式,支持rpx。设置的样式优先级比组件wxml里面定义的样式高。不能设置最顶层页面的样式。
addClass/removeClass/ hasClass string 设置组件的class。设置的class优先级比组件wxml里面定义的class 高。不能设置最顶层页面的 class。
getDataset 返回当前组件/页面的 dataset 对象
callMethod (funcName:string, args:object) 调用当前组件/页面在逻辑层(App Service)定义的函数。funcName表示函数名称,args表示函数的参数。
requestAnimationFrame Function 和原生 requestAnimationFrame 一样。用于设置动画。
getState 返回一个object对象,当有局部变量需要存储起来后续使用的时候用这个方法。
triggerEvent (eventName, detail) 和组件的triggerEvent一致。

callMethod 是 WXS 里面调用逻辑层(App Service)开发者的代码的方法,而 WxsPropObserver 是逻辑层(App Service)开发者的代码调用 WXS 逻辑的机制。

使用方法
   <wxs module='test' src='./test.wxs'/>
   <view change:prop='{{test.propObserver}}'
    prop='{{propValue}}' bindtouchmove='{{test.touchmove}}' class='movable'/>

上面的change:prop,这个属性是当prop属性被设置的时候触发wxs函数,它优点类似component定义的properties里面的observer属性,在setData({propValue:newValue})调用之后会触发。
tips
当 prop 的值被设置 WXS 函数就会触发,而不只是值发生改变,所以在页面初始化的时候会调用一次WxsPropObserver的函数。

    module.exports={
        touchmove:function(event, instance){
            console.log('log event:',JSON.stringify(event))
        },
        propObserver:function(newValue, oldValue, ownerInstance, instance) {
            console.log('prop observer',newValue, oldValue)
        }
    }

总结

wxs就是为了实现小程序开发得过程中减少渲染层和逻辑层之间得通讯从而提高性能而使用的。

参考: https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html

相关文章

网友评论

      本文标题:wxs

      本文链接:https://www.haomeiwen.com/subject/dxvjxktx.html