0
点赞
收藏
分享

微信扫一扫

CSS画特殊边框

小_北_爸 2023-07-05 阅读 31

mixin 会带来什么问题

Vue2 中可以使用 mixin 来封装可复用的逻辑,它可以向一个对象注入另一个对象的所有属性,这让它非常灵活,但是同时也带来了一些问题:

  • 来源不明:使用的 mixin 越多,越难找到某个属性或方法来自哪里。
  • 无法精确引入:引入一个 mixin 时,会引入这个 mixin 的全部属性,因此可能会引入一些用不到的东西,也很难清楚知道到底引入了什么内容。
  • 命名冲突:因为是将两个对象合并,所以可能会遇到命名冲突的问题。

如何解决上述的问题

可以转变 mixin 引入的方式,传统的 mixin 都是直接引入一个对象,我们可以封装一个函数来生成需要引入的 mixin 对象,通过参数来控制要引入的变量名、方法名。

示例一:鼠标跟踪器

实现一个鼠标跟踪功能,获取鼠标当前的 x、y 坐标,并将这个功能封装到 mixin 中。

先来看看期望中引入 mixin 的方式:

<template>
  <div>{{ posX }}-{{ posY }}</div>
</template>

<script>
import { mousePosition } from "./mixin/mouse";
export default {
  mixins: [
    mousePosition({
      x: "posX",
      y: "posY",
    }),
  ],
};
</script>

这里引入了一个 mousePosition 的方法,这个方法的返回值是一个 mixin 对象,通过参数告诉 mousePosition 方法用 posX 来接收 x 、用 posY 来接收 y

mousePosition 的实现如下:

const defaultOption = {
  x: "x",
  y: "y",
};
export function mousePosition(option = defaultOption) {
  const xKey = option.x;
  const yKey = option.y;
  const data = {
    [xKey]: 0,
    [yKey]: 0,
  };
  document.addEventListener("mousemove", (event) => {
    data[xKey] = event.clientX;
    data[yKey] = event.clientY;
  });
  return {
    data() {
      return data;
    },
  };
}

示例二:公共表单逻辑

有这样一个业务场景:一个表单需要展现不同的样式,这种场景下可以将表单的逻辑部分封装到 mixin 中,只在组件中重写样式即可。

先看看引入方式:

<template>
  <div>
    <div>
      <span>姓名:</span>
      <input type="text" v-model="customerName" />
    </div>
    <div>
      <span>电话:</span>
      <input type="text" v-model="customerPhone" />
    </div>
    <button @click="onSubmit">提交</button>
  </div>
</template>

<script>
import { formCore } from "./mixin/form";
export default {
  mixins: [
    formCore({
      name: "customerName",
      phone: "customerPhone",
      onSubmit: "onSubmit",
    }),
  ],
};
</script>

<style scoped>
@import "@/styles/components/formV1.css";
</style>

对于不同的组件,只需要重写 template 和 style 即可。

mousePosition 的实现如下:

const defaultOption = {
  name: "name",
  phone: "phone",
  onSubmit: "onSubmit",
};

export function formCore(option = defaultOption) {
  const nameKey = option.name;
  const phoneKey = option.phone;
  const onSubmitKey = option.onSubmit;
  const data = {
    [nameKey]: "",
    [phoneKey]: "",
  };

  const methods = {};

  if (onSubmitKey) {
    methods[onSubmitKey] = function () {
      const valid = () => {
        if (!this[nameKey]) {
          alert("请输入姓名");
          return false;
        }
        if (!this[phoneKey]) {
          alert("请输入电话");
          return false;
        }
        return true;
      };
      const validResult = valid();
      if (validResult) {
        alert(`${this[nameKey]}-${this[phoneKey]}`);
      }
    };
  }

  return {
    data() {
      return data;
    },
    methods,
  };
}

参考

我可能发现了 Vue Mixin 的正确用法——动态 Mixin

举报

相关推荐

0 条评论