Mixin

6/25/2022

# Mixin

# 什么是Mixin

  • mixin是一种简化代码的方法,能提高代码的重复使用率。在css,js,vue里面都有用到。(起因也是面试被问了这个知识盲区刚好来补充一下)
  • Mixin模式有助于提高函数复用,减少系统代码的重复度。当一个程序在各个对象中共享属性和行为时,我们可以考虑使用Mixin模式。但Mixin模式 也有自己的缺点,有些人认为将功能注入对象原型中的操作会导致原型污染和函数起源方面的不确定性等方面的问题,所以在使用时需要衡量利弊来做出选择。

# CSS中的mixin

  • css中,用@mixin定义,@include引用
/* 定义 */
@mixin hexagon-generator($hexagon-width, $factor, $border-radius) {
    display: inline-block;
    border-radius: 50%;
    width: ($hexagon-width + $border-radius) * $factor;
    height: ($hexagon-width + $border-radius) * $factor;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 引用 */
.hexagon-shape {
    @include hexagon-generator(88rpx, 1, 8rpx)
}

/* 编译后是这样的 */
.hexagon-shape {
    display: inline-block;
    border-radius: 50%;
    width: (88rpx + 8rpx) * 1;
    height: (88rpx + 8rpx) * 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# js中的Mixin

  • 在js中的mixin更多的是写可以复用的函数,提高函数的复用性(一般用class写),将一个对象的全部或者部分拷贝到另一个对象上去
  • 与Object.assign的不同: 一个是mixin可以指定混入source对象总的部分属性,只会混入指定的属性,其它不处理;二是优先级不同,assign中源对象属性优先级更高。
function Car(model=null, color='') {
    this.model = model;
    this.color = color;
}
function CarMove() {
    CarMove.prototype.run = function () {
        console.log('car has stoped')
    }
}
// 编写mixin,将source对象中的方法混入到origin对象中去
// 在mixin函数中,源对象属性的优先级更高,如果源对象和目标对象同时含有某个属性,目标对象中的属性会覆盖源对象中的属性。
function mixin(origin ,source, ...rest) {
    const restLen = rest.length;
    if(restLen) {
        for(let i=0; i<restLen; i++){
            origin.prototype[rest[i]] = source.prototype[rest[i]];
        }
    } else {
        for(let method in source.prototype) {
            if(!Reflect.has(origin.prototype, method)) {
                origin.prototype[method] = source.prototype[method]
            }
        }
    } 
}
// 测试
mixin(Car, CarMove, 'run')
console.log(Car.prototype);     // {run: [Function(anoymous)]}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# Vue中的mixin

  • 这个在开发中很常见了,有全局混入和局部混入两种。
  • 注意生命周期,混入对象的钩子将在组件自身钩子之前调用。(也是面试的一个考点)
  • 具体使用看这个 (opens new window)
  • 和vuex的区别
    • vuex是状态共享的,mixin中的数据是不共享的(但可以定义公用的变量or方法),数据是互不影响的
    • mixin混入对象值为函数的同名函数会进行递归合并为数组,两个都会执行,但先执行mixin中的同名函数
    • 混入对象值为对象的同命对象则会替换,有限执行组件内的同命对象,组件内的对象会覆盖mixin中的对象
  • 那么公共组件和mixin又有什么区别呢?
    • 组件相当于在父组件开出来一个独立空间给子组件使用,根据props传值;本质亮着是相对独立的
    • mixin是引入组件后与组件中的对象、方法进行合并,相当于是对父组件的扩展,可以理解为形成了新的组件。