vue3 project cart with animations from entry to entry

vue animation
cnpm install animate.css --save yarn add animate.css // install
import 'animate.css' // where to use and where to import
 3.0 --------------- -------------------------------------------------- -------------------------
 <transition-group appear name="animate__animated animate__bounce" enter-active-class="animate__zoomInDown" leave-active-class ="animate__zoomOutDown">
      <!-- //This wraps the content to be animated and requires a -group with the element or delete label -->
  

      <!-- animation end-->
    </transition-group>

Part of the renderings 

 App.view

<template>
  <!-- <div id="nav"> -->
  <!--
      vue3中移除了tag属性 新增了custom属性  custom可以用来自定义router-link的内容
      但是使用了之后会导致路由无法跳转 这时候需要v-slot="{navigate}" 通过事件触发navigate方法就能跳转页面
      假如有两个路由地址 第一个 /home 第二个是 /home/index
      exact-acitve-class 精确匹配后才会添加的class类名
      active-class 包含有就会添加的class类名
      vue2中的写法
      <router-view to="/" tag="button" exact-active-class="active">home</router-view>
    -->

  <!-- <router-link to="/" custom v-slot="{navigate, isExactActive}">
      <button @click="navigate" :class="isExactActive ? 'active' : ''">home</button>
    </router-link> |
    <router-link to="/about" custom v-slot="{navigate, isExactActive}">
      <button @click="navigate" :class="isExactActive ? 'active' : ''">about</button>
    </router-link> | -->

  <!-- </div> -->
  <!-- 动画 -->

  <div>
    <div>
      <router-view v-slot="{ Component }">
        <transition name="ani">
          <component :is="Component" class="page1"></component>
        </transition>
      </router-view>
    </div>
    <!-- <router-view></router-view> -->
  </div>
</template>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  // text-align: center;
  width: 100%;
  height: 100%;
  position: relative;
}

// 动画触发时组件共存,是块级元素,组件分上下动画僵硬,定位让组件在一行显示,
.page1 {
  width: 100%;
  position: absolute;
  top: 0px;
  left: 0;
}
// 进入时
.ani-enter-from {
  left: 100%;
}
//进入过程
.ani-enter-active {
  transition: all 0.5s linear;
}
//离开过程
.ani-leave-active {
  transition: all 0.5s linear;
  transform-origin: center;
}
//离开时
.ani-leave-to {
  left: -100%;
}
</style>

                                         home.view

<template>
  <div class="home">
    <div class="tabs">
      <span
        v-for="(item, i) in tabs"
        :key="item.id"
        :class="num == i ? 'active' : ''"
        @click="tabclick(i)"
        >{
   
   { item.name }}</span
      >
    </div>
    <!-- lits -->
    <div
      class="list"
      v-for="item in $store.state.data"
      :key="item.id"
      v-show="num == item.status"
    >
      <div class="one">
        <img :src="item.img" alt />
      </div>
      <div class="two">
        <p>{
   
   { item.name }}</p>
        <p class="price">¥{
   
   { item.price }}</p>
        <section class="footer">
          <p>{
   
   { item.payNum }}人付款</p>
          <p @click="add(item)">+</p>
        </section>
      </div>
    </div>
  </div>
</template>
<script>
import { useStore } from "vuex";
import { ref, reactive } from "vue";
import { useRouter } from "vue-router";
export default {
  components: {},
  setup() {
    const store = useStore();
    const router = useRouter();
    const num = ref(0);
    const tabs = reactive([
      {
        name: "推荐",
        id: 0,
      },
      {
        name: "母婴",
        id: 1,
      },
      {
        name: "鞋包",
        id: 2,
      },
      {
        name: "食品",
        id: 3,
      },
      {
        name: "数码",
        id: 4,
      },
    ]);
    function tabclick(i) {
      num.value = i;
    }
    function add(item) {
      store.commit("add", item);
      router.push("/About");
    }
    store.dispatch("getData");
    return {
      store,
      tabclick,
      num,
      tabs,
      add,
      router,
    };
  },
};
</script>
<style lang="scss" scoped>
.tabs {
  display: flex;
  align-items: center;
  width: 100%;
  height: 50px;
  background-color: #4b0082;
  span {
    flex-basis: 20%;
    height: 100%;
    line-height: 50px;
    color: #fff;
    text-align: center;
  }
}
.list {
  display: flex;
  width: 100%;
  height: 130px;
  background-color: #fff;
  margin-bottom: 20px;
  .one {
    flex-basis: 30%;
    height: 100%;
    img {
      width: 100%;
      height: 100%;
    }
  }
  .two {
    flex-basis: 70%;
    height: 100%;
    p {
      &:nth-child(1) {
        margin-top: 20px;
      }
    }
    .price {
      color: #4b0082;
      margin: 15px 0 15px 15px;
    }
    .footer {
      padding: 0 15px;
      margin-top: 10px;
      display: flex;
      width: 100%;
      justify-content: space-between;
      p {
        &:nth-child(2) {
          width: 40px;
          height: 25px;
          text-align: center;
          line-height: 25px;
          border-radius: 25px;
          background-color: #4b0082;
          font-size: 20px;
          color: #fff;
        }
      }
    }
  }
  .active {
    color: #ec1f10 !important;
  }
}
</style>

                                    About.vue

<template>
  <div>
    <button @click="$router.go(-1)">返回</button>
    <transition-group
      appear
      name="animate__animated animate__bounce"
      enter-active-class="animate__zoomInDown"
      leave-active-class="animate__zoomOutDown"
    >
      <!-- //这里包住要动画内容  要一个跟元素或删除标签的-group -->
      <!-- list -->
      <div class="list" v-for="item in $store.state.cardDate" :key="item.id">
        <div class="one">
          <input
            type="checkbox"
            :checked="item.checked"
            @change="ck(item.id)"
          />
          <img :src="item.img" alt />
        </div>
        <div class="two">
          <p v-html="item.name"></p>
          <p v-html="item.price"></p>
        </div>
        <div class="three">
          <span @click="item.num > 1 ? item.num-- : 1">-</span>
          <span>{
   
   { item.num }}</span>
          <span @click="item.num++">+</span>
        </div>
      </div>

      <!-- 动画结束 -->
    </transition-group>
  </div>
  <button @click="del">删除所选</button>
  <button>已选{
   
   { $store.getters.num }}</button>
  <button>总数{
   
   { $store.getters.priceAll }}</button>
  <input
    type="checkbox"
    v-model="$store.state.vmckall"
    @click="ckAll($event || e)"
  />全选
</template>
<script>
import { useStore } from "vuex";
import { onBeforeMount } from "vue";
import "animate.css";
export default {
  components: {},
  setup() {
    onBeforeMount(() => {
      // ...
      // 在小括号里不用赋值,不在小括号箭头函数要生命一个变量接受
      store.commit("mount");
    });
    const store = useStore();
    function del() {
      store.commit("del");
    }
    function ck(id) {
      store.commit("ck", id);
    }
    function ckAll(e) {
      store.commit("ckAll", e.target.checked);
    }
    return {
      del,
      store,
      ck,
      ckAll,
    };
  },
};
</script>
<style lang="scss" scoped>
.list {
  display: flex;
  justify-content: space-between;
  padding: 0 15px;
  align-items: center;

  width: 100%;
  height: 130px;
  background-color: #fff;
  .one {
    display: flex;
    img {
      width: 60%;
      height: 100%;
      margin-left: 10px;
    }
  }
  .two {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 20px;
  }
  .three {
    display: flex;
    flex-direction: column;
    span {
      display: inline-block;
      width: 20px;
      height: 20px;
      text-align: center;
      line-height: 20px;
      background-color: #ccc;
      &:nth-child(2) {
        margin: 10px 0;
      }
    }
  }
}
</style>

 Source code on the homepage resource

Conclusion :

I hope everyone can get off work early, have no bugs, and accompany family and friends

Guess you like

Origin blog.csdn.net/m0_57904695/article/details/123536893