Миксины предсталяют способ передачи функциональности из одной сущности в другую, аналогичный наследованию. Миксин может содержать любые свойства. Если компонент использует миксин, то все свойства миксина добавляются к свойствам данного компонента.
Допустим у нас есть два компонента:
<!DOCTYPE html> <html> <head> <title>Компоненты Vue 3</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <light></light> <enabled></enabled> </div> <script src="https://unpkg.com/vue"></script> <script> const app = Vue.createApp({}); app.component('light', { template: `<div><h3>{{header}}</h3> <button v-on:click="toggle" v-show="state">{{on}}</button> <button v-on:click="toggle" v-show="!state">{{off}}</button> </div>`, data(){ return { state: true, on: "ON", off: "OFF"} }, methods:{ toggle(){ this.state= !this.state; } }, computed:{ header(){ return this.state==true?"Свет включен":"Свет выключен"; } } }); app.component('enabled', { template: `<div>Состояние: {{ state?"доступ открыт":"доступ закрыт" }} <button v-on:click="toggle" v-show="state">{{on}}</button> <button v-on:click="toggle" v-show="!state">{{off}}</button> </div>`, data(){ return { state: true, on: "ON", off: "OFF"} }, methods:{ toggle(){ this.state= !this.state; } } }); app.mount('#app'); </script> </body> </html>
Здесь определено два компонента. Функциональность обоих компонентов в некоторых моментах сходится. И весь этот общий функционал можно вынести в миксин:
<div id="app"> <light></light> <enabled></enabled> </div> <script src="https://unpkg.com/vue"></script> <script> const toggleMixin = { data(){ return { state: true, on: "ON", off: "OFF"} }, methods:{ toggle(){ this.state= !this.state; } }, }; const app = Vue.createApp({}); app.component('light', { template: `<div><h3>{{header}}</h3> <button v-on:click="toggle" v-show="state">{{on}}</button> <button v-on:click="toggle" v-show="!state">{{off}}</button> </div>`, mixins:[toggleMixin], computed:{ header(){ return this.state==true?"Свет включен":"Свет выключен"; } } }); app.component('enabled', { template: `<div>Состояние: {{ state?"доступ открыт":"доступ закрыт" }} <button v-on:click="toggle" v-show="state">{{on}}</button> <button v-on:click="toggle" v-show="!state">{{off}}</button> </div>`, mixins:[toggleMixin] }); app.mount('#app'); </script>
Теперь общий код вынесен в отдельный объект - миксин toggleMixin. С помощью параметра mixins миксин передается компоненту:
mixins:[toggleMixin]
Данный параметр представляет массив, поэтому мы можем передать несколько миксинов. В итоге функциональность миксина будет объединяться с функциональностью, которая определена непосредственно в компоненте. А результат работы кода будет тот же самый, что и в предыдущем примере.
И если потребуется изменить логику нажатия кнопок обоих компонентов, достаточно это будет сделать в одном месте - в миксине.
Следует отметить, что если миксины и компоненты определяют методы и свойства с одним и тем же именем, то подобная функциональность миксинов отбрасывается.
Vue 3 позволяет задавать миксины глобально, то есть сразу для всех компонентов. Для этого используется метод mixin() объекта приложения Vue:
<!DOCTYPE html> <html> <head> <title>Компоненты Vue 3</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <message></message> </div> <script src="https://unpkg.com/vue"></script> <script> const app = Vue.createApp({}); app.component('message', { template: `<h2>Hello</h2>` }); app.mixin({ created() { console.log("Global mixin has been created"); } }) app.mount('#app'); </script> </body> </html>
В данном случае глобальный миксин использует событие created и выводит на консоль браузера строку:
Поскольку в данном случае определен один компонент и объект приложения Vue, то глобальный миксин будет вызываться два раза.