聊聊mixins

367 阅读4分钟

聊聊mixins

前言

mixins在我们日常开发中用的算多了,如果有啥公共的逻辑的话,有时候我们就会放到mixins里面。

但是我刚开始写项目的时候还是被这个突如其来的“新东西”吓了一跳。

介绍

mixins即混入,mixins是个包含任意组件选项的对象,即这个对象可以存放包括data,methods等内容。

举个例子:

export default {
    data() {
        return {
            num: 1
        }
    },
    methods: {
        numAdd(val, o_val) {
            return val + o_val
        }
    }
};

上面就是一个mixins对象。

重点:当你的组件引入mixins时,mixins对象的组件选项也会混入到你的组件选项中,即你组件原本内部也存在data等方法属性,当你引入mixins之后这些属性就会合并,相当于你组件里面的方法属性被扩充了。

使用

创建一个新的vue文件,命名为Mixins.vue

代码如下:

<template>
  <div>Mixins 测试 {{ num }}</div>
</template>

<script>
export default {
  data() {
    return {
      num: 1,
    };
  },
  methods: {
    numAdd(val, o_val) {
      return val + o_val;
    },
  },
};
</script>

效果如图:

image.png

创建一个mixins对象文件,命名为text.js

const mixinsObj = {
  data() {
    return {
      new_num: 200,
    };
  },
  methods: {
    numAddNew(val, o_val) {
      return val + o_val + 1;
    },
  },
};
export default mixinsObj;

使用mixins的时候将其引入组件中即可,如:

<template>
  <div>Mixins 测试 {{ num }}--{{ new_num }}</div>
</template>

<script>
import mixinsObj from "./mixins/test"; // 导入mixins对象
export default {
  mixins: [mixinsObj], // mixins混入  
  ...
};
</script>

效果如下:

image.png

可以看到200这个参数已经在组件中被使用了。

这就是mixins的使用方法。

注意

看完上面的介绍是不是觉得mixins很容易使用呢?

往往容易使用的东西需要注意的点也就越多,下面就是我平时会遇到的一些mixins的坑。

同名变量

mixins可以抽离公共的变量及逻辑方法,那就会涉及到方法参数重名的问题。

实践出真理,依然是上面的代码,我们将data及methods的参数名或方法名改成和组件内部一致

代码如下:

const mixinsObj = {
  data() {
    return {
      num: 200,
    };
  },
  methods: {
    numAdd(val, o_val) {
      return val + o_val + 1;
    },
  },
};

同时我们也要更新组件内容,如下所示:

<template>
  <div>Mixins 测试 {{ num }}--{{ numAdd(1, 2) }}</div>
</template>

代码执行:

image.png

通过上图显示mixins的obj中的数据均被组件内部覆盖。

因此,mixins第一个特点是:mixinsObj的参数和组件参数同名的情况下,组件会把mixins的参数给覆盖。

数据共享

通过上文我们可以发现mixins是不是和vuex有一点点像,都是拿公共的东西嘛

接下来我们就来看看mixins有没有数据共享这回事。

首先我们要创建两个组件,A和B,两个组件同时引入mixins对象。

修改所属A下的mixins对象的num,我们改A之后B会不会改变呢?

将原组件改成如下所示,同时引入A和B组件:

<template>
  <div>
    <div><A /></div>
    <p />
    <div><B /></div>
  </div>
</template>

<script>
import A from "./A";
import B from "./B";
export default {
  components: { A, B },
};
</script>

A组件,如下所示:

<template>
  <div>Mixins 测试 {{ num }}--{{ numAdd(1, 2) }}--{{ getThis() }}</div>
</template>

<script>
import mixinsObj from "./mixins/test";
export default {
  mixins: [mixinsObj],
  created() {
    this.num = this.num + 1;
  },
};
</script>

B组件,如下所示:

<template>
  <div>Mixins 测试 {{ num }}--{{ numAdd(1, 2) }}--{{ getThis() }}</div>
</template>

<script>
import mixinsObj from "./mixins/test";
export default {
  mixins: [mixinsObj],
};
</script>

可以看到我在原组件中同时 引入了A和B,然后A组件在生命周期中更改了num的值,假如二者数据共享则A组件和B组件的展示会一致。

看看效果:

image.png

由于mixins的num值为200,图上可知,A组件的num已经加1 而B组件还是原来的200

可以知道,mixins第二个特点是:mixins定义了共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。

mixins的this

我们平时开发vue项目的时候,常常会使用到this,大家也知道vue组件中这个this指向的是使用它的vue实例。

突发奇想,如果我在mixins中使用this还可以正常使用吗?

代码如下(组件侧):

(1)引入mixins对象的getThis方法

<template>
  <div>Mixins 测试 {{ num }}--{{ numAdd(1, 2) }}--{{ getThis() }}</div>
</template>

<script>
import mixinsObj from "./mixins/test";
export default {
  mixins: [mixinsObj],
  data() {
    return {
      num: 1,
    };
  },
  methods: {
    numAdd(val, o_val) {
      return val + o_val;
    },
  },
};
</script>

代码如下(mixins对象):

(1)getThis方法中返回num,同时打印this

methods: {
    ...
    getThis() {
      console.log(this);
      return this.num;
    },
  },

效果如下:

image.png

成功返回当前组件的data下的num,并且打印的调用它的vue实例。

可知,mixins第三个特点是:mixins会混入当前组件,而mixins中的this值指向的就是当前调用这个组件的vue实例,可正常使用。

注意

mixinsObj的参数和组件参数同名的情况下,组件会把mixins的参数给覆盖。
mixins定义了共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
mixins中的this值指向的就是当前调用这个组件的vue实例,可正常使用。

补充

注:mixins和vuex还是差别很大的,mixins可以定义共用变量,各个变量互不干扰,而vuex则是用于状态管理,数据可以在各个组件间修改,并非独立。