vue3自定义指令——元素平滑移动

vue提供一个用户可以高度自定义的指令入口directives
利用这个入口我们实现一个常见的元素平滑移动的自定义指令 ‘sl
首先我们结合指令创建一个多元素的界面:
vue3自定义指令——元素平滑移动_第1张图片
这个场景我们在很多网站,商城都有见过,特别对于移动端的清单类界面
我们的终极目标是在滚动的过程中出现在视口的元素移动,而并不是所有的元素都在移动

平滑移动

有了目标之后我们就可以分解一下我们codeing的过程,

  1. 创建一个基础的指令
  2. 选则一个合适的方式去建立一个高效的运行动画
  3. 如何获取到进入视口的元素
  4. 找到视口元素并让它移动

s1创建一个基础的指令文件

//移动的距离
const DISTANCE : number = 150;

const derDve = {
    
    mounted(el:any){
    
    el.style.transform=`translateY(${DISTANCE}px)` 
  }
}
export default derDve

s2指令内容根据分解的需求变更

  1. 指令使用的过程不应影响到原始元素的属性特征 el.style 方式会导致元素原有的样式出现变更
  2. 指令的使用应该具有兼容性和高效的复用价值

动画方式创建一个平滑指令

const derDve = {
    mounted(el:any){
     //动画方式创建
    const animation = el.animate([
        {
            transform:`translateY(${DISTANCE}px)`,
            opacity:0.5
        },
        {
            transform:'translateY(0)',
            opacity:1
        }
    ],
        {
            duration:DURATION,
            easing:'ease'
        }
    );
    //初始状态下动画应该是停止状态
       animation.pause();
    },
}
export default derDve

s3一个好用的视口元素检测WebAPI IntersectionObserver

IntersectionObserver 一个浏览器自带的用于检测元素与视口是否有交集的api 接收两个参数,[callback,option] 详细配置可自行百度

有了这个api之后我们就可以对上述指令再次进行修改

//移动的距离
const DISTANCE : number = 150;
//动画时间
const DURATION : number = 1000;

//创建一个动画保存对象

const cations =new  WeakMap(); //使用弱映射防止内存泄露
//创建一个视口元素监听
const ob= new IntersectionObserver(entries =>{
    for(const  entry of entries){
        if(entry.isIntersecting){
         const animation=cations.get(entry.target);
         animation.play();
         ob.unobserve(entry.target)
        }
    }
})
const derDve = {
    mounted(el:any){
     //动画方式创建
    const animation = el.animate([
        {
            transform:`translateY(${DISTANCE}px)`,
            opacity:0.5
        },
        {
            transform:'translateY(0)',
            opacity:1
        }
    ],
        {
            duration:DURATION,
            easing:'ease'
        }
    );
       animation.pause();
       cations.set(el,animation);
       ob.observe(el);
    },
    unmounted(el:any){
      ob.unobserve(el)
    }
}
export default derDve

业务中使用也很简单

 <li v-for="(item,index) in list" class="_cl_row" v-sl v-bg>{{item}}</li>
import derDve from "../../utils/silderAntiom";
import color from "../../utils/randomColor";
 directives: {
         sl:  derDve, //平滑移动的指令
         bg:  color  //随机颜色指令
     },
      setup(){

         const list : Array<number> =[1,2,3,4,5,6,7,8,9,10,11,12]
       }

你可能感兴趣的:(前端,javascript,vue.js)