Table of Contents
Brief description of Mixin
Mixin is considered "harmful"
Naming conflict
Implicit dependency
Migrate from mixin
Composition API crash course
Code Extraction
Code reuse
Naming conflict...resolved!
Implicit dependency...resolved!
Summarize
Home Web Front-end CSS Tutorial How the Vue Composition API Replaces Vue Mixins

How the Vue Composition API Replaces Vue Mixins

Apr 07, 2025 am 10:50 AM

How the Vue Composition API Replaces Vue Mixins

Sharing code between Vue components? If you are familiar with Vue 2, you may have used mixin to achieve this. But the new Composition API (now available as a plugin for Vue 2 and is an upcoming feature of Vue 3) provides a better solution.

This article will explore the shortcomings of mixin and understand how the Composition API overcomes these shortcomings and makes Vue applications more scalable.

Brief description of Mixin

Let's quickly review the mixin mode, as it is crucial to what we'll cover in the next section.

Typically, the Vue component is defined by a JavaScript object that has various properties that represent the functions we need to implement - such as data, methods, computed properties, etc.

 // MyComponent.js
export default {
  data: () => ({
    myDataProperty: null
  }),
  methods: {
    myMethod () { ... }
  }
  // ...
}
Copy after login

When we want to share the same properties between components, we can extract the common properties into a separate module:

 // MyMixin.js
export default {
  data: () => ({
    mySharedDataProperty: null
  }),
  methods: {
    mySharedMethod () { ... }
  }
}
Copy after login

Now we can add this mixin to any component that uses it by assigning it to the mixin configuration property. At runtime, Vue merges the component's properties with any added mixin.

 // ConsumingComponent.js
import MyMixin from "./MyMixin.js";

export default {
  mixins: [MyMixin],
  data: () => ({
    myLocalDataProperty: null
  }),
  methods: {
    myLocalMethod () { ... }
  }
}
Copy after login

For this particular example, the component definition used by the runtime is as follows:

 export default {
  data: () => ({
    mySharedDataProperty: null,
    myLocalDataProperty: null
  }),
  methods: {
    mySharedMethod () { ... },
    myLocalMethod () { ... }
  }
}
Copy after login

Mixin is considered "harmful"

As early as mid-2016, Dan Abramov wrote “Mixins Considered Harmful”, in which he believed using mixins in React components to reuse logic is an anti-pattern, advocating avoiding them.

Unfortunately, the shortcomings he mentioned about React mixin also apply to Vue. Before we understand how the Composition API overcomes these shortcomings, let's take a look at these shortcomings.

Naming conflict

We see how mixin mode merges two objects at runtime. What happens if they all share a property with the same name?

 const mixin = {
  data: () => ({
    myProp: null
  })
}

export default {
  mixins: [mixin],
  data: () => ({
    // The same name!
    myProp: null
  })
}
Copy after login

This is where the merger strategy comes into play. This is a set of rules to determine what happens when a component contains multiple options with the same name.

The default (but configurable) merge policy of Vue components stipulates that local options will override mixin options. But there are exceptions. For example, if we have multiple life cycle hooks of the same type, these hooks will be added to the hook array and all hooks will be called sequentially.

Even if we don't encounter any actual errors, it can be increasingly difficult to write code when dealing with named properties between multiple components and mixins. This is especially difficult once a third-party mixin as npm package and its named properties that may cause conflicts.

Implicit dependency

There is no hierarchical relationship between mixin and the components that use it. This means that the component can use data properties defined in the mixin (e.g. mySharedDataProperty), but the mixin can also use it assuming data properties defined in the component (e.g. myLocalDataProperty). This is common when using mixin to share input validation. The mixin may expect the component to have an input value which will use in its own validate method.

But this can cause problems. What happens if we want to refactor the component later and change the name of the variables required by the mixin? We won't notice any issues from the components. The code inspector will not find it either. We will only see errors at runtime.

Now imagine a component that contains many mixins. Can we refactor local data properties, or will it break the mixin? Which mixin? We have to search for all mixins manually to know.

Migrate from mixin

Dan's article provides alternatives to mixin, including advanced components, utility methods, and some other component combination patterns.

While Vue is similar to React in many ways, the alternative pattern he suggests doesn't convert well to Vue. So, although this post was written in mid-2016, Vue developers have been enduring mixin issues since then.

Until now. The disadvantages of mixin are one of the main motivational factors behind the Composition API. Before you understand how it overcomes the mixin problem, let's take a quick look at how it works.

Composition API crash course

The key idea of ​​the Composition API is that instead of defining the functions of components (such as states, methods, computed properties, etc.) as object properties, they are defined as JavaScript variables returned from the new setup function.

Here is a classic example of a Vue 2 component defined using the Composition API, which defines a "counter" function:

 //Counter.vue
export default {
  data: () => ({
    count: 0
  }),
  methods: {
    increment() {
      this.count ;
    }
  },
  computed: {
    double () {
      return this.count * 2;
    }
  }
}
Copy after login

Here are the exact same components defined using the Composition API.

 // Counter.vue
import { ref, calculated } from "vue";

export default {
  setup() {
    const count = ref(0);
    const double = computed(() => count.value * 2)
    function increment() {
      count.value ;
    }
    return {
      count,
      double,
      Increment
    }
  }
}
Copy after login

You will first notice that we imported the ref function, which allows us to define a responsive variable that has almost the same function as a data variable. The same is true for the computered function.

The increment method is not responsive, so it can be declared as a normal JavaScript function. Note that we need to change the subproperty value to change the value of the count responsive variable. This is because responsive variables created with ref need to be objects to maintain their responsiveness when passed.

It is best to consult the Vue Composition API documentation for a detailed understanding of how ref works.

After defining these functions, we return them from the setup function. There is no difference in the functions of the above two components. All we did was using the alternative API.

Tip: The Composition API will be the core feature of Vue 3, but you can also use the NPM plugin @vue/composition-api in Vue 2.

Code Extraction

The first obvious advantage of the Composition API is its ease of extracting logic.

Let's use the Composition API to refactor the components defined above so that the functionality we define is in the JavaScript module useCounter. (The prefix using "use" as the function description is the naming convention of the Composition API.)

 // useCounter.js
import { ref, calculated } from "vue";

export default function () {
  const count = ref(0);
  const double = computed(() => count.value * 2)
  function increment() {
    count.value ;
  }
  return {
    count,
    double,
    Increment
  }
}
Copy after login

Code reuse

To use this function in a component, we simply import the module into the component file and call it (note that import is a function). This will return the variables we define, which we can then return from the setup function.

 // MyComponent.js
import useCounter from "./useCounter.js";

export default {
  setup() {
    const { count, double, increment } = useCounter();
    return {
      count,
      double,
      Increment
    }
  }
}
Copy after login

At first, this seems a bit lengthy and meaningless, but let's see how this pattern overcomes the mixin problem we've seen before.

Naming conflict...resolved!

We have seen before that mixin can use properties that may be of the same name as those in the use component, or even more concealedly as those in other mixin used by the use component.

This problem does not exist in the Composition API because we need to explicitly name any state or method returned from the compositing function:

 export default {
  setup () {
    const { someVar1, someMethod1 } = useCompFunction1();
    const { someVar2, someMethod2 } = useCompFunction2();
    return {
      someVar1,
      someMethod1,
      someVar2,
      someMethod2
    }
  }
}
Copy after login

Naming conflicts will be resolved in the same way as any other JavaScript variable.

Implicit dependency...resolved!

We have also seen before that mixin can use data properties defined on components, which makes the code fragile and difficult to understand.

Combination functions can also call local variables defined in components. However, the difference is that this variable must now be passed explicitly to the combined function.

 import useCompFunction from "./useCompFunction";

export default {
  setup () {
    // A local value that needs to be used for the combination function const myLocalVal = ref(0);

    // It must be explicitly passed as a parameter const { ... } = useCompFunction(myLocalVal);
  }
}
Copy after login

Summarize

The mixin mode looks very safe on the surface. However, because it increases the vulnerability of the code and the way it masks the ability to understand functions, sharing code by merging objects becomes an anti-pattern.

The cleverest thing about the Composition API is that it allows Vue to rely on security measures built into native JavaScript to share code, such as passing variables to functions and module systems.

Does this mean that the Composition API is superior to Vue's classic API in every way? No. In most cases, you can stick to the classic API. However, if you plan to reuse your code, the Composition API is undoubtedly a better choice.

The above is the detailed content of How the Vue Composition API Replaces Vue Mixins. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Vue 3 Vue 3 Apr 02, 2025 pm 06:32 PM

It's out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

Building an Ethereum app using Redwood.js and Fauna Building an Ethereum app using Redwood.js and Fauna Mar 28, 2025 am 09:18 AM

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

Can you get valid CSS property values from the browser? Can you get valid CSS property values from the browser? Apr 02, 2025 pm 06:17 PM

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That's like this.

A bit on ci/cd A bit on ci/cd Apr 02, 2025 pm 06:21 PM

I'd say "website" fits better than "mobile app" but I like this framing from Max Lynch:

Stacked Cards with Sticky Positioning and a Dash of Sass Stacked Cards with Sticky Positioning and a Dash of Sass Apr 03, 2025 am 10:30 AM

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

Using Markdown and Localization in the WordPress Block Editor Using Markdown and Localization in the WordPress Block Editor Apr 02, 2025 am 04:27 AM

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

Comparing Browsers for Responsive Design Comparing Browsers for Responsive Design Apr 02, 2025 pm 06:25 PM

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

Why are the purple slashed areas in the Flex layout mistakenly considered 'overflow space'? Why are the purple slashed areas in the Flex layout mistakenly considered 'overflow space'? Apr 05, 2025 pm 05:51 PM

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...

See all articles