Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

boyjarv's avatar

Vue 3 built in Tansition component

I see there is a built-in Transition component for Vue 3 https://vuejs.org/guide/built-ins/transition.html#reusable-transitions

Here is my code, the transition ease over 2 seconds doesn't seem to be working, I'm not sure why?!

<template>
  <div
    class="main-content relative"
    :style="{
      'background-size': 'cover',
      'backdrop-filter': 'blur(5px)',
      //filter: 'blur(8px)',
    }"
  >
    <div
      :style="{
        '-webkit-filter': 'blur(0px)',
        'backdrop-filter': 'blur(0px)',
        filter: 'blur(0px)',
      }"
      class="md:max-w-screen-lg mx-auto"
    >
      <h2
        class="
          text-xl text-red
          font-bold
          z-10
          pt-28
          pb-14
          uppercase
          text-center
        "
      >
        Calculating your total costs
      </h2>
      <Transition name="products-fade">
        <ProductItem v-if="loadedProducts" :items="productItems" />
      </Transition>
    </div>
  </div>
</template>

<script>
import ProductItem from "./ProductItem.vue";

export default {
  name: "HomePage",
  components: {
    ProductItem,
  },
  data() {
    return {
      loadedProducts: false,
      productItems: [
        {
          id: 1,
          name: "Identity requirements",
          price: 6.0,
        },
        {
          id: 2,
          name: "Request a quotation",
          price: 3.0,
        },
        {
          id: 3,
          name: "Find products",
          price: 16.0,
        },
        {
          id: 4,
          name: "Raise an order",
          price: 6.0,
        },
        {
          id: 5,
          name: "Authorise sale",
          price: 21.55,
        },
        {
          id: 6,
          name: "Pay provider",
          price: 13.0,
        },
        {
          id: 7,
          name: "Deliver product",
          price: 4.3,
        },
        {
          id: 8,
          name: "Invoice check",
          price: 6.0,
        },
        {
          id: 9,
          name: "Place order",
          price: 6.5,
        },
      ],
      totalPrice: 0,
    };
  },
  mounted() {
    this.loadedProducts = true;
  },
};
</script>

<style>
.container {
  z-index: 10;
  filter: blur(0px);
  -webkit-filter: blur(0px);
}
.main-content {
  z-index: 1;
  background: linear-gradient(
      0deg,
      rgba(255, 255, 255, 0.5),
      rgba(255, 255, 255, 0.5)
    ),
    url("@/assets/background-office.png");
  min-width: "100vw";
  min-height: "100vh";
}
li.item {
  width: 324px;
  height: 72px;
}
.products-fade-enter-from {
  opacity: 0;
}
.products-fade-enter-to {
  opacity: 1;
}
.products-fade-enter-active {
  transition: all 2s ease-in;
}
.products-fade-leave-from {
  opacity: 1;
}
.products-fade-leave-to {
  opacity: 0;
}
.products-fade-leave-active {
  transition: all 2s ease-out;
}
</style>

I have version: "vue": "^3.2.13"

0 likes
5 replies
boyjarv's avatar

It kind of looks like it worked but then I refreshed and it didn't I stopped the serve and changed to 10s the started serve, nothing

boyjarv's avatar
<template>
  <ul class="flex flex-grow flex-wrap items-list justify-around">
    <li
      v-for="item in items"
      :key="item.id"
      @click.prevent="addProduct(item)"
      :class="{
        selected: selectedItems.some((product) => product.id === item.id),
      }"
      class="
        w-1/3
        drop-shadow-lg
        bg-white
        rounded-full
        item
        mb-10
        flex flex-row
        items-center
        align-center
        justify-between
        px-6
        text-purple
        hover:cursor-pointer hover:bg-purple hover:text-white
      "
    >
      <div
        class="
          circled-border
          flex
          h-8
          w-8
          justify-center
          items-center
          rounded-full
          border-purple border-2
          hover:border-white
        "
      >
        <i class="fa fa-check hover:text-white"></i>
      </div>
      <span class="text-base justify-center text-center">{{ item.name }}</span>
      <div class="flex flex-col uppercase text-lightpurple text-xs font-bold">
        Estimate
        <span class="text-sm font-normal text-purple price"
          >&pound;&nbsp;{{ item.price.toFixed(2) }}</span
        >
      </div>
    </li>
  </ul>
  <div
    class="
      flex
      md:flex-row
      flex-col
      md:justify-evenly
      mx-auto
      items-center
      md:items-start
    "
  >
    <div class="invisible w-32">&nbsp;</div>
    <div
      class="
        total-price
        drop-shadow-lg
        bg-white
        rounded-full
        text-black
        item
        mb-10
        flex flex-row
        items-center
        align-center
        justify-between
        px-6
        hover:cursor-pointer
      "
    >
      <div
        class="
          flex
          justify-center
          items-center
          uppercase
          font-bold
          text-base text-purple
        "
      >
        Total
      </div>
      <div class="flex flex-col uppercase text-lightpurple text-xs font-bold">
        <span class="text-xxl text-red font-normal"
          >&pound;&nbsp;{{ this.totalPrice.toFixed(2) }}</span
        >
      </div>
    </div>
    <div
      class="
        rounded-l-full rounded-r-full
        text-white
        bg-red
        h-10
        flex flex-row
        justify-between
        items-center
        w-32
        px-4
        py-2
        hover:cursor-pointer
      "
    >
      <span>Continue</span>
      <span
        class="
          continue-button
          text-center
          justify-center
          bg-white
          p-1
          rounded-full
          flex
        "
        ><i class="fa fa-play text-red"></i
      ></span>
    </div>
  </div>
</template>

<script>
export default {
  name: "ProductItem",
  props: {
    items: {
      typeof: "Array",
    },
  },
  data() {
    return {
      selectedItems: [],
      itemSelected: false,
    };
  },
  computed: {
    totalPrice() {
      return this.selectedItems.reduce(
        (total, product) => (total += product.price),
        0
      );
    },
  },
  methods: {
    addProduct(product) {
      var index = this.selectedItems.findIndex(
        (item) => item.id === product.id
      );

      if (index === -1) {
        this.selectedItems.push(product);
      } else {
        this.selectedItems.splice(index, 1);
      }
    },
  },
};
</script>

<style scoped>
.total-price {
  width: 324px;
  height: 72px;
}
li.selected {
  background-color: #5f259f;
}
li.selected .circled-border {
  border-color: #ffffff;
}
li.selected {
  color: #ffffff;
}
li.selected i {
  color: #ffffff;
}
li.selected span.price {
  color: #ffffff;
}
li:hover .circled-border {
  border-color: #ffffff;
}
li:hover span.price {
  color: #ffffff;
}
.continue-button {
  height: 25px;
  width: 25px;
}
</style>

Please or to participate in this conversation.