Vue mixins were the standard way to share reusable logic across Options API components in Vue 2. A mixin is a plain JavaScript object containing component options like data, methods, and lifecycle hooks that Vue merges into any component using it.
While Vue 3 still supports mixins for backward compatibility, the Vue team recommends Composition API composables for all new code. Understanding mixins still helps when reading older codebases and migrating them cleanly to <script setup>.
flowchart TD
Mixin1["Mixin A (loading, reset)"] --> Component["Options Component"]
Mixin2["Mixin B (loading, fetch)"] --> Component
Component --> Conflict["Name Collision and Unclear Origin"]
this.isLoading does not tell you which mixin defined it.<script setup> ComposableHere is a legacy mouse-tracking mixin next to its modern composable replacement. Notice how the composable makes inputs and outputs explicit.
// Legacy Mixin (mixins/mouseMixin.js)
export const mouseMixin = {
data() {
return { x: 0, y: 0 };
},
methods: {
updateMouse(event) {
this.x = event.pageX;
this.y = event.pageY;
}
},
mounted() {
window.addEventListener('mousemove', this.updateMouse);
},
unmounted() {
window.removeEventListener('mousemove', this.updateMouse);
}
};
// Modern Composable (composables/useMouse.js)
import { ref, onMounted, onUnmounted } from 'vue';
export function useMouse() {
const x = ref(0);
const y = ref(0);
function update(event) {
x.value = event.pageX;
y.value = event.pageY;
}
onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));
return { x, y };
}
<script setup>
import { useMouse } from './composables/useMouse';
const { x, y } = useMouse();
</script>
<template>
<p>Mouse coordinates: {{ x }}, {{ y }}</p>
</template>
app.mixin(): Global mixins inject options into every single component in your app, including third-party libraries. Use provide/inject or composables instead.<script setup>: <script setup> does not have a mixins: [] option. Rewrite mixin logic as a use...() composable function before adopting <script setup>.mounted hook, both hooks run; when they share a methods name, the component overwrites the mixin.No. Legacy mixins continue to work in Options API components, so you can migrate them one feature at a time into composables whenever you touch those files.
Because composables return explicit objects, you can rename colliding variables on destructuring, such as const { data: userData } = useFetch('/user').
Yes. Composables are regular JavaScript functions, so one composable can import and compose several smaller composables cleanly.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With