除了 Vue 内置的一系列指令 (比如 v-model
或 v-show
) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。下面以元素平滑上移动画指令为例说明。
1、新建指令处理文件 vSlideIn.js
const DISTANCE = 80;
const DURATION = 500;
const map = new WeakMap();
const ob = new IntersectionObserver(entries =>{
for(const entry of entries){
if(entry.isIntersecting){
// 播放动画
const animation = map.get(entry.target);
animation.play();
// 取消观察
ob.unobserve(entry.target);
}
}
})
/**
* 判断元素是否位于视窗下方
*
* @param {HTMLElement} el - 需要判断的元素
* @returns {boolean} 如果元素位于视窗下方则返回true,否则返回false
*/
function isBelowViewport(el) {
const rect = el.getBoundingClientRect();
return rect.top > window.innerHeight;
}
export default {
/**
* 挂载元素并应用动画效果
*
* @param {HTMLElement} el - 需要挂载的元素
*/
mounted(el) {
if(!isBelowViewport(el)){
return;
}
const animation = el.animate(
[
{
transform: `translateY(${DISTANCE}px)`,
opacity: 0.5,
},
{
transform: `translateY(0)`,
opacity: 1,
},
],
{
duration: DURATION,
easing: "ease-out",
fill: "forwards",
}
);
// 初始化时动画不播放,等元素进入视口再播放
animation.pause();
map.set(el, animation);
// 监听元素是否进入视口
ob.observe(el);
},
unmounted(el) {
ob.unobserve(el);
},
};
2、在main.js中全局注册指令
import vSlideIn from './plugins/vSlideIn'
const app = createApp(App)
app.directive('slide-in', vSlideIn);
app.mount('#app')
3、在需要应用动画的元素中应用指令
<div v-slide-in></div>
评论区