DEV Community

terrierscript
terrierscript

Posted on

5 2

How to replace mixin to slot in Vue.js

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.

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

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay