跟着尚硅谷学vue2—进阶版2.0—使用 Vue 脚手架3.0

16. nextTick

1. 总结
  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次 DOM 更新结束后执行其指定的回调。
  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
2. 案例

实现点击点击,输入框自动获取焦点

MyItem.vue
<template>
  <div>
    <li>
      <label>
        <!-- 使用props传参方式改变选中or不选 -->
        <!-- <input
          type="checkbox"
          :checked="todo.done"
          @click="handleCheck(todo.id)"
        /> -->
        <input
          type="checkbox"
          :checked="todo.done"
          @change="handleCheck(todo.id)"
        />
        <!-- 使用v-model方法改变选中or不选 -->
        <!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props,只不过vue没检测到 -->
        <!-- <input type="checkbox" v-model="todo.done" /> -->
        <span v-show="!todo.isEdit">{{ todo.title }}</span>
        <input
          v-show="todo.isEdit"
          type="text"
          :value="todo.title"
          @blur="handleBlur(todo, $event)"
          ref="inputTitle"
        />
      </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>
  </div>
</template>

<script scoped>
import pubsub from "pubsub-js";
export default {
  name: "MyItem",
  // 声明接受todo对象
  props: ["todo"],
  methods: {
    // 勾选or取消勾选
    handleCheck(id) {
      // console.log(id);
      // 通知App组件将对用的todo对象的done值取反
      // this.checkTodo(id);
      this.$bus.$emit("checkTodo", id);
    },
    // 删除
    handleDelete(id) {
      if (confirm("确定删除吗?")) {
        // 通知App组件将对应的todo对象删除
        // this.deleteTodo(id);
        // this.$bus.$emit("deleteTodo", id);
        pubsub.publish("deleteTodo", id);
      }
    },
    // 编辑
    handleEdit(todo) {
      // hasOwnProperty判断对象是否存在
      if (todo.hasOwnProperty.call("isEdit")) {
        console.log("如果todo身上有isEdit");
        todo.isEdit = true;
      } else {
        console.log("如果todo身上没有isEdit");
        this.$set(todo, "isEdit", true);
      }
      this.$nextTick(() => {
        this.$refs.inputTitle.focus();
      });
    },
    // 失去焦点回调(真正智兴修改逻辑
    handleBlur(todo, e) {
      todo.isEdit = false;
      if (!e.target.value.trim()) return alert("输入不能为空");
      console.log("updateTodo", todo.id, e.target.value);
      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;
}
</style>

17. Vue封装的过度与动画

1. 总结
  1. 操作 css 的 trasition 或 animation

  2. vue 会给目标元素添加/移除特定的 class

  3. 作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。

  4. 图示:过度与动画

  5. 写法:

    1. 准备好样式:

    2. 如果设置name则为 name的名称-enter ,如果没设置name则为v

      • 元素进入的样式:
        1. v-enter:进入的起点
        2. v-enter-active:进入过程中
        3. v-enter-to:进入的终点
      • 元素离开的样式:
        1. v-leave:离开的起点
        2. v-leave-active:离开过程中
        3. v-leave-to:离开的终点
    3. 使用<transition>包裹要过度的元素,并配置name属性:

      <transition name="hello">
      	<h1 v-show="isShow">你好啊!</h1>
      </transition>
      
      
    4. 备注:若有多个元素需要过度,则需要使用:<transition-group>,且每个元素都要指定key值。

    5. 基本过渡动画的编码

      1. 在目标元素外包裹

      2. 定义 class 样式

        • 指定过渡样式: transition

        • 指定隐藏时的样式: opacity/其它

  6. 使用插件

    1. 插件: animate.style

    2. 安装:

      Install with npm:

      npm install animate.css --save
      
      

      Install with yarn:

      yarn add animate.css
      
      
    3. Animate.css详细class列表

      Attention seekers
      animate__bounce弹跳
      animate__flash闪光
      animate__pulse脉冲
      animate__rubberBand橡皮筋
      animate__shakeX摇晃X轴
      animate__shakeY摇晃Y轴
      animate__headShake摇头
      animate__swing摇摆
      animate__tada然后
      animate__wobble摇晃
      animate__jello果冻
      animate__heartBeat心跳
      Back entrances
      animate__backInDown后退
      animate__backInLeft后退左
      animate__backInRight后右
      animate__backInUp后退下都上
      Back exits
      animate__backOutDown后退
      animate__backOutLeft后退左
      animate__backOutLeft后退右
      animate__backOutUp后退上
      Bouncing entrances
      animate__bounceIn弹跳
      animate__bounceInDown弹跳向下
      animate__bounceInLeft向左反弹
      animate__bounceInRight右弹跳
      animate__bounceInUp反弹
      Bouncing exits
      animate__bounceOut弹跳
      animate__bounceOutDown弹跳向下
      animate__bounceOutLeft向左反弹
      animate__bounceOutRight弹跳向右
      animate__bounceOutUp弹跳向上
      Fading entrances
      animate__fadeIn淡入
      animate__fadeInDown淡入淡出
      animate__fadeInDownBig淡入淡出大
      animate__fadeInLeft向左淡入淡出
      animate__fadeInLeftBig淡入左大
      animate__fadeInRight向右淡入淡出
      animate__fadeInRightBig淡入右大
      animate__fadeInUp淡入向上
      animate__fadeInUpBig淡入大
      animate__fadeInTopLeft淡入左上
      animate__fadeInTopRight右上淡入淡出
      animate__fadeInBottomLeft淡入左下
      animate__fadeInBottomRight淡入右下
      Fading exits
      animate__fadeOut消退
      animate__fadeOutDown淡出淡出
      animate__fadeOutDownBig淡出淡出大
      animate__fadeOutLeft淡出左
      animate__fadeOutLeftBig淡出左大
      animate__fadeOutRight淡出右移
      animate__fadeOutRightBig淡出右大
      animate__fadeOutUp淡出向上
      animate__fadeOutUpBig淡出向上大
      animate__fadeOutTopLeft淡出左上角
      animate__fadeOutTopRight淡出右上角
      animate__fadeOutBottomRight淡出右下角
      animate__fadeOutBottomLeft淡出左下角
      Flippers
      animate__flip翻动
      animate__flipInX翻转X轴
      animate__flipInY翻转Y轴
      animate__flipOutX翻转输出X轴
      animate__flipOutY翻转输出Y轴
      Lightspeed
      animate__lightSpeedInRight右光速弹动
      animate__lightSpeedInLeft左光速弹动
      animate__lightSpeedOutRight右光速弹动消失
      animate__lightSpeedOutLeft左光速弹动消失
      Rotating entrances
      animate__rotateIn旋转输入
      animate__rotateInDownLeft向左下旋转
      animate__rotateInDownRight向右下旋转
      animate__rotateInUpLeft向左上旋转
      animate__rotateInUpRight向右上旋转
      Rotating exits
      animate__rotateOut旋转输出
      animate__rotateOutDownLeft向左旋转消失
      animate__rotateOutDownRight向右旋转消失
      animate__rotateOutUpLeft向左上旋转消失
      animate__rotateOutUpRight向右上旋转消失
      Specials
      animate__hinge合页
      animate__jackInTheBox旋转闪烁弹动
      animate__rollIn滚入
      animate__rollOut推出
      Zooming entrances
      animate__zoomIn放大
      animate__zoomInDown缩小放大弹出
      animate__zoomInLeft向左放大
      animate__zoomInRight向右放大
      animate__zoomInUp由下向上放大
      Zooming exits
      animate__zoomOut缩小
      animate__zoomOutDown放大缩小消失
      animate__zoomOutLeft向左缩小
      animate__zoomOutRight向右缩小
      animate__zoomOutUp由下向上缩小
      Sliding entrances
      animate__slideInDown向下滑入
      animate__slideInLeft向左滑入
      animate__slideInRight向右滑入
      animate__slideInUp向上滑入
      Sliding exits
      animate__slideOutDown向下滑出
      animate__slideOutLeft向左滑出
      animate__slideOutRight向右滑出
      animate__slideOutUp向上滑出
2. 实例
1. App.vue
<template>
  <div>
    <Test></Test>
    <Test2></Test2>
    <Test3></Test3>
  </div>
</template>
<script>
import Test from "./components/Test";
import Test2 from "./components/Test2.vue";
import Test3 from "./components/Test3.vue";
export default {
  name: "App",
  components: { Test, Test2, Test3 },
  data() {
    return {};
  },
};
</script>
<style></style>

2. Test.vue
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- 动画 -->
    <transition name="hello" appear>
      <h1 v-show="isShow">你好啊!</h1>
    </transition>
  </div>
</template>
<script>
export default {
  name: "Test",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>
<style lang="less" scoped>
h1 {
  background-color: orange;
}

// 如果transition 设置了name 那么标签样式也要用name的参数,如果没有默认为v
// 进入时激活的样式
.hello-enter-active {
  animation: atguigu 0.5s linear;
}
// 离开时激活的样式
.hello-leave-active {
  animation: atguigu 0.5s linear reverse;
}
@keyframes atguigu {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0px);
  }
}
</style>


3. Test2.vue
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- 动画 -->
    <!-- 
        transition只能使用一个元素
        transition-group可以是使用多个元素
     -->
    <!-- <transition name="hello" appear>
      <h1 v-show="isShow">你好啊!</h1>
    </transition> -->
    <transition-group name="hello" appear>
      <h1 v-show="!isShow" key="1">你好啊!</h1>
      <h1 v-show="isShow" key="2">尚硅谷!</h1>
    </transition-group>
  </div>
</template>
<script>
export default {
  name: "Test2",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>
<style lang="less" scoped>
h1 {
  background-color: orange;
  transition: 0.5s linear;
}
// 进入的起点、离开的终点
.hello-enter,
.hello-leave-to {
  transform: translateX(-100%);
}
.hello-enter-active,
.hello-leave-active {
  transition: 0.5s linear;
}
// 进入的终点、离开的起点
.hello-enter-to,
.hello-leave {
  transform: translateX(0);
}
</style>

4. Test3.vue
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <!-- 动画 -->
    <!-- 
        transition只能使用一个元素
        transition-group可以是使用多个元素
     -->
    <!-- <transition name="hello" appear>
      <h1 v-show="isShow">你好啊!</h1>
    </transition> -->
    <transition-group
      name="animate__animated animate__bounce"
      enter-active-class="animate__swing"
      leave-active-class="animate__backOutUp"
      appear
    >
      <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: "Test3",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>
<style lang="less" scoped>
h1 {
  background-color: orange;
}
</style>

18. TodoList案例_动画

MyList.vue
<template>
  <ul class="todo-main">
    <!-- 使用props传参方式改变选中or不选 -->
    <transition-group name="todo" appear="">
      <MyItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj" />
    </transition-group>

    <!-- 使用v-model方法改变选中or不选 -->
    <!-- <MyItem
      v-for="todoObj in todos"
      :key="todoObj.id"
      :todo="todoObj"
    /> -->
  </ul>
</template>

<script scoped>
import MyItem from "./MyItem";
export default {
  name: "MyList",
  components: { MyItem },
  // 声明接收App传递过来的数据
  props: ["todos"],
  data() {
    return {};
  },
};
</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;
}
.todo-enter-active {
  animation: atguigu 0.5s linear;
}
/* 离开时激活的样式 */
.todo-leave-active {
  animation: atguigu 0.5s linear reverse;
}
@keyframes atguigu {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0px);
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值