Categories
Vue 3 Projects

Create an Accordion Component with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create an accordion component with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create accordion-component

and select all the default options to create the project.

Create the Accordion Component

To create the accordion component, we write:

<template>
  <div v-for="c of contents" :key="c.title">
    <div class="title" @click="c.expanded = !c.expanded">
      <div>
        <b>{{ c.title }}</b>
      </div>
      <div>
        <span v-if="c.expanded">&#x2191;</span>
        <span v-else>&#x2193;</span>
      </div>
    </div>
    <div class="description" v-if="c.expanded">
      {{ c.description }}
    </div>
  </div>
</template>

<script>
const contents = Array(10)
  .fill()
  .map((_, i) => {
    return {
      title: `title ${i}`,
      description: `description ${i}`,
      expanded: false,
    };
  });

export default {
  name: "App",
  data() {
    return {
      contents,
    };
  },
};
</script>

<style scoped>
.title {
  cursor: pointer;
  display: flex;
  justify-content: space-between;
}

.title,
.description {
  border: 1px solid black;
  padding: 5px;
}
</style>

We start by adding the elements for the accordion in the templaye.

We use the v-for directive to render the contents array into an accordion.

The key is set to the c.title property, which is unique.

In the inner div, we attached a click listener with the @click directive.

The click listener toggles the expanded property.

Inside it, we render the c.title property and show the down arrow if it’s not expanded, which is when c.expanded is false

And we show the up arrow when c.expanded is true .

c.description is rendered in the div below the title div.

It’s only shown with c.expanded is true .

Below that, we have the contents array to add some content to show.

In the data method, we return an object with the contents reactive property created from the contents array.

In the style tag, we have the title class selector’s styles set to cursor: pointer to set to a hand cursor.

display set to flex to enable flex layout.

This lets us use justify-content set to space-between to display the 2 divs at the left and right ends of the title div.

Then finally, we set the border and padding on the divs with the title and description classes styles.

We add a border and padding to these divs.

Now when we click on the title divs, we see the description divs toggled on and off.

Conclusion

We can create an accordion component easily with Vue 3 and JavaScript.

Categories
Vue 3 Projects

Create a Tooltip with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a tooltip with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create tooltip

and select all the default options to create the project.

Create the Tooltip

To create the tooltip, we write:

<template>
  <div id="container">
    <button @mouseover="onHover">hover me</button>
    <div
      id="tooltip"
      :style="{ top: `${clientY}px`, left: `${clientX}px` }"
      v-if="show"
      @mouseout="show = false"
    >
      tooltip
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      show: false,
      clientX: 0,
      clientY: 0,
    };
  },
  methods: {
    onHover(e) {
      const { clientX, clientY } = e;
      this.show = true;
      this.clientX = clientX;
      this.clientY = clientY;
    },
  },
};
</script>

<style scoped>
#container {
  width: 95vw;
  height: 95vh;
  align-items: center;
  display: flex;
  justify-content: center;
}

#tooltip {
  border: 1px solid black;
  padding: 5px;
  position: absolute;
  background-color: white;
}
</style>

We have a button that triggers the tooltip when we hover over it.

The button has the @mouseover directive to run the onHover method.

onHover sets this.show to true to show the tooltip.

It also sets the clientX and clientY reactive properties to set the position of the tooltip.

Below that, we have a div with ID tooltip .

The style prop has an object that has the top and left properties to set the position of the tooltip according to the position of the mouse.

In the script tag, we have the data method that returns an object with the reactive properties and their initial values.

In the style tag, we have the styles for the container div to center its content horizontally and vertically.

We center the content horizontally with justify-content .

align-items set to center center content vertically.

display: flex enables flex layout which lets us use align-items and justify-content .

The div with ID tooltip has styles to set the border, padding, and makes the position absolute .

background-color is set to white to make the background white instead of transparent.

Now when we hover over the button, we see the tooltip displayed where the mouse pointer is.

Conclusion

We can create a tooltip easily with Vue 3 and JavaScript.

Categories
Vue 3 Projects

Create a Hi-Low Card Game with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a hi-low card game with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create hi-low-game

and select all the default options to create the project.

Create the Hi-Low Card Game

To create the hi-low game, we write:

<template>
  <form @submit.prevent="draw">
    <select v-model="guess">
      <option>lower</option>
      <option>higher</option>
    </select>
    <button type="submit">guess</button>
  </form>
  <p>score: {{ score }}</p>
  <p>last drawn card</p>
  <img
    v-if="drawnCards[drawnCards.length - 2]"
    :src="`https://tekeye.uk/playing_cards/images/svg_playing_cards/fronts/${
      drawnCards[drawnCards.length - 2]
    }.svg`"
  />
  <p>currently drawrn card</p>
  <img
    v-if="drawnCards[drawnCards.length - 1]"
    :src="`https://tekeye.uk/playing_cards/images/svg_playing_cards/fronts/${
      drawnCards[drawnCards.length - 1]
    }.svg`"
  />
</template>

<script>
const suits = ["diamonds", "clubs", "hearts", "spades"];
const values = ["ace", 2, 3, 4, 5, 6, 7, 8, 9, 10];
const cards = [];
for (const s of suits) {
  for (const v of values) {
    cards.push(`${s}_${v}`);
  }
}
export default {
  name: "App",
  data() {
    return {
      score: 0,
      cards: [...cards].sort(() => Math.random() - 0.5),
      drawnCards: [],
      guess: "lower",
    };
  },
  methods: {
    draw() {
      const drawnCard = this.cards.pop();
      this.drawnCards.push(drawnCard);
      const indexLastCard = cards.indexOf(
        this.drawnCards[this.drawnCards.length - 2]
      );
      const indexDrawnCard = cards.indexOf(
        this.drawnCards[this.drawnCards.length - 1]
      );
      if (
        (indexLastCard < indexDrawnCard && this.guess === "higher") ||
        (indexLastCard > indexDrawnCard && this.guess === "lower")
      ) {
        this.score++;
      }
    },
  },
};
</script>

In the template, we have the form element with a select dropdown to let us pick whether the next card is higher or lower than the last drawn card.

The @submit directive lets us listen to the submit event, which is triggered when we click on a button with type set to submit .

The prevent modifier lets us prevent server-side submission and do client-side submission instead.

The score is displayed below the form.

And we display the last drawn card and the currently drawn card’s picture below that.

Then we create the cards array in the order of their magnitude by combining the values from the suits and values array.

In the data method,. we have the reactive properties in the object we return.

score has the score.

cards has a copy of the cards array shuffled with sort .

guess has the guess which can be 'lower' or 'higher' .

In the draw method, we take the card with pop .

And then we push that into drawnCards .

Then we have get the index of each card from the original card array, which is sorted in the order of their magnitude.

Then finally, we have an if block that compares the index of the last and currently drawn card and the guess.

If they match the condition, then score is increment by 1.

Conclusion

We can create a high-low card game easily with Vue 3 and JavaScript.

Categories
Vue 3 Projects

Create a Click Shape Game with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a click shape game with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create click-shape-game

and select all the default options to create the project.

Create the Click Shape Game

The game lets us score by clicking on shapes that are shown in random locations.

To create the click shape game, we write:

<template>
  <button @click="start">start game</button>
  <button @click="end">end game</button>
  <p>score: {{ score }}</p>
  <div
    class="circle"
    v-if="circleX && circleY"
    :style="{ position: 'absolute', top: `${circleY}px`, left: `${circleX}px` }"
    @click="onClick"
  >
    &nbsp;
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      score: 0,
      circleX: undefined,
      circleY: undefined,
      timer: undefined,
    };
  },
  methods: {
    onClick() {
      this.score++;
    },
    start() {
      this.timer = setInterval(() => {
        this.circleX = Math.floor(Math.random() * window.innerWidth);
        this.circleY = Math.floor(
          Math.random() * (window.innerHeight - 50) + 50
        );
      }, 2000);
    },
    end() {
      clearInterval(this.timer);
      this.score = 0;
      this.circleX = undefined;
      this.circleY = undefined;
    },
  },
  beforeUnmount() {
    clearInterval(this.timer);
  },
};
</script>

<style scoped>
.circle {
  border: 1px solid black;
  width: 50px;
  height: 50px;
  border-radius: 50%;
}
</style>

In the template, we have a button with the start game and end game buttons to start and end the game timer.

Below that, we have the score display.

And then we have the div that the player clicks on to score.

We set the style prop to the style with the top and left values. We need the px at the end to specify the position.

In the script tag, we have the data method to return the reactive property with their initial values.

circleX and circleY have the left and top values respectively.

timer has the timer.

onClick is the click handler of the div.

In the start method, we call setInterval with the callback to set the circleX and circleY values.

We set them to random values that are within the width and height of the screen.

In the end method, we call clearInterval to stop the timer.

And we reset the other reactive properties to their initial values.

In the beforeUnmount hook, we call clearInterval to remove the timer.

Then in the style tag, we have styles to make the div with class circle a circle.

Conclusion

We can create a click shape game easily with Vue 3 and JavaScript.

Categories
Vue 3 Projects

Create a Memory Game with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a memory game with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create memory-game

and select all the default options to create the project.

We also need the uuid package to let us generate unique IDs for the tiles.

To do this, we run:

npm i uuid

Create the Memory Game

To create the memory game, we write:

<template>
  <div class="container">
    <div v-for="a of answer" :key="a.id" class="tile" @click="onClick(a.id)">
      <div v-if="a.open">
        {{ a.value }}
      </div>
      <div v-else>&nbsp;</div>
    </div>
  </div>
</template>

<script>
import { v4 as uuidv4 } from "uuid";
const answer = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
  .map((n) => {
    return {
      id: uuidv4(),
      open: false,
      value: n,
    };
  })
  .sort(() => Math.random() - 0.5);

export default {
  name: "App",
  data() {
    return {
      answer,
      itemIds: []
    };
  },
  methods: {
    onClick(id) {
      if (!this.itemIds.length < 2 && !this.itemIds.includes(id)) {
        this.itemIds.push(id);
      }
      const index = this.answer.findIndex((a) => a.id === id);
      this.answer[index].open = true;
      if (this.itemIds.length === 2) {
        const item1Index = this.answer.findIndex(
          (a) => a.id === this.itemIds[0]
        );
        const item2Index = this.answer.findIndex(
          (a) => a.id === this.itemIds[1]
        );
        if (this.answer[item1Index].value !== this.answer[item2Index].value) {
          this.answer[item1Index].open = false;
          this.answer[item2Index].open = false;
        }
      }
      if (this.itemIds.length === 2) {
        this.itemIds = [];
      }
    },
  },
};
</script>

<style scoped>
.container {
  display: flex;
}

.tile {
  border: 1px solid black;
  width: 20vw;
  height: 50px;
}
</style>

We have a div with the class container which is a flex container.

Inside it, we have the tiles that we can click.

If 2 tiles have the same value, then they stay displayed.

Otherwise, we make them both blank again.

If a.open is true , we display the value.

Otherwise, we show an empty div.

In the script tag, we create the answer array with the number array.

We mao them to objects with the map method.

Each object has an id and the open value.

And then we sort them randomly with the sort method with a callback that returns a random number between -0.5 and 0.5.

In the data method, we return an object with the reactive properties.

answer is made reactive so that we can render it in the template.

itemId has the IDs of the tile object we clicked on.

Next, we add the onClick method which takes an id that we put into the itemIds reactive array if we have less than 2 items and the item isn’t already in the itemIds array.

Next, we get the index of the item with the given id value and set its open property to true to flip it.

If we have 2 items as indicated by this.itemIds.length === 2 , then we compare both items to see if they have the same value.

If they don’t, then we set open for each item back to false .

And in the last if statement, we set itemIds back to an empty if we already have 2 items in itemIds .

Now when we click on 2 tiles that match, we see them stay displayed with the value.

Otherwise, we see the tile going back to an empty tile.

Conclusion

We can create a memory game easily with Vue 3 and JavaScript.