乐趣区

关于微信小程序:微信小程序三实现类似Vue中的-computedwatch-功能

前言

微信小程序和 vue 的语法十分像,会写 vue 的敌人上手 vue 根本是大海捞针。然而微信小程序中短少了很多 vue 中没有的货色,比方计算属性 computed、监听 watch。这些在平时开发中会常常用到。尽管微信小程序没有间接提供相干的 API 来应用这些,然而咱们能够用其余的一些办法来简略的间接的实现这些性能。
这篇文章就是记录一下实现这些性能的过程和一些集体感触。

实现步骤

computed 的实现过程

computed 的实现过程非常简单,咱们能够通过微信小程序脚本语言 WXS(WeiXin Script) 来简略实现相似 vue 中的 计算属性性能(computed)。

  1. 先了解官网文档的示例

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

    页面输入:hello world

咱们能够把 <wxs></wxs> 标签当做一对 <script></script> 标签一样,咱们能够在外面定义变量、函数。
而后在“Mustache”语法双括号里应用咱们定义的函数和变量。

  1. 看完官网示例后咱们就来实现一个相似 vue 中的简略的 computed
// page.js
Page({
  data: {
    order: {
        time: '2022-06-27',
        status: 1,
        amount: 10
    }
  }
})
<wxs module="comp">
  module.exports = {handleMatchStatus: function (source) {switch (source) {
        case 1:
          return '已领取'
        case 2:
          return '领取失败'
        case 3:
          return '退款中'
      }
    }
  }
</wxs>

<view> {{comp.handleMatchStatu(order.status)}} </view>

输入:已领取

在后盾拿到的一些数据,比方订单数据外面只有商品单价和数据,页面须要你显示总价,这个时候就能够这种形式来实现;或者是我的项目中有些数据是状态或者类型数据,比方订单状态、订单类型、商品渠道等,通过后端传过来的都是数字,有字典表的话还好办,没有字典表的话个别都是和后端磋商好,定死几个值,这个时候就能够通过这种形式显示数值对应的文字意思。

watch 的实现过程

首先明确实现后的成果:能监听小程序 page 外面 data 的所有属性值实时的变动。

思路:小伙伴们应该都晓得 vue2.x 中的 双向绑定是通过 Object.defineProperty 办法来实现的。所以咱们微信小程序能够借鉴这一办法。通过遍历 page 里 data 的属性,应用 Object.defineProperty 一一的对每个属性进行监听,发现属性值被批改时就在 set 里调用对应的处理函数。

具体实现代码:

/**
 * 
 * @param {*} data 监听的对象
 * @param {*} watch 听的 key 和回调函数组成的类
 */
export const setWatcher = (data, watch, _this) => { // 接管 page 传过来的 data 对象和 watch 对象
  // 监听属性 并执行监听函数
  const observe = (obj, key, watchFn) => {var val = obj[key]; // 为扭转之前的属性值
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      set: (value) => {
        val = value;
        watchFn.call(_this, value); // 调用对应函数
      },
      get: () => {return val;}
    })
  }
  Object.keys(watch).forEach(v => { // 将 watch 对象内的 key 遍历
    observe(data, v, watch[v]); // 监听 data 内的 v 属性,传入 watch 内对应函数以调用
  })
}

函数有三个入数 datawatch_this;

data 就是咱们监听的对象,在小程序里也就是 page 里的 data

watch 就是一个对象,外面装着以键值对的模式贮存的被监听的各个属性和对应的函数,key 是被监听属性,key 对应的值是这个属性值扭转后的回调函数。

_this 是调用咱们封装的这个函数的环境。

封装完后咱们就能够在 page 页面导入并且应用了

import {setWatcher} from '../../utils/util'

Page({
  data: {
    a: 1,
    b: 2
  }
  async onLoad(options) {setWatcher(this.data, this.watch, this);
  },
  // 监听的值
  watch: {a: function (newValue) {
      // 值扭转后的操作
      console.log(newValue)
    },
    b: function (newValue) {
      // 值扭转后的操作
      console.log(newValue)
    }
  }
})

留神的中央

WXS

  • WXS 函数不能作为组件的事件回调
  • 在 WXS 中是不能调用其余 js 文件的函数和变量的,还有小程序的 API 也不能调用,因为 WXS 的运行环境是和其余 js 代码隔离的。有长处也有毛病吧,速度快,然而不能和其余文件的代码交互。

    watch

  • 封装的时候肯定要用传进来的 this,通过 call 批改 this 指向到函数被调用的 词法环境。否则就调不了 set 中传进来的回调函数.

总结

  • 说 iOS 设施上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。所以像这种订单流水中的一些数据用 WXS 简略实现的相似 vuecomputed 还是比拟有劣势,特地是这种要常常渲染到页面上的数据。
  • 下面代码中用 Object.defineProperty 这种形式封装实现的相似 vuewatch 的形式还有优化的中央,比方 data 中的深层数据扭转时是监听不到的,还需深层次循环遍历。当然也能够借鉴 vue3 中用代理 proxy 的形式来实现。大家还有什么其余更好的形式能够在评论区留言,一起交换交换

写在最初

我是 AndyHu,目前临时是一枚前端搬砖工程师。

文中如有谬误,欢送在评论区斧正,如果这篇文章帮到了你,欢送点赞和关注呀😊

未经许可禁止转载💌

speak less,do more.

退出移动版