1

I'm having a Nuxt.js project where I'm using a custom button.

The button is a link with an svg path and a span. I also have animation for the button where it triggers on the mouse over and mouse out event.

here is my button code.

<template>  
        <a class="button green" href="/"
            @mouseover="buttonEnter"
            @mouseout="buttonLeave">
            <svg viewBox="0 0 180 60">
                <path d="M10,10 C10,10 50,9.98999977 90,9.98999977 C130,9.98999977 170,10 170,10 C170,10 170.009995,20 170.009995,30 C170.009995,40 170,50 170,50 C170,50 130,50.0099983 90,50.0099983 C50,50.0099983 10,50 10,50 C10,50 9.98999977,40 9.98999977,30 C9.98999977,20 10,10 10,10 Z"/>
            </svg>
            <span>Go Home</span>
        </a>
</template>


<script>
import { buttonEnter } from '~/assets/animate'
import { buttonleave } from '~/assets/animate'

export default {
    methods: {
        buttonEnter(event) {
            const buttonPath = event.currentTarget.querySelector('path')
            const buttonSpan = event.currentTarget.querySelector('span')
            buttonEnter(buttonPath, buttonSpan)
        },
        buttonLeave(event) {
            const buttonPath = event.currentTarget.querySelector('path')
            const buttonSpan = event.currentTarget.querySelector('span')
            buttonleave(buttonPath, buttonSpan)
        },
    },
}
</script>

I use this button in many pages and I feel like i duplicate my self and having a button component will make things better and more tidy. The problem is I'm new with Vue and I fail to do this. Can somebody point me out or give me an example code how properly to write a reusable component ?

here are also the buttonEnter and buttonleave function for the animation.

import anime from "animejs";

export function buttonEnter(buttonPath, buttonSpan) {
  anime.remove([buttonPath, buttonSpan]);
  anime({
    targets: buttonPath,
    d:
      "M10,10 C10,10 50,7 90,7 C130,7 170,10 170,10 C170,10 172,20 172,30 C172,40 170,50 170,50 C170,50 130,53 90,53 C50,53 10,50 10,50 C10,50 8,40 8,30 C8,20 10,10 10,10 Z",
    elasticity: 700,
    offset: 0
  });
  anime({
    targets: buttonSpan,
    scale: 1.15,
    duration: 800,
    offset: 0
  });
}

export function buttonleave(buttonPath, buttonSpan) {
  anime.remove([buttonPath, buttonSpan]);
  anime({
    targets: buttonPath,
    d:
      "M10,10 C10,10 50,9.98999977 90,9.98999977 C130,9.98999977 170,10 170,10 C170,10 170.009995,20 170.009995,30 C170.009995,40 170,50 170,50 C170,50 130,50.0099983 90,50.0099983 C50,50.0099983 10,50 10,50 C10,50 9.98999977,40 9.98999977,30 C9.98999977,20 10,10 10,10 Z",
    elasticity: 700,
    offset: 0
  });
  anime({
    targets: buttonSpan,
    scale: 1,
    duration: 800,
    offset: 0
  });
}

here is a demo of the button codesandbox

0

2 Answers 2

2

Creating a component is what you are after. Lucky you, this is really simple to do in Vue.js.

The only thing you need in your code is to name the component with the name key. For the example, let's call our reusable component custom-button: name: 'custom-button'

custom-button.vue

<template>
        <a class="button green" href="/"
            @mouseover="buttonEnter"
            @mouseout="buttonLeave">
            <svg viewBox="0 0 180 60">
                <path d="M10,10 C10,10 50,9.98999977 90,9.98999977 C130,9.98999977 170,10 170,10 C170,10 170.009995,20 170.009995,30 C170.009995,40 170,50 170,50 C170,50 130,50.0099983 90,50.0099983 C50,50.0099983 10,50 10,50 C10,50 9.98999977,40 9.98999977,30 C9.98999977,20 10,10 10,10 Z"/>
            </svg>
            <span>Go Home</span>
        </a>
</template>


<script>
import { buttonEnter } from '~/assets/animate'
import { buttonleave } from '~/assets/animate'

export default {
    name: 'custom-button',
    methods: {
        buttonEnter(event) {
            const buttonPath = event.currentTarget.querySelector('path')
            const buttonSpan = event.currentTarget.querySelector('span')
            buttonEnter(buttonPath, buttonSpan)
        },
        buttonLeave(event) {
            const buttonPath = event.currentTarget.querySelector('path')
            const buttonSpan = event.currentTarget.querySelector('span')
            buttonleave(buttonPath, buttonSpan)
        },
    },
}
</script>

The only thing you have to do now is to import the file in the page(s) you want to use it. Since we already exported it as default, we can simply import it using import. Last but not least, we need to tell Vue that we want to register a new component to be used in the markup. Add a components key with an object of components you wish to use on the specific page.

about.vue

<template>
  <div class="container">
    <div>
      <h1>About us</h1>
      <custom-button></custom-button>
    </div>
  </div>
</template>

<script>
import customButton from './pathToCustomButton.vue'
export default {
    name: 'about',
    components: { customButton }
}
</script>
Sign up to request clarification or add additional context in comments.

Comments

1

Simply put the content that you have in index.vue in new file named custombtn.vue under the components folder and your index.vue should be like :

<template>	
  <div>
    test btn
    <custombtn />
    it done ! 
  </div>
</template>


<script>
  import custombtn from '~/components/custombtn.vue'

  export default {
    components: {
      custombtn
    }
  }
</script>

in custombtn.vue you could import buttonEnter, buttonleave as follows:

    import { buttonEnter, buttonleave } from '../assets/animate'

check this sandbox

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.