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 () { ... } } // ... }
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 () { ... } } }
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 () { ... } } }
For this particular example, the component definition used by the runtime is as follows:
export default { data: () => ({ mySharedDataProperty: null, myLocalDataProperty: null }), methods: { mySharedMethod () { ... }, myLocalMethod () { ... } } }
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 }) }
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; } } }
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 } } }
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 } }
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 } } }
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 } } }
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); } }
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!

What it looks like to troubleshoot one of those impossible issues that turns out to be something totally else you never thought of.

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

I know, I know: there are a ton of content management system options available, and while I've tested several, none have really been the one, y'know? Weird pricing models, difficult customization, some even end up becoming a whole &

Linking CSS files to HTML can be achieved by using elements in part of HTML. 1) Use tags to link local CSS files. 2) Multiple CSS files can be implemented by adding multiple tags. 3) External CSS files use absolute URL links, such as. 4) Ensure the correct use of file paths and CSS file loading order, and optimize performance can use CSS preprocessor to merge files.

Choosing Flexbox or Grid depends on the layout requirements: 1) Flexbox is suitable for one-dimensional layouts, such as navigation bar; 2) Grid is suitable for two-dimensional layouts, such as magazine layouts. The two can be used in the project to improve the layout effect.

The best way to include CSS files is to use tags to introduce external CSS files in the HTML part. 1. Use tags to introduce external CSS files, such as. 2. For small adjustments, inline CSS can be used, but should be used with caution. 3. Large projects can use CSS preprocessors such as Sass or Less to import other CSS files through @import. 4. For performance, CSS files should be merged and CDN should be used, and compressed using tools such as CSSNano.

Yes,youshouldlearnbothFlexboxandGrid.1)Flexboxisidealforone-dimensional,flexiblelayoutslikenavigationmenus.2)Gridexcelsintwo-dimensional,complexdesignssuchasmagazinelayouts.3)Combiningbothenhanceslayoutflexibilityandresponsiveness,allowingforstructur

What does it look like to refactor your own code? John Rhea picks apart an old CSS animation he wrote and walks through the thought process of optimizing it.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

Atom editor mac version download
The most popular open source editor

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

Dreamweaver Mac version
Visual web development tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
