这是个啥?
@vueuse/motion 本质上是对Popmotion.js的vue版本的封装。也即它实际上是一个实现动画效果的库。对于常规的动画,我们可以使用CSS的 transition/animation 结合 <Transition>、<TransitionGroup>去实现,但如果对动画有更高的需求,比如想要实现一些自然效果(小球碰撞会弹几下之类的)效果,原生CSS便无法实现,这个时候就需要用JS来实现,而Popmotion.js就是对这些“自然效果”动画的封装。
Popmotion 的核心就是让用户声明式的声明动画,而它则负责将实现动画所需的每一帧的变化返回给用户,让用户根据其返回的每帧变化去修改元素的style以此实现动画效果。
@vueuse/motion 便是对Popmotion的封装,其将Popmotion封装为useMotion(el,animationOptions)这种更契合Vue组合式函数的写法。它还提供对directive的支持,允许通过 v-motion-slide-right 这样的语法去应用动画。
它还额外的实现了一些元素状态的动画,visible(元素可见性动画)、hovered(元素hover状态时的动画)、tapped(鼠标在元素上按住时的动画)、focused(元素获得焦点时的动画)。
听你介绍,它不挺好的嘛!
好个屁,现在就让我一一列举它的不好。
-
巨坑:这个库的文档完成度并不高,看完官方文档你甚至不知道要怎么使用它。你必须阅读一番源码,否则你hold不住这个库。
-
在 setup 中使用 directive 语法,官网没有介绍,只有在 options 语法才有介绍(但有错):
//这是它官方文档的介绍,但这是错误的,directive 在源码中并不存在,它改名为了:MotionDirective。
//正确的引入方法是:
//import { MotionDirective as motion } from '@vueuse/motion'
//如果你以为 MotionDirective 是大写开头,然后你就 new MotionDirective(...).
//那么你就会发现报错,它并没有遵守 class 以大写开头的风俗.
import { directive as motion } from '@vueuse/motion'
export default {
directives: {
motion: motion(),
},
}
//-----------------------------------
//如果你使用的是 setup 的语法,那么你应该这样使用
import { MotionDirective as createDirective } from '@vueuse/motion'
const vXXX = createDirective({
//动画相关配置
})
- 你以为
<div v-xxx />就可以让它应用上动画,但实际上它的动画只应用了一半。实际上你这样写只能够在元素 enter 阶段应用上动画,而 leave 阶段是没有动画的,如果你使用 v-if 控制元素的显示与隐藏,那么你就会发现:入场有动画,离场没动画。
怎么解决,官网没给你说!(github有人提问也没得到回答)
实际上,这是由于 directive 的问题,因为 directive 提供的钩子并没有“应用完动画再销毁组件”的监听提供,所以directive天然就做不到在v-if 切换间去应用离开动画。
提供该钩子的地方只有
<Transition>组件,因此你如果希望应用离开动画,你就需要用<Transition>进行包裹,并在其上使用@leave对离开进行处理。具体语法如下:
//你可能疑问el上啥时候添加的 .motionInstance,那其实是 v-motion-slide-right 指令添加的。
//实际上,它不应该直接向 el 上添加 motionInstance 属性的,这显然是一种“污染”
//更恰当的方法其实是使用Symbol添加,然后再暴露一个 getMotionInstance(el) 的方法去给用户
//以避免变量污染的发生,但很可惜的是,在源码上它没有这样做。
<Transition @leave="(el,done) => el.motionInstance.leave(done)">
<div v-motion-slide-right />
<Transition>
总而言之,它的官方文档很多问题都没有讲明白,你如果入坑,那你看文档是学不会如何去使用它的,你需要跑去看源码。在更好的官方文档出现前,它是一个坑。
ps: 我也想为这个开源库做些贡献,但墙太高。我访问github能把自己气死。
本文的产生基于 @vueuse/motion v2.0.0(2023年9月5日还处于该版本)版本的源码阅读,可能具有时效性。
时过境迁,可能文档会变得更好,如果你想要入坑,那么你应该先去看看它的官方文档,说不定当时的文档已经变得对用户更加友好。