Використання міксинів у Vue.js

7 хв. читання

Це звичайна ситуація: у вас є два компоненти, які дуже схожі. У них одна і та сама базова функція, але в кожному з них є достатньо різного для того, щоб ви опинилися на роздоріжжі: чи розбити цей компонент на два окремі компоненти? Чи краще зберегти один компонент, але створити достатню розбіжність із вхідними параметрами, щоб можна було змінити кожен із них?

Ні одне із цих рішень не є ідеальним: розбивши компонент на два, ви ризикуєте (якщо функціональність коли-небудь зміниться) оновити його одразу в двох місцях, руйнуючи передумови DRY. Занадто багато вхідних параметрів можуть привести до безладу й вимагати для використання компоненту розуміння занадто великої кількості контексту, що може дуже сповільнити вас.

Використайте міксини (mixins). Міксини у Vue корисні для написання у функціональному стилі, оскільки, зрештою, функціональне програмування існує для того, щоб робити код зрозумілим, усуваючи «рухомі частини». Міксини дозволяють інкапсулювати одну частину функціональності так, щоб можна було використовувати її в різних компонентах застосунку. Написані правильно міксини є чистими — вони не модифікують і не змінюють нічого поза межами функції, тому при кількох виконаннях з однаковими вхідними даними ви завжди будете отримувати одне й те саме значення.

Основний приклад

Припустімо, у нас є кілька різних компонентів, завдання яких – перемикати стани модального вікна та спливної підказки. Спливні підказки й модальні вікна не мають багато спільного, за винятком цієї функціональності: вони не виглядають однаково, не використовуються однаково, але їх логіка аналогічна.

//modal
const Modal = {
  template: '#modal',
  data() {
    return {
      isShowing: false
    }
  },
  methods: {
    toggleShow() {
      this.isShowing = !this.isShowing;
    }
  },
  components: {
    appChild: Child
  }
}

//tooltip
const Tooltip = {
  template: '#tooltip',
  data() {
    return {
      isShowing: false
    }
  },
  methods: {
    toggleShow() {
      this.isShowing = !this.isShowing;
    }
  },
  components: {
    appChild: Child
  }
}

Ми могли б вилучити логіку та створити щось, що можна використовувати повторно:

const toggle = {
  data() {
    return {
      isShowing: false
    }
  },
  methods: {
    toggleShow() {
      this.isShowing = !this.isShowing;
    }
  }
}

const Modal = {
  template: '#modal',
  mixins: [toggle],
  components: {
    appChild: Child
  }
};

const Tooltip = {
  template: '#tooltip',
  mixins: [toggle],
  components: {
    appChild: Child
  }
};

Цей приклад навмисно залишався малим і простим з ціллю зрозумілості — приклади міксинів, які є корисними у реальних застосунках, включені, але не обмежуються: отриманням розмірів вікна перегляду та компонентів, збиранням конкретних подій mousemove, а також базових елементів діаграм. Є хороший репозиторій міксинів Vue, але варто зазначити, що вони написані в coffeescript.

Використання

Файл, який ми створили, матиме розширення .js (на відміну від .vue, як і інші наші файли). Ми експортуємо об'єкт для міксину:

Використання міксинів у Vue.js

Тоді в Modal.vue ми будемо мати доступ до нього, імпортуючи перемикач як показано нижче:

import Child from './Child'
import { toggle } from './mixins/toggle'

export default {
  name: 'modal',
  mixins: [toggle],
  components: {
    appChild: Child
  }
}

Важливо зрозуміти, що хоча ми використовуємо об'єкт, а не компонент, методи життєвого циклу для нас доступні. Ми можемо приєднатися до mounted(), і він буде застосовуватися до життєвого циклу компоненту, що робить цей спосіб роботи дійсно гнучким та потужним.

Злиття

Розглядаючи останній приклад, можна побачити, що у нас є не тільки функціональність, але і хуки життєвого циклу, доступні нам із міксину. Слід враховувати порядок, застосовуючи його до компонента з перекривними процесами. За замовчуванням, спочатку будуть застосовуватися міксини, другим буде компонент, щоб ми могли його перевизначити, по мірі необхідності. За компонентом останнє слово. Це стає дійсно важливим тільки тоді, коли є конфлікт, і компонент має «вирішити», що переможе, інакше все буде поміщено в масив для виконання, в якому міксин буде першим, компонент — другим.

//mixin
const hi = {
  mounted() {
    console.log('hello from mixin!')
  }
}

//vue instance or component
new Vue({
  el: '#app',
  mixins: [hi],
  mounted() {
    console.log('hello from Vue instance!')
  }
});

//Output in console
> hello from mixin!
> hello from Vue instance!

Якщо ці двоє конфліктують, ми побачимо, як переможе екземпляр або компонент:

//mixin
const hi = {
  methods: {
    sayHello: function() {
      console.log('hello from mixin!')
    }
  },
  mounted() {
    this.sayHello()
  }
}

//vue instance or component
new Vue({
  el: '#app',
  mixins: [hi],
  methods: {
    sayHello: function() {
      console.log('hello from Vue instance!')
    }
  },
  mounted() {
    this.sayHello()
  }
})

// Output in console
> hello from Vue instance!
> hello from Vue instance!

Ви можете помітити, що у нас два console.log для рядка екземпляра Vue замість одного. Це тому що перша викликана функція не була знищена, а була перевизначена. Ми все ще викликаємо обидві функції за допомогою sayHello().

Глобальні міксини

Коли ми використовуємо термін «глобальний» у відношенні міксинів, ми не маємо на увазі можливість доступу до них з кожного компоненту. Ми вже можемо отримати доступ до наших міксинів у компоненті з mixins: [toggle].

Глобальні міксини буквально застосовуються до кожного окремого компонента. З цієї причини їх використання є надзвичайно обмеженим, і їх слід розглядати з великою обережністю. Одне з використань, яке має сенс, — щось на зразок плагіна, де вам може знадобитися отримати доступ до всього. Але, знову ж таки, навіть у цьому прикладі, слід остерігатися того, що ви застосовуєте, особливо якщо ви розширюєте функціональність для застосунків, які можуть бути для вас чорним ящиком.

Щоб створити глобальний екземпляр, ми розмістимо його над екземпляром Vue. У типовій збірці Vue-cli це буде в файлі main.js.

Vue.mixin({
  mounted() {
    console.log('hello from mixin!')
  }
})

new Vue({
  ...
})

Знову-таки, користуйтесь цим з обережністю. Тепер console.log з'явиться у кожному окремому компоненті. В цьому випадку це не так і погано, але ви можете побачити, наскільки потенційно шкідливим може це бути, якщо буде використано неправильно.

Висновок

Міксини можуть бути корисними для інкапсуляції невеликої частини функціональності, яку ви хочете використовувати повторно. Вони, звичайно, не єдиний доступний вам варіант: компоненти вищого порядку, наприклад, дозволяють створювати подібні функції. Це лише один зі способів роботи. Міксини чудові тим, що не потрібно передавати стани. Цим патерном бажано не зловживати, тому будьте обережні й краще подумайте, використання якого варіанту підходить для вашого застосунку.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.6K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація