vue.js 3.2.22:用useIntersectionObserver实现滑动到div可见时才运行css动画(@vueuse/core@7.0.3)

一,安装所需的库@vueuse/core

liuhongdi@lhdpc:/data/vue/lazy$ npm install --save @vueuse/core

说明:刘宏缔的架构森林是一个专注架构的博客,

网站:https://blog.imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/06/01/vue-js-3-2-22-yong-useintersectionobserver-shi-xian-hua/

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,编写js代码

Ani.vue

<template>
<div>
  
  <div>
  <h3 :ref="refset" class="red-bg-title animate_element" data-animate="bounceIn,0.6s,0.3s">现金表标题一
  </h3>
  <div style="width:640px;position: relative;margin: 0 auto;">
    <div class="title">
      <h4 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,0.4s" >经营活动现金流入小计</h4>
      <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,0.8s" >数值(亿元)</p>
    </div>
    <div class="data-info">
      <div class="part1">
        <h5 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1s">366.26</h5>
        <p :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1.2s">2021H1</p>
      </div>
      <div class="part2">
        <h5 :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.3s">303.87</h5>
        <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.5s">2020H1</p>
      </div>
    </div>
    <div class="graph">
      <p :ref="refset" class="increase-charac animate_element" data-animate="fadeInUp,0.6s,1.6s" >同比增长</p>
      <p :ref="refset" class="increase-num animate_element increase-icon" data-animate="fadeInUp,0.6s,1.8s"><span></span>20.53%</p>
    </div>
  </div>
  </div>
  
  <div>
    <h3 :ref="refset" class="red-bg-title animate_element" data-animate="bounceIn,0.6s,0.3s">现金表标题二
    </h3>
    <div style="width:640px;position: relative;margin: 0 auto;">
      <div class="title">
        <h4 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,0.4s" >经营活动现金流入小计</h4>
        <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,0.8s" >数值(亿元)</p>
      </div>
      <div class="data-info">
        <div class="part1">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1s">366.26</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1.2s">2021H1</p>
        </div>
        <div class="part2">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.3s">303.87</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.5s">2020H1</p>
        </div>
      </div>
      <div class="graph">
        <p :ref="refset" class="increase-charac animate_element" data-animate="fadeInUp,0.6s,1.6s" >同比增长</p>
        <p :ref="refset" class="increase-num animate_element increase-icon" data-animate="fadeInUp,0.6s,1.8s"><span></span>20.53%</p>
      </div>
    </div>
  </div>

  <div>
    <h3 :ref="refset" class="red-bg-title animate_element" data-animate="bounceIn,0.6s,0.3s">现金表标题三
    </h3>
    <div style="width:640px;position: relative;margin: 0 auto;">
      <div class="title">
        <h4 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,0.4s" >经营活动现金流入小计</h4>
        <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,0.8s" >数值(亿元)</p>
      </div>
      <div class="data-info">
        <div class="part1">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1s">366.26</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1.2s">2021H1</p>
        </div>
        <div class="part2">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.3s">303.87</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.5s">2020H1</p>
        </div>
      </div>
      <div class="graph">
        <p :ref="refset" class="increase-charac animate_element" data-animate="fadeInUp,0.6s,1.6s" >同比增长</p>
        <p :ref="refset" class="increase-num animate_element increase-icon" data-animate="fadeInUp,0.6s,1.8s"><span></span>20.53%</p>
      </div>
    </div>
  </div>

  <div>
    <h3 :ref="refset" class="red-bg-title animate_element" data-animate="bounceIn,0.6s,0.3s">现金表标题四
    </h3>
    <div style="width:640px;position: relative;margin: 0 auto;">
      <div class="title">
        <h4 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,0.4s" >经营活动现金流入小计</h4>
        <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,0.8s" >数值(亿元)</p>
      </div>
      <div class="data-info">
        <div class="part1">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1s">366.26</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1.2s">2021H1</p>
        </div>
        <div class="part2">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.3s">303.87</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.5s">2020H1</p>
        </div>
      </div>
      <div class="graph">
        <p :ref="refset" class="increase-charac animate_element" data-animate="fadeInUp,0.6s,1.6s" >同比增长</p>
        <p :ref="refset" class="increase-num animate_element increase-icon" data-animate="fadeInUp,0.6s,1.8s"><span></span>20.53%</p>
      </div>
    </div>
  </div>

  <div>
    <h3 :ref="refset" class="red-bg-title animate_element" data-animate="bounceIn,0.6s,0.3s">现金表标题五
    </h3>
    <div style="width:640px;position: relative;margin: 0 auto;">
      <div class="title">
        <h4 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,0.4s" >经营活动现金流入小计</h4>
        <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,0.8s" >数值(亿元)</p>
      </div>
      <div class="data-info">
        <div class="part1">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1s">366.26</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1.2s">2021H1</p>
        </div>
        <div class="part2">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.3s">303.87</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.5s">2020H1</p>
        </div>
      </div>
      <div class="graph">
        <p :ref="refset" class="increase-charac animate_element" data-animate="fadeInUp,0.6s,1.6s" >同比增长</p>
        <p :ref="refset" class="increase-num animate_element increase-icon" data-animate="fadeInUp,0.6s,1.8s"><span></span>20.53%</p>
      </div>
    </div>
  </div>
  
  <div>
    <h3 :ref="refset" class="red-bg-title animate_element" data-animate="bounceIn,0.6s,0.3s">现金表标题六
    </h3>
    <div style="width:640px;position: relative;margin: 0 auto;">
      <div class="title">
        <h4 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,0.4s" >经营活动现金流入小计</h4>
        <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,0.8s" >数值(亿元)</p>
      </div>
      <div class="data-info">
        <div class="part1">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1s">366.26</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInLeft,0.6s,1.2s">2021H1</p>
        </div>
        <div class="part2">
          <h5 :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.3s">303.87</h5>
          <p :ref="refset" class="animate_element" data-animate="fadeInRight,0.6s,1.5s">2020H1</p>
        </div>
      </div>
      <div class="graph">
        <p :ref="refset" class="increase-charac animate_element" data-animate="fadeInUp,0.6s,1.6s" >同比增长</p>
        <p :ref="refset" class="increase-num animate_element increase-icon" data-animate="fadeInUp,0.6s,1.8s"><span></span>20.53%</p>
      </div>
    </div>
  </div>

</div>
</template>

<script>
import {onMounted} from "vue";
import {useIntersectionObserver} from "@vueuse/core";

export default {
  name: "Ani",
  setup() {

    //初始化列表
    let itemRefs = []
    const refset = el => {
      if (el) {
        itemRefs.push(el)
      }
    }

    //添加监控
    //挂载后
    onMounted(()=>{
      //为各个div添加监控事件
      console.log("onMounted div的数量:"+itemRefs.length);
      for (let i=0;i<itemRefs.length;i++) {
        //console.log(itemRefs[i]);
        useIntersectionObserver(itemRefs[i], ([{ isIntersecting }]) => {
          // 如果target对应的DOM进入可视区,那么该回调函数就触发
          if (isIntersecting) {
            // 被监听的DOM进入了可视区:此时调用接口获取数据;停止继续监听
            stop()
            if (itemRefs[i].dataset.animate !== '') {
              console.log(""+i+"个div已显示");
              //修改背景色
              let ani = itemRefs[i].dataset.animate;
              let arrAni = ani.split(",");

              console.log(arrAni[0]);
              console.log(arrAni[1]);
              console.log(arrAni[2]);

              let style="animation-name: "+arrAni[0]+"; animation-duration: "+arrAni[1]+"; animation-delay: "+arrAni[2]+";"

              //itemRefs[i].dataset.bg = 1;
              itemRefs[i].style = style;
            }
          }
        },{ threshold: 0 })
      }
    })
    
    return {
      refset,
    }
  }
}
</script>

<style>
.animate_element {
  margin:0px;
  position: inherit;
  opacity: 0;
  animation-fill-mode: forwards;
  animation-timing-function: linear;
}

.red-bg-title {
  position: relative;
  width: 612px;
  height: 88px;
  font-size: 54px;
  font-weight: bold;
  border-radius: 50px;
  margin: 0 auto;
  background: #ca312b;
  color: #ffffff;
  text-align: center;
  line-height: 88px;
  box-shadow: 0 10px 10px rgb(244 99 94 / 50%);
}

.red-bg-title:before {
  left: 25px;
}

.red-bg-title:before, .red-bg-title:after {
  content: '';
  display: block;
  position: absolute;
  top: 20px;
  /*margin-top: 25px;*/
  width: 73px;
  height: 49px;
  background: url(https://zsl.p5w.net/home/images/twelve_blade/title-triangle-icon.png) no-repeat;
  background-size: cover;
}

.red-bg-title:after {
  right: 25px;
}

@keyframes mymove
{
  from {top:0px;}
  to {top:200px;}
}

@keyframes bounceIn {
  0% {
    opacity: 0;
    transform: scale(.3);
  }
  50% {
    opacity: 1;
    transform: scale(1.05);
  }
  70% {
    transform: scale(.9);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.title {
  height: 80px;
  line-height: 80px;
  padding: 0 40px;
  overflow: hidden;
  border-bottom: 1px solid #ec6941;
}
.title h4 {
  float: left;
  font-size: 28px;
  color: #333333;
}

.swiper-container {
  margin: 0 auto;
  position: relative;
  overflow: hidden;
  list-style: none;
  padding: 0;
  z-index: 1;
}

@keyframes fadeInLeft {
  0% {
    opacity: 0;
    transform: translateX(-20px);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

.title p {
  float: right;
  font-size: 26px;
  color: #999999;
}

@keyframes fadeInRight {
  0% {
    opacity: 0;
    transform: translateX(20px);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

.data-info {
  display: flex;
  text-align: center;
  align-items: center;
  height: 130px;
}

.data-info .part2 {
  width:50%;
  flex: 1;
}

.data-info .part1 {
  width:50%;
}

.data-info .part1 h5 {
  color: #ec6941;
}

.data-info h5 {
  font-size: 54px;
  font-weight: bold;
}

.data-info p {
  font-size: 28px;
  color: #666666;
}

/*--------------------------------graph--------------------------------------*/

.graph {
  width: 100%;
  height: 372px;
  background-color: #eeeeee;
  text-align: center;
  margin-top: 24px;
  /*line-height: 130px;*/
  margin: 0;
  padding: 0;
}

.graph .increase-charac {
  font-size: 28px;
  color: #666666;
  padding-top: 20px;
}

@keyframes fadeInUp {
  0% {
    opacity: 0;
    transform: translateY(20px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

.increase-icon {
  position: relative;
  font-size: 62px;
  color: #ea441c;
}

.increase-icon span {
  display: inline-block;
  width: 38px;
  height: 51px;
  background: url(https://zsl.p5w.net/home/images/twelve_blade/increase-icon@2x.png) no-repeat;
  background-size: cover;
  margin-right: 10px;
}

</style>

 

三,测试效果

四,查看vue和vueuse的版本

复制代码
liuhongdi@lhdpc:/data/vue/lazy$ npm list vue
lazy@0.1.0 /data/vue/lazy
├─┬ @vue/cli-plugin-babel@4.5.15
│ └─┬ @vue/babel-preset-app@4.5.15
│   └── vue@3.2.22 deduped
├─┬ @vueuse/core@7.0.3
│ ├─┬ @vueuse/shared@7.0.3
│ │ └── vue@3.2.22 deduped
│ ├─┬ vue-demi@0.12.1
│ │ └── vue@3.2.22 deduped
│ └── vue@3.2.22 deduped
└─┬ vue@3.2.22
  └─┬ @vue/server-renderer@3.2.22
    └── vue@3.2.22 deduped
复制代码

 

 
posted @ 2022-05-11 14:55  刘宏缔的架构森林  阅读(373)  评论(0编辑  收藏  举报