3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Vue.js】ミックスインでコンポーネントオプションを追加する

Last updated at Posted at 2019-09-15

ミックスインとは

  • オプションを他のコンポーネントに混ぜ込む(マージする)機能
  • 複数のコンポーネントで共通の処理を実行したい場合に使える
  • ミックスインオブジェクトとコンポーネントの定義がコンフリクトした場合は、コンポーネントのデータが優先される
  • フック(createdなど)は、ミックスインに定義されているものから先に呼び出される
  • 1つのコンポーネントから複数のミックスインオブジェクトを呼び出すことも可能
  • 複数のミックスインオブジェクト同士で定義がコンフリクトしている場合は、後で呼び出されているオブジェクトの定義が優先される
  • 上記の場合、createフックは先に呼び出されているミックスインオブジェクトから実行される

補足

extendとdataオプション

extendを使用する場合、extendしたいオブジェクトのdataオプションの記述方法が少し異なります。

この記述方法だとエラーが発生します。

vue_mixin_test.html
<script>
data: {
    foo: 'abc',
    message: 'hello'
},
</script>
[Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.

メッセージの通り、dataオプションをfunctionで返せば問題ありません。
以下の記述方法はextendを使用しない場合も使えるので、こちらの方が無難かもしれません。

vue_mixin_test.html
<script>
data: function () {
    return {
        foo: 'abc',
        message: 'hello'
    }
},
</script>

公式サイトにも説明があります。

コンポーネントオプション〜データ

ライフサイクルフック

createdフックなど、インスタンス生成時に初期化として実行される関数のことです。

ミックスインオブジェクトに定義されているフック関数は、コンポーネントのフック関数より先に呼び出されます。
ミックスインオブジェクトはこの時点で既にマージされているので、定義がコンポーネントとコンフリクトしている場合は、コンポーネントのデータが呼び出されます。

Vue インスタンス〜インスタンスライフサイクルフック

フック関数は複数あり、それぞれ実行されるタイミングが異なります。

Vue インスタンス〜ライフサイクルダイアグラム

ソースコード

公式サイトからお借りしました。

vue_mixin_test.html
<!DOCTYPE>
<head>
  <meta charset="UTF-8">
  <title>Vue.js_mixin_test</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <script>
      var mixin = {
          data: function () {
              return {
                  hoge: 'hoge',
                  foo: 'abc',
                  // 重複するプロパティ
                  message: 'hello'
              }
          },
          methods: {
              fooMethod: function () {
                  console.log('foo')
              },
              // 重複するメソッド
              conflicting: function () {
                  console.log('from mixin')
              }
          },
          // this.$dataはmixinがマージされた後の状態で表示される
          created: function () {
              console.log('mixin', this.$data)
              this.fooMethod()
              this.conflicting()
          }
      }

      var mixin2 = {
          data: function () {
              return {
                  foo: 'abc2',
                  message: 'hello2'
              }
          },
          methods: {
              fooMethod: function () {
                  console.log('foo2')
              },
              conflicting: function () {
                  console.log('from mixin2')
              }
          },
          created: function () {
              console.log('mixin2', this.$data)
              this.fooMethod()
              this.conflicting()
          }
      }

      // 複数のmixinを呼び出すことも可能
      var Component = Vue.extend({
          mixins: [mixin, mixin2]
      })

      new Component()

      var vm = new Vue({
          // mixinをマージする
          mixins: [mixin],
          // mixinと定義が重複している場合、コンポーネントのデータが優先される
          data: function () {
              return {
                  bar: 'def',
                  // 重複するプロパティ
                  message: 'goodbye'
              }
          },
          methods: {
              barMethod: function () {
                  console.log('bar')
              },
              // 重複するメソッド
              conflicting: function () {
                  console.log('from self')
              }
          },
          created: function () {
              console.log('self', this.$data)
              this.barMethod()
              this.conflicting()
          }
      })

      vm.fooMethod()
      vm.barMethod()
      vm.conflicting()
  </script>
</body>
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?