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