JavaScript 钩子

正如我们在上一节中了解到的,我们可以使用自定义过渡类来集成外部第三方 CSS 动画库来实现样式效果。 但是,有些外部库不是基于 CSS,而是基于 JavaScript,例如 Velocity.js 或 GreenSock Animation API (GSAP),它们需要使用 JavaScript 事件和外部动画处理程序来设置挂钩。

为了在 Vue 应用程序中使用 Velocity.js 或 GSAP 库,您需要使用 npm installyarn add 命令单独安装它们,如下所示:

  • 要安装 Velocity.js,请使用以下命令:

    npm install velocity-animate
    #Or
    yarn add velocity-animate
  • 要安装 GSAP,请使用以下命令:

    npm install gsap
    #or
    yarn add gsap

作为 Vue.js 组件意味着转换组件支持将自定义处理程序作为 props 绑定到事件列表。 考虑以下示例:

<transition
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
>
    <h1 v-if="show">{{ msg }}</h1>
</transition>

我们以编程方式将动画方法绑定到转换元素上的相应事件:

  • beforeEnter 是插入组件之前的动画状态——类似于 v-enter 阶段。

  • Enter 用于整个进入阶段的动画—类似于 v-enter-active 阶段。

  • 在整个离开(leave)阶段播放动画。这与 v-leave-active 阶段类似。

我们需要在 HelloWorld.vue 组件配置的方法(methods)部分中定义这些事件处理程序:

<script>
export default {
    name: 'HelloWorld',
    props: {
        msg: String
    },
    data() {
        return {
            show: false
        }
    },
    methods: {
        beforeEnter() {
        //...
        },
        enter() {
            //...
        },
        leave() {
            //...
        }
    }
}
</script>

在此示例中,我们将使用 GSAP 库提供的 TweenMax 和 TimelineMax 功能创建动画事件,如下所示:

beforeEnter(el) {
    el.style.opacity = 0;
},
enter(el, done) {
    TweenMax.to(el, 2, {
        opacity: 1,
        fontSize: '20px',
        onComplete: done
    })
},
leave(el, done) {
    const tl = new TimelineMax({
        onComplete: done
    });
    tl.to(el, {rotation: -270,duration: 1, ease: "elastic"})
    .to(el, {rotation: -360}).to(el, {
        rotation: -180,
        opacity: 0
    });
}

对于 TweenMax 和 TimelineMax 来说,to() 动画触发方法的语法非常简单:

TimelineMax.to(<element>, <effect properties>, <time position>)
TweenMax.to(<element>, <effect properties>, <time position>)

大多数 effect properties 有与 CSS 类似的语法,因此学习和使用它们并不困难。此外,我们必须将从事件发射器接收到的 enter 和 leave 等事件的 Done 回调传递给 onComplete 以确保它被触发,并且钩子不会被同步调用。另请注意,所有事件发射器还传递 el,它是指向当前要使用的过渡元素的指针。

除了这三个事件之外,我们还可以根据动画和过渡的复杂程度绑定其它事件,例如 afterEnterenterCancelledbeforeLeaveafterLeaveleftCancelled

请注意,如果您仅使用 JavaScript 进行过渡,强烈建议添加 v-bind:css="false" (或 :css="false")。这是为了防止 Vue.js 检测和应用任何相关的 CSS,从而避免意外的转换干扰:

<transition
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
    :css="false"
>
<h1 v-if="show">{{ msg }}</h1>

在本节中,我们了解了如何将外部 JavaScript 库用于动画。 我们使用 GSAP 库实现了一个简单的补间,利用其 TweenMax 和 TimelineMax 函数。

现在让我们学习如何使用动画效果添加新消息。

练习 7.01:添加带有动画效果的新消息

我们将创建一个消息编辑器,用户将在其中撰写并提交新消息。新消息将立即显示,并具有从右滑动的动画效果。

要访问本练习的代码文件,请参阅 https://packt.live/338ZXJv

在开始本练习之前,请运行 vue create 命令来生成 Vue 入门项目。

  1. 首先创建一个名为 MessageEditor.vue 的新组件,位于 /src/components/ 文件夹中。在此组件中, <template> 将包含两个部分:textarea,用于撰写新消息并带有提交按钮;以及 section,其中将显示新撰写的消息:

    <template>
        <div>
            <div class="editor--wrapper">
                <textarea ref="textArea" class="editor"></textarea>
                <button @click="onSendClick()" class="editor--submit">Submit</button>
            </div>
            <section v-if="message" class="message--display">
                <h4>Your saved message: </h4>
                <span>{{message}}</span>
            </section>
        </div>
    </template>
  2. 接下来,用过渡(transition)元素包裹整个消息部分,为我们的动画做好准备。

    <transition name="slide-right">
        <section v-if="message" class="message--display">
            <h4>Your saved message: </h4>
            <span>{{message}}</span>
        </section>
    </transition>
  3. 我们需要带有更改消息文本的方法的导出(export)组件。添加以下代码:

    <script>
    export default {
        data() {
            return {
                message: ''
            }
        },
        methods: {
            onSendClick() {
                const message = this.$refs.textArea.value;
                this.message = message;
                this.$refs.textArea.value = '';
            }
        }
    }
    </script>
  4. 接下来,我们将使用以下命令在样式(style)部分中使用 @keyframes 定义向右滑动(slide-right)的动画效果:

    <style scoped>
    @keyframes slide-right {
        100% {
            transform: translateX(0)
        }
    }
    </style>

    这意味着它将水平(在 X 轴上)具有此效果的元素重新定位到原始起点 (0,0)。

  5. 现在我们将定义两个类,一类用于从左向右滑动(slideright),一类用于相反方向(slide-left):

    .slide-right {
        animation: 1s slide-right 1s forwards;
        transform:translateX(-100%);
        transition: border-top 2s ease;
    }
    
    .slide-left {
        animation: 1s slide-right 1s reverse;
        transform:translateX(-100%);
    }
  6. 添加 border-top:0 作为向右滑动过渡的起点,以对此部分的 border-top 产生一些效果:

    .slide-right-enter {
        border-top: 0;
    }
  7. 接下来,利用我们学到的自定义转换类的知识,让我们将 enterActive 绑定到 slide-right 类,并类似地将 leave-active 绑定到 slide-left 类。这三个属性被添加到步骤 2 中创建的过渡(transition)元素中:

    <transition
        name="slide-right"
        enter-active-class="slide-right"
        leave-active-class="slide-left"
    >
    
    # Add CSS stylings using CSS Flexbox to make the editor look nice:
    
    .editor--wrapper {
        display: flex;
        flex-direction: column;
    }
    
    .editor {
        align-self: center;
        width: 200px;
    }
    
    .editor--submit {
        margin: 0.5rem auto;
        width: 50px;
        align-self: center;
    }
    
    .message--display {
        margin-top: 1rem;
        border-top: 1px solid lightgray;
    }
  8. 使用 yarn serve 命令运行应用程序。

    这将生成一个组件,该组件将显示带有滑动动画效果的键入消息,如图 7.4 所示:

    image 2023 10 16 10 28 41 817
    Figure 1. Figure 7.4: Message Editor text area

下面的屏幕截图显示了消息组件如何以从左到右滑动的动画效果出现:

image 2023 10 16 10 29 51 865
Figure 2. Figure 7.5: Message in transition for display

从左侧启动动画后,组件应停止在中心位置,如图 7.6 所示:

image 2023 10 16 10 30 47 929
Figure 3. Figure 7.6: Message after the animation

本练习帮助您习惯 CSS 中的一些变换效果,例如 translateX 和 transition。它还演示了向 Vue 应用程序中的元素添加动画是多么容易。对于同一组中的多个元素(例如列表)进行转换怎么样? 我们将在下一个主题中找到答案。