手写Mixins

144 阅读1分钟


进去之前介绍了Mixins怎么使用。
今天突发奇想,要不手写一个吧。

效果

先展示下实现效果:
动画113.gif 其中bb以及aa等属性是我Mixins进去的

实现

先来看首页代码

image.png

细心的朋友可以看到我定义了一个connect方法,然后里面第二个参数内容就是vue文件原来导出的对象

{
  name: "HomeView",
  data() {
    return {
      data: 211321,
    };
  },
  aa: 11,
}

没错我定义了一个connect方法,通过先拦截了一波vue文件原来导出的对象,然后在这里面做了mixins数据融合的操作,再返回这个对象实现。

看看connect方法是咋写的

export function connect(input = {}, params) {
  let inputKeys = Object.keys(input);
  for (let index = 0; index < inputKeys.length; index++) {
    // 没有就新加
    if (!params[inputKeys[index]]) {
      params[inputKeys[index]] = input[inputKeys[index]];
    } else {
      // data 特殊,需要先获取实际内容再拼接
      if (inputKeys[index] == "data") {
        let paramsdata = params.data();
        let inputdata = input.data();
        params.data = () => {
          return Object.assign(inputdata, paramsdata);
        };
      } 
      // 如果是函数就覆盖
      else if (
        Object.prototype.toString.call(params[inputKeys[index]]) ===
        "[object Function]"
      ) {
        params[inputKeys[index]] = input[inputKeys[index]];
      } 
       // 如果是数组,则合并去重
      else if (Array.isArray(params[inputKeys[index]])) { 
        params[inputKeys[index]] = [
          ...new Set(
            ...[...params[inputKeys[index]], ...input[inputKeys[index]]]
          ),
        ];
      }
      // 如果是对象, 先把原改成map然后一个一个往map里面加,保证key唯一,然后map再转对象即可
      else if (params[inputKeys[index]]?.constructor === Object) {
        let paramsMap = new Map(Object.entries(params[inputKeys[index]]));
        let paramsKeysMinis = Object.keys(params[inputKeys[index]]);
        for (let i = 0; i < paramsKeysMinis.length; i++) {
          paramsMap.set(
            paramsKeysMinis[i],
            params[inputKeys[index]][paramsKeysMinis[i]]
          );
        }
        params[inputKeys[index]] = Object.fromEntries(paramsMap.entries());
      }
      // 基本数据类型,直接赋值
      else {
        params[inputKeys[index]] = input[inputKeys[index]];
      }
    }
  }
  return params;
}

在这里我拦截了一下vue导出的对象,将它和需要mixins的数据进行比较,如果是原来不存在的就插入,存在的就按照各个类型进行覆盖。


具体使用如下所示:

// 导入自定义mixins方法
import { connect } from "../minis/connect";
// 导入需要mixins的数据
import input from "../minis/minis";
// 调用connect方法对数据进行处理,并返回处理后的数据
export default connect(input, {
  name: "HomeView",
  data() {
    return {
      data: 211321,
    };
  },
  aa: 11,
});