Mixin is one of Vue.js feature.
https://vuejs.org/v2/guide/mixins.html
This gives options common to multiple components.
React also had a mixin in the past, but it is now deprecated.
This reason is descripted in follow documents.
- https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
- https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
Summary is here.
- Introduce implicit dependencies
- Cause name clashes
- Cause snowballing complexity
There also may apply on Vue.js.
How to replace mixin? Answer: slot.
In React, we can resolve this probrem with higher order components or functional children.
In Vue.js, we can replace mixin with slot.
In this article, I use mouse event tracking example.
First: Use mixin pattern.
Mixin example is here:
// mouseMixin.js
export default {
data() {
return {
x: 0,
y: 0
};
},
methods: {
mousemove(e) {
this.x = e.clientX;
this.y = e.clientY;
}
}
}
and Components example is here:
<!-- Item -->
<template>
<div @mousemove="mousemove">
<div>Item with mixin</div>
<div>x: {{ x }}</div>
<div>y: {{ y }}</div>
</div>
</template>
<script>
import mouseMixin from "./mouseMixin"
export default {
mixins: [ mouseMixin ],
};
</script>
Finally, components is called those:
<!-- Parent.vue -->
<template>
<div>
<Item />
</div>
</template>
<script>
export default {
components: {
Item,
}
};
</script>
In this example, some properties (x
, y
and mousemove
) is implicit. It's not to easy to find those properties.
Next: Use slot
First, write mixin usage component:
<!-- Item.vue -->
<template>
<div>
<div>Item with scope</div>
<div>x: {{ x }}</div>
<div>y: {{ y }}</div>
</div>
</template>
<script>
export default {
props: {
x: Number,
y: Number
}
};
</script>
This is very simple because got only x
and y
.
Next, we create MouseEvent
component.
This got x
and y
from mousemove
and pass to <slot>
<!-- MouseEvent.vue -->
<template>
<div @mousemove="mousemove">
<slot :x="x" :y="y"></slot>
</div>
</template>
<script>
export default {
data() {
return {
x: 0,
y: 0
};
},
methods: {
mousemove(e) {
this.x = e.clientX;
this.y = e.clientY;
}
}
};
</script>
And last, combine <MouseEvent>
and <Item>
with slot-scope
.
<!-- Parent.vue -->
<template>
<div>
<MouseEvent>
<div slot-scope="{x, y}">
<Item :x="x" :y="y" />
</div>
</MouseEvent>
</div>
</template>
<script>
export default {
components: {
MouseEvent,
Item,
},
};
</script>
Okay, It's work.
We can replace slot
from mixins
. You can use this pattern when avoid mixins
But Vue.js scope is so redundancy. It's a little pain point
Top comments (0)