Vue--动画效果与过度效果

API文档:https://v2.cn.vuejs.org/v2/guide/transitions.html#CSS-%E5%8A%A8%E7%94%BB

单个元素

transition标签不会呈现在浏览器元素选项上,将相应动画效果的内容放置在transition标签内,并且设置相应class的样式,可以实现动画效果。

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!--将需要增加动画效果的元素放在transition内-->
    <!--如果设置name="xxx",name后面的v-enter-active的v就要改成xxx-->
    <!--appear设置表示一进页面就显示动画效果-->
    <!-- 如果变化元素只有一个,可以不设置name,如果有多个,为了避免样式冲突,还是设置name -->
    <transition name="democss" :appear="true">
      <h1 v-show="isShow">你好啊!</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: "MyTest",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style>
/*过度效果,标志transition*/
h1 {
  background-color: aqua;
}
/*进入和离开过程*/
.v-enter-active,
.v-leave-active {
  transition: 0.5s linear;
}
/*刚进入和离开过去*/
.v-enter,
.v-leave-to {
  transform: translateX(-100%);
}
/*刚进入和进入过去*/
.v-leave,
.v-enter-to {
  transform: translateX(0);
}
/*
下面的是用@keyframe实现的,一样的效果,动画效果,标志@keyframe,animation
h1 {
  background-color: aqua;
}
.democss-enter-active {		//如果没有name则为.v-enter-active
  animation: testPart 1s linear;
}
.democss-leave-active {
  animation: testPart 1s linear reverse;
}
@keyframes testPart {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0px);
  }
}
*/
</style>

多个元素

这时候需要用transition-group标签,并且其子标签也就是要给与动画的标签需要有key值。

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- transition-group的子标签有key值 -->
    <transition-group :appear="true">
      <h1 v-show="!isShow" key="1">你好啊!</h1>
      <h1 v-show="isShow" key="2">你好啊!</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: "MyTest",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style>
h1 {
  background-color: aqua;
}
.v-enter-active,
.v-leave-active {
  transition: 0.5s linear;
}
.v-enter,
.v-leave-to {
  transform: translateX(-100%);
}
.v-leave,
.v-enter-to {
  transform: translateX(0);
}
</style>

引用第三方库

有很多动画第三方库,这里示例为animate.css
可以通过

npmjs.com

搜索得到并进入官网。里面有相应的步骤,基本就是先安装相应的类库

npm install animate.css

然后再相应的组件中导入

import "animate.css"

接着将transition的name值改为animate__animated animate__bounce,以及设置属性,示例中加的为enter-active-class和leave-active-class,相应的类可以在官网复制粘贴直接使用

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- 如果变化元素只有一个,可以不设置name,如果有多个,为了避免样式冲突,还是设置name -->
    <transition-group
      name="animate__animated animate__bounce"
      :appear="true"
      enter-active-class="animate__shakeX"
      leave-active-class="animate__bounceOut"
    >
      <h1 v-show="!isShow" key="1">你好啊!</h1>
      <h1 v-show="isShow" key="2">你好啊!</h1>
    </transition-group>
  </div>
</template>

<script>
import "animate.css";
export default {
  name: "MyTest",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style>
h1 {
  background-color: aqua;
}
</style>

todolist案例

方法一:在MyItem内改

<template>
  <transition name="democss" appear>
    <li>
      <label>
        <!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props -->
        <!-- <input type="checkbox" v-model="todo.done"/> -->
        <input
          type="checkbox"
          :checked="todo.done"
          @change="handleCheck(todo.id)"
        />
        <span v-show="!todo.isEdit">{{ todo.title }}</span>
        <input
          v-show="todo.isEdit"
          type="text"
          :value="todo.title"
          @blur="handleBlur(todo, $event)"
          ref="inputPart"
        />
      </label>
      <button class="btn btn-danger" @click="handleDelete(todo.id)">
        删除
      </button>
      <button
        v-show="!todo.isEdit"
        class="btn btn-edit"
        @click="handleEdit(todo)"
      >
        编辑
      </button>
    </li>
  </transition>
</template>

<script>
export default {
  name: "MyItem",
  props: ["todo"],
  methods: {
    handleCheck(id) {
      //this.checkTodo(id);
      this.$bus.$emit("checkTodo", id);
    },
    handleDelete(id) {
      //this.deleteTodo(id);
      this.$bus.$emit("deleteTodo", id);
    },
    handleEdit(todo) {
      if (Object.prototype.hasOwnProperty.call(todo, "isEdit")) {
        todo.isEdit = true;
      } else {
        this.$set(todo, "isEdit", true);
      }
      this.$nextTick(function () {
        this.$refs.inputPart.focus();
      });
    },
    //失去焦点回调
    handleBlur(todo, e) {
      todo.isEdit = false;
      if (!e.target.value.trim()) return alert("输入不能为空");
      this.$bus.$emit("updateTodo", todo.id, e.target.value);
    },
  },
};
</script>

<style scoped>
/*item*/
li {
  list-style: none;
  height: 36px;
  line-height: 36px;
  padding: 0 5px;
  border-bottom: 1px solid #ddd;
}
li label {
  float: left;
  cursor: pointer;
}
li label li input {
  vertical-align: middle;
  margin-right: 6px;
  position: relative;
  top: -1px;
}
li button {
  float: right;
  display: none;
  margin-top: 3px;
}
li:before {
  content: initial;
}
li:last-child {
  border-bottom: none;
}
li:hover {
  background-color: #ddd;
}
li:hover button {
  display: block;
}
.democss-enter-active {
  animation: testPart 1s linear;
}
.democss-leave-active {
  animation: testPart 1s linear reverse;
}
@keyframes testPart {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0px);
  }
}
</style>

方法二: 在MyList中修改
由于使用了v-for因此这时候需要用transition-group


<template>
  <ul class="todo-main">
    <transition-group name="democss" appear>
      <MyItem v-for="todo in todos" :key="todo.id" :todo="todo" />
    </transition-group>
  </ul>
</template>

<script>
import MyItem from "./MyItem";

export default {
  name: "MyList",
  components: { MyItem },
  props: ["todos"],
};
</script>

<style scoped>
/*main*/
.todo-main {
  margin-left: 0px;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding: 0px;
}
.todo-empty {
  height: 40px;
  line-height: 40px;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding-left: 5px;
  margin-top: 10px;
}
.democss-enter-active {
  animation: testPart 1s linear;
}
.democss-leave-active {
  animation: testPart 1s linear reverse;
}
@keyframes testPart {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0px);
  }
}
</style>

感觉第二种情况更加清晰点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值