### 彪哥

爱好前端

- 基础

- 组件

- 过渡&动画

- 可复用性&组合

  - Mixin混入
    - 基础
    - 选项合并
    - 某项目中使用的Mixin示例

- 工具

- 规模化

- Vuex

- 其他

- 《Vue》笔记
- 可复用性&组合

heBody
2020-02-19
目录

# Mixin混入

# # Mixin混入

## # 基础

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

> 组件选项：指的是组件对象中的 `data`、`created`、`methods` 等等选项。

> 可通过 `this.$options` 查看选项

例子：

    // 定义一个混入对象
    var myMixin = {
      created: function () {
        this.hello()
      },
      methods: {
        hello: function () {
          console.log('hello from mixin!')
        }
      }
    }

    // 定义一个使用混入对象的组件
    var Component = Vue.extend({
      mixins: [myMixin]
    })

    var component = new Component() // => "hello from mixin!"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

通俗讲，就是把组件的部分代码抽离出来，再"混合"进入组件。当多个组件有相同的选项代码时，可以把相同的选项代码抽离到一个文件，再混入到每个组件，从而达到共享部分代码的目的。

## # 选项合并

当组件和混入对象含有同名选项时，这些选项将以恰当的方式进行“合并”。

比如，数据对象在内部会进行递归合并，并在发生冲突时以组件数据优先。

    var mixin = {
      data: function () {
        return {
          message: 'hello',
          foo: 'abc'
        }
      }
    }

    new Vue({
      mixins: [mixin],
      data: function () {
        return {
          message: 'goodbye',
          bar: 'def'
        }
      },
      created: function () {
        console.log(this.$data)
        // => { message: "goodbye", foo: "abc", bar: "def" }
        // message同名，组件数据优先，而foo被混入
      }
    })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

同名钩子函数将合并为一个数组，因此都将被调用。另外，混入对象的钩子将在组件自身钩子之前调用。

    var mixin = {
      created: function () {
        console.log('混入对象的钩子被调用')
      }
    }

    new Vue({
      mixins: [mixin],
      created: function () {
        console.log('组件钩子被调用')
      }
    })

    // => "混入对象的钩子被调用"
    // => "组件钩子被调用"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

值为对象的选项，例如 `methods`、`components` 和 `directives`，将被合并为同一个对象。两个对象键名冲突时，取组件对象的键值对。

    var mixin = {
      methods: {
        foo: function () {
          console.log('foo')
        },
        conflicting: function () {
          console.log('from mixin')
        }
      }
    }

    var vm = new Vue({
      mixins: [mixin],
      methods: {
        bar: function () {
          console.log('bar')
        },
        conflicting: function () {
          console.log('from self')
        }
      }
    })

    vm.foo() // => "foo"
    vm.bar() // => "bar"
    vm.conflicting() // => "from self"

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

注意：`Vue.extend()` 也使用同样的策略进行合并。

## # 某项目中使用的Mixin示例

抽离各组件相同的代码：

    // mixin.js
    export const playlistMixin = {
      computed: {
        ...mapGetters([
          'playlist'
        ])
      },
      mounted() {
        this.handlePlaylist(this.playlist)
      },
      activated() {
        this.handlePlaylist(this.playlist)
      },
      watch: {
        playlist(newVal) {
          this.handlePlaylist(newVal)
        }
      },
      methods: {
        // 根据选项合并策略，此方法和组件中的方法同名时，则被覆盖。如组件中没有相同名称方法时则会使用此方法，从而抛出错误。
        handlePlaylist() {
          throw new Error('component must implement handlePlaylist method')
        }
      }
    }

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

混入到组件：

    // 使用，可在多个组件中共用mixin的代码
    import { playlistMixin } from '@/common/js/mixin' // 共享代码的引入
    export default {
        mixins: [playlistMixin],
        methods: {
            handlePlaylist(playlist) { // 此方法可针对不同组件做不同处理
                ...
            }
        }
    }

1
2
3
4
5
6
7
8
9
10
编辑
(opens new window)
#Vue
上次更新: 2022/12/14, 19:36:42
transition-group列表过渡
Vue CLi v3 创建项目使用记录

← transition-group列表过渡 Vue CLi v3 创建项目使用记录→

最近更新

  01
Git修改分支名
08-11

  02
CSS给table的tbody添加滚动条
06-29

  03
我做了一个手写春联小网页，祝大家虎年暴富 原创
01-28

更多文章>

Copyright © 2016-2022 Hesb | MIT License

- 跟随系统
- 浅色模式
- 深色模式
- 阅读模式