Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In Vue 3, you can replace a mixin’s reusable behavior with a composable: a function that uses Composition API features, such as ref(), computed(), and lifecycle hooks, then returns the values and methods a component needs. Mixins still work, but Vue now prefers composables for sharing logic between components.

What replaces a Vue mixin?

A composable is an ordinary JavaScript function, usually named with a use prefix, that encapsulates reusable stateful logic using Vue’s Composition API. For example, a useSearch() function could manage search results and return them to a component. The component imports and calls that function rather than receiving properties implicitly from a mixin.

The Composition API is built into Vue 3 and Vue 2.7. Vue describes it as addressing the drawbacks of mixins, its primary Options API mechanism for reusing logic. See the Composition API FAQ and the Composables guide.

Why Vue recommends composables over mixins

Trace where values come from

A mixin can add data, computed properties, and methods to a component instance. When a component combines several mixins, it may be difficult to identify which one supplies a particular property. A composable makes the source visible where the component calls it and receives its returned bindings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Avoid name collisions

Mixins can add properties with the same name to a component, creating conflicts. With a composable, you can rename a returned binding locally when destructuring it—for example, const { results: searchResults } = useSearch(query).

Make communication explicit

Mixins may coordinate through properties attached to the same component instance. A composable instead accepts inputs as function arguments and exposes outputs through its return value. That makes dependencies and data flow easier to follow.

Keep lifecycle work with its owner

Options hooks from mixins are merged into the component, so the origin of a lifecycle effect can be less obvious. A composable can register hooks such as onMounted() and onUnmounted() for the logic it owns, keeping setup and cleanup together. Watchers created during a composable call made in the active component’s setup context can be disposed of when that component unmounts.

Improve type inference and organization

Composables are plain functions using ordinary variables and return values, which Vue says are naturally type-friendly and support full type inference with little manual annotation. They can also split a large component into logical concerns, and one composable’s returned values can be passed to another.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Mixin versus composable

Concern Mixin Composable
Traceability Properties are merged into the component instance; their source can be hard to identify across multiple mixins. Imported function and returned bindings are visible at the call site.
Name safety Shared instance property names can collide. Returned bindings can be renamed locally.
Communication Often relies on shared instance properties. Uses explicit function arguments and return values.
Lifecycle ownership Hooks are merged into the component’s options. Hooks can be registered beside the related logic in the composable.
Type inference Options and mixin inference can be less straightforward. Plain functions and Composition API support strong type inference.
Compatibility Still supported in Vue 3. Preferred for reusable logic in new Vue 3 code.

Vue’s Options API reference confirms that the mixins option remains supported while identifying composables as the preferred code-reuse approach.

How to refactor a mixin into a composable

  1. Inventory the mixin. List its data fields, computed properties, methods, watchers, and lifecycle hooks. Note which values it reads from the component, such as props, IDs, or services.
  2. Create a composable module. Put the reusable behavior in a separate module, such as useSearch.js, and export a function like useSearch().
  3. Translate each kind of behavior. Use ref() or reactive() for state, computed() for derived values, and Composition API lifecycle hooks such as onMounted() or onUnmounted() where they fit.
  4. Make inputs explicit. Pass component-specific values into the function as arguments rather than relying on hidden instance properties.
  5. Return only what callers need. Expose the refs, computed values, and methods that the component should use. Keep internal implementation details private.
  6. Call it during setup. Use the composable synchronously from setup() or <script setup>, then use its returned bindings in the template. Vue strongly recommends <script setup> for single-file components.

Illustrative composable

// useSearch.js
import { ref, watch, onUnmounted } from 'vue'

export function useSearch(query) {
  const results = ref([])
  const stop = watch(query, async (value) => {
    // Fetch and assign results.
  })
  onUnmounted(stop)
  return { results }
}

Call it from a component

<script setup>
import { ref } from 'vue'
import { useSearch } from './useSearch'

const query = ref('')
const { results } = useSearch(query)
</script>

The snippets show the shape of an extraction, not a complete search implementation: you still need to provide the fetch logic and decide how the composable handles errors, loading state, and other behavior required by your app.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Can you keep using mixins in Vue 3?

Yes. Vue 3 has not removed mixins, and existing mixins can remain in a codebase while you migrate. Vue’s application API cautions against global mixins in application code because they affect every component; it says they are mainly useful for backwards compatibility with ecosystem libraries. For new reusable logic, Vue recommends composables instead.

For Vue 2 upgrades, the migration build guide describes @vue/compat, which provides Vue 2-compatible behavior and runtime warnings to help identify changed or deprecated usage, subject to documented limitations. Vue’s migration guide also recommends Composition API over inheritance and mixins in Vue 3.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When a refactor needs more than a direct translation

A composable is not an automatic conversion of a mixin. During extraction, decide which values are inputs, which results the component needs, and who owns side effects and their cleanup. If other code depends on the mixin’s instance properties or lifecycle behavior, account for those compatibility requirements before removing it.

For the setup rules and lifecycle details, see Vue’s Composables guide and setup() reference.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.