过渡组

到目前为止,我们已经了解了简单组件和元素的 Vue 过渡元素的基础知识,以及对动画的仅自定义 CSS 和仅 JavaScript 支持。接下来,我们将探索如何使用 v-for 在一组组件上应用转换,例如将同时渲染的项目列表。

Vue.js 为此特定目的提供了另一个组件:transition-group 组件。

现在,我们假设 feed 上显示了一个消息列表,并且我们希望向此列表添加一个过渡,以便在每个项目出现在屏幕上时产生一些效果。在 ./src/components/Messages.vue 文件中,让我们用 transition-group 组件包装主容器,并传递我们之前用于过渡(transition)组件的相同属性。它们共享相同的 prop 类型:

<transition-group name="fade">
    <p v-for="message in messages" :key="message" v-show="show">
        {{message}}
    </p>
</transition-group>

我们需要为作为淡入淡出传递的过渡效果设置 CSS 样式效果,遵循与过渡类相同的语法规则:

.fade-enter-active, .fade-leave-active {
    transition: all 2s;
}

.fade-enter, .fade-leave-active {
    opacity: 0;
    transform: translateX(30px);
}

使用 yarn serve 命令运行应用程序后,列表中的项目出现时将具有淡入淡出效果。以下屏幕截图显示了您的屏幕应如何显示:

image 2023 10 16 10 36 02 035
Figure 1. Figure 7.7: Fading of the list item

请注意,与不渲染任何包装容器元素的过渡(transition)组件不同,transition-group 将渲染实际元素,并且您可以使用 tag 属性更改元素标签名称。默认情况下,使用的元素是 span

<transition-group
    name="fade"
    tag="div"
>
    <p v-for="message in messages" :key="message" v-show="show">
        {{message}}
    </p>
</transition-group>

在浏览器中,实际的 HTML 输出将如下所示:

image 2023 10 16 10 38 01 962
Figure 2. Figure 7.8: Transition container element rendered according to the tag attribute

此外,所有转换类将仅应用于具有 v-for 属性的列表项元素,而不应用于包装器。

最后,每个列表项都必须具有 :key 属性,以便 Vue.js 能够索引并知道将转换应用到哪个项目。

我们现在将在列表上创建移动效果。

在转换列表时创建移动效果

除了过渡(transition)组件中提供的所有类之外,transition-group 还有另一个类 v-move,它允许我们在每个项目移动到其位置时添加额外的效果。可以通过 move-class 属性手动分配:

.fade-move {
    transition: transform 2s ease-in;
}

接下来,我们将研究在页面或组件的初始渲染上制作动画。

在初始渲染上制作动画

通常,项目列表将在第一次初始页面加载时显示,并且我们的动画将不起作用,因为该元素已经在视图中。为了触发动画,我们需要使用不同的过渡属性,appear,以在页面加载后立即在初始页面渲染上强制动画:

<transition-group
    appear="true"
    tag="div"
>
    <p v-for="message in messages" :key="message">{{message}}</p>
</transition-group>

我们还可以使用 v-on:after-appearv-on:appearv-on:after-appearv-on:appear-cancelled 设置挂钩,或者我们可以使用以下格式创建自定义类:

<transition-group
    appear="true"
    appear-class="fade-enter"
    appear-active-class="fade-enter-active"
    tag="div"
>
    <p v-for="message in messages" :key="message">{{message}}</p>
</transition-group>

渲染动画是一个常用的功能,可以在许多情况下使用,例如我们在这里所做的组件淡入淡出。 在下一节中,我们将研究用动画对消息列表进行排序。

练习 7.02:用动画对消息列表进行排序

在这个简短的练习中,我们将向消息列表添加附加功能:sorting。 排序(A-Z 或 Z-A)后,列表上会有翻转动画效果。

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

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

  1. 我们将使用与之前相同的组件代码在 Messages.vue 组件中渲染消息。该列表将用 transition-group 组件包装,准备动画。并且不要忘记设置 appear="true",或者只是简短地 appear,以便元素仅在页面加载完成后才进行动画处理:

    <transition-group
        appear
        name="flip"
        tag="div"
    >
        <p v-for="message in messages" :key="message" class="message--item">{{message}}</p>
    </transition-group>
  2. 使用 yarn serve 命令运行应用程序。这将生成以下输出:

    image 2023 10 16 10 46 49 353
    Figure 3. Figure 7.9: Message list before animation
  3. 没有动画,因为我们还没有定义翻转的 CSS 动画样式。我们开始做吧。在 src/components/Messages.vue 的 <style> 部分中,我们将添加 opacity: 0 ,然后将列表中的每个元素垂直(在 Y 轴上)从原始位置重新定位 20px。这应该是元素进入 flip-enter 或即将使用 flip-leave-to 离开过渡的初始阶段:

    <style scoped>
    .flip-enter, .flip-leave-to {
        opacity: 0;
        transform: translateY(20px);
    }
    </style>
  4. 在同一 <style> 部分中,将自定义 CSS 样式添加到每个消息元素(消息项类),并使用 transition: all 2s。这是为了确保元素的过渡效果将在 2 秒内完成所有 CSS 属性:

    .message--item {
        transition: all 2s;
    }
  5. 一旦 flip-move 开始运行,我们只需为变换(之前定义为垂直 20px)添加过渡效果。我们可以完美地看到每条信息的上下移动效果。此外,我们还需要添加 position: absolute(绝对位置),以便在离开阶段的中间位置进行过渡:

    .flip-leave-active {
        position: absolute;
    }
    .flip-move {
        transition: transform 1s;
    }
  6. 接下来我们将添加三个按钮 - 允许从 A 到 Z 排序、从 Z 到 A 排序以及随机洗牌:

    <button @click="sorting()">Sort A-Z</button>
    <button @click="sorting(true)">Sort Z-A</button>
    <button @click="shuffle()">Shuffle</button>
  7. 我们还需要添加基本组件导出代码以及消息源数据。请随意在消息中使用您喜欢的任何内容:

    export default {
        data() {
            return {
                messages: [
                    'Hello, how are you?',
                    'The weather is nice',
                    'This is message feed',
                    'And I am the fourth message',
                    'Chapter 7 is fun',
                    'Animation is super awesome',
                    'Sorry, I didn't know you called',
                    'Be patient, animation comes right up'
                ],
                show: false
            }
        },
    }
  8. 接下来,我们将添加排序和洗牌的逻辑。方法(methods)部分应该位于上一步中创建的组件导出(export)内:

    methods: {
        sorting(isDescending) {
            this.messages.sort();
            if (isDescending) { this.messages.reverse(); }
        },
        shuffle() {
            this.messages.sort(() => Math.random() - 0.5);
        }
    }

单击其中一个按钮后的输出将类似于以下内容:

image 2023 10 16 10 55 03 866
Figure 4. Figure 7.10: Message list during sorting with animation

在本练习中,我们学习了如何根据元素顺序的变化,使用过渡组动态地将翻转动画效果添加到组件列表中。接下来,让我们探讨如何在页面之间导航时应用过渡效果。