vue2之mixin混入

139 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

混入

概念

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

功能

混入可以将多个组件中的公共配置提取成一个混入对象。这样就可以实现代码的复用。

语法

混入和过滤器等配置类似,也有两种使用方式:全局混入和局部混入。

首先注册一个mixin对象

const mixin = {
  data() {
    return {
      mixinData: {
        name: '儿子',
        msg: '我是你爸爸'
      }
    };
  },
  created() {
    console.log('混入的created');
  },
  methods: {
    sayHello() {
      console.log('我是混入的sayHello');
    }
  }
};

export default mixin;

1. 全局混入

Vue.mixin(mixin)

参数

其中参数mixin是一个对象,里面包含混入的所有组件配置。

说明

全局注册一个混入,影响注册之后所有创建的每个 Vue 实例。使用混入可以向组件注入自定义的行为。但是不推荐在应用代码中使用

使用方法

在main.js中全局混入

import mixin from './mixin/data';

Vue.mixin(mixin);

组件中使用

<template>
  <div class="hello">
    <button @click="sayHello">点我打印信息</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
    }
  }
}
</script>

这样所有组件就能使用混入配置了。效果如下:

image.png

说明

上面效果图中打印了三遍是因为使用的组件是个子组件,它的父组件也加载了created方法。因此mixin在实际生产环境中不建议使用全局混入。

2. 局部混入

将定义好的混入对象引入要用的组件。它和全局混入的方式不同的是,它不需要在main.js中引入。

语法

mixins: [mixin]

参数说明 同全局混入一样,其中参数mixin是一个对象,里面包含混入的所有组件配置。

使用方法 在组件中引入并使用

<template>
  <div class="hello">
    <button @click="sayHello">点我打印信息</button>
  </div>
</template>

<script>
import mixin from '../mixin/data';
export default {
  name: 'HelloWorld',
  mixins: [mixin],
  data() {
    return {
    }
  }
}
</script>

效果如图:

image.png

混入规则

  1. 数据对象内部,如果是基本类型的变量,那么组件中变量会覆盖混入中定义的变量。如果是引用数据类型,在内部会进行递归合并,并在发生冲突时以组件数据优先。
// 混入组件
const mixin = {
  data() {
    return {
      name: '儿子',
      msg: {
        name: '刘亦菲',
        age: 16
      }
    };
  },
  created() {
    console.log('混入的created');
  },
  methods: {
    sayHello() {
      console.log('我是混入的sayHello');
    }
  }
};

export default mixin;

// 组件
<template>
  <div class="hello">
    <button @click="sayHello">点我打印信息</button>
    <p>{{name}}</p>
    <p v-for="(item, index) in msg" :key="index">{{item}}</p>
  </div>
</template>

<script>
import mixin from '../mixin/data';
export default {
  name: 'HelloWorld',
  mixins: [mixin],
  data() {
    return {
      name: '女儿',
      msg: {
        name: '张雨彤',
        title: '我是乖乖女'
      }
    }
  }
}
</script>

效果如下:

image.png

  1. 生命周期钩子冲突时,会执行两遍,先执行混入中的,然后执行组件中的。

    混入配置同上

    // 组件
    <template>
      <div class="hello">
        <button @click="sayHello">点我打印信息</button>
        <p>{{name}}</p>
        <p v-for="(item, index) in msg" :key="index">{{item}}</p>
      </div>
    </template>
    
    <script>
    import mixin from '../mixin/data';
    export default {
      name: 'HelloWorld',
      mixins: [mixin],
      data() {
        return {
          name: '女儿',
          msg: {
            name: '张雨彤',
            title: '我是乖乖女'
          }
        }
      },
      created() {
        console.log('组件的created');
      }
    }
    </script>
    

    效果如下:

image.png

  1. 值为对象的其他配置,比如methods等,会合并成一个对象,然后取组件中的键值执行。

    混入配置同上

    // 组件
    <template>
      <div class="hello">
        <button @click="sayHello">点我打印信息</button>
        <p>{{name}}</p>
        <p v-for="(item, index) in msg" :key="index">{{item}}</p>
      </div>
    </template>
    
    <script>
    import mixin from '../mixin/data';
    export default {
      name: 'HelloWorld',
      mixins: [mixin],
      data() {
        return {
          name: '女儿',
          msg: {
            name: '张雨彤',
            title: '我是乖乖女'
          }
        }
      },
      created() {
        console.log('组件的created');
      },
      methods: {
        sayHello() {
          console.log('我是组件的sayHello');
        }
      }
    }
    </script>
    

    效果如下:

image.png