tangyuxian
文章79
标签37
分类5
微信小程序-使用mixin混入

微信小程序-使用mixin混入

本文用于实现微信小程序的mixin使用

mixin理解

本意就是混入的意思,利用语言特性进行组合式操作.

如果你对vue中的mixin有所了解,那么对mixin一定不会陌生,如果您使用过java语言,那么它解决多重继承 带来复杂继承链的问题,或者说是多重继承实现的一种技巧.

微信小程序中的mixin理解

了解过vue中的混入思路,我们可以将之转化到微信小程序中,可以劫持Page或者Component,改写函数并最终释放出来

完整代码

// 保存原生的 Page 函数
const originPage = Page
const originComponent = Component
Page = (options) => {
  const mixins = options.mixins
  // mixins 必须为数组
  if (Array.isArray(mixins)) {
    delete options.mixins
    // mixins 注入并执行相应逻辑
    options =  merge(mixins, options)
  }
  // 释放原生 Page 函数
  originPage(options)
}
Component = (options) => {
  const mixins = options.mixins
  // mixins 必须为数组
  if (Array.isArray(mixins)) {
    delete options.mixins
    // mixins 注入并执行相应逻辑
    options = merge(mixins, options)
  }
  // 释放原生 Component 函数
  originComponent(options)
}

// 定义小程序内置的属性/方法
const originProperties = ['data', 'properties', 'options', 'methods','observers']
const originMethods = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap']

function merge(mixins, options) {
  mixins.forEach((mixin) => {
    if (Object.prototype.toString.call(mixin) !== '[object Object]') {
      throw new Error('mixin 类型必须为对象!')
    }
    // 遍历 mixin 里面的所有属性
    for (let [key, value] of Object.entries(mixin)) {
      if (originProperties.includes(key)) {
        // 内置对象属性混入
        options[key] = {
          ...value,
          ...options[key]
        }
      } else if (originMethods.includes(key)) {
        // 内置方法属性混入,优先执行混入的部分
        const originFunc = options[key]
        options[key] = function (...args) {
          value.call(this, ...args)
          return originFunc && originFunc.call(this, ...args)
        }
      } else {
        // 自定义方法混入
        options = {
          ...mixin,
          ...options
        }
      }
    }
  })
  return options
}

使用方法

可将其命名为mixin.js存入项目的utils或者core中作为工具;

app.js顶部引入

//app.js
import './utils/mixins.js'

可在项目根目录创建common/mixins文件夹,用于存放各种mixin文件

Page的mixin定义风格如下:

//listMixin.js
module.exports = {
  data: {
    list: [],
    page: 1, //页数
    limit: 10, //每页最大数
    lastPage: false, //是否为最后一页
    isUpload: false, //是否在加载,
  },
   /**
   * 监听滚动到底部
   */
  scrolltolower(e) {
    console.log("滚动到底部", e);
    if (!this.data.lastPage && !this.data.isUpload) {
      this.getList() //由被混入的文件实现getList()函数
    };
  }
}

使用方法如下:

Page({
  mixins: [require('/common/mixins/ListMixin.js')]
})

Component的mixin定义风格如下:

//componentListMixin.js
module.exports = {
  data: {},
  /**
   * 组件的属性列表
   */
  properties: {
    //数据集合
    list:{
      type:Array,
      value:[]
    },
  },
  methods:{
     /**
     * 选择某项
     */
    chooseItem(event){
      let item = event.currentTarget.dataset.cap;
      this.triggerEvent('onChoose', item, {})
    }
  }
 }

使用方法如下:

Component({
  mixins: [require('/common/mixins/componentListMixin.js')]
})

功能实现参考了此篇文章,并对存在的问题进行修正

本文作者:tangyuxian
本文链接:https://www.tangyuxian.com/2021/02/20/%E5%89%8D%E7%AB%AF/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F-%E4%BD%BF%E7%94%A8mixin%E6%B7%B7%E5%85%A5/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可