Миксины

Последнее обновление: 12.10.2017

Миксины предсталяют способ передачи функциональности из одной сущности в другую, аналогичный наследованию. Миксин может содержать любые свойства. Если компонент использует миксин, то все свойства миксина добавляются к свойствам данного компонента.

Допустим у нас есть два компонента:

<!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>
Mixin in Vue.js

Здесь определено два компонента. Функциональность обоих компонентов в некоторых моментах сходится. И весь этот общий функционал можно вынести в миксин:

<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 и выводит на консоль браузера строку:

Global mixin in Vue.js

Поскольку в данном случае определен один компонент и объект Vue, то глобальный миксин будет вызываться два раза.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850