利用Vue自定义指令(directives)实现全站动画效果

grtsinry43
10/13/2024
253 views
预计阅读时长 10 分钟

AI Summary

Powered By DeepSeek-R1
|

最近一直在学习 React 高阶知识,因此对于主页的开发再一次停滞了,主要也是一段时间内没有找到什么灵感,今天空闲时间打开又添加了一些另外的功能,其中包括了折腾了好久的主页加载 Spring (不是那个 Spring 啦)弹簧效果和模糊效果。

<!--more-->

最后的效果在 Grtsinry43 的个人主页

(最近还会考虑继续更新,哭)

环境准备

这里我的网站是使用 Nuxt.js 开发的,使用了"nuxt": "^3.12.4",于是就可以使用 Vue.js 的所有语法和写法,当然也包括自定义指令啦!这就为我们的集成添加了可行性

前置知识

首先我们要知道 Vue 中的指令是类似v-xxx的形式,比如我们平时常用的 v-model v-for 等等都是其提供的指令,当然也为我们保留了自定义的能力。

问题引入

在标准 Vue/Vue+Vite 项目中,其往往位于 /directives 路径,在我们自定义之后在 main.js/main.ts 文件中引入即可

js
1import { createApp } from 'vue';
2import App from './App.vue';
3import scrollSpring from '@/directives/scrollSpring';
4
5const app = createApp(App);
6
7app.directive('scroll-spring', scrollSpring);
8
9app.mount('#app');

而在 Nuxt.js项目中,其主 app 对象创建与挂载,以及 SSR 实现等都是由框架统一管理,为了引入里定自定义指令,我们要借助 nuxt 强大的插件系统。

问题解决

我们可以参考对应的文档: Vue指令

其给出了这样一段示例

js
1export default defineNuxtPlugin((nuxtApp) => {
2  nuxtApp.vueApp.directive('focus', {
3    mounted (el) {
4      el.focus()
5    },
6    getSSRProps (binding, vnode) {
7      // 你可以在这里提供SSR特定的props
8      return {}
9    }
10  })

由于我们无需单独处理 SSR 部分,直接引入插件注册指令即可,Nuxt 会自动扫描并加载 /plugins 路径的文件,无需手动添加。

实现这段动画的大致思路就是,首先所有元素默认 opacity 为 0,并且有向下的位移,当元素移动到视口内即添加标签设置为可见,并恢复位置,当然也可以配合 filter blur 等实现模糊渐显的效果,于是写好如下 css

css
1/* 初始状态,元素处于下方且不可见,并带有模糊效果 */
2.scroll-item {
3  opacity: 0;
4  filter: blur(10px); /* 元素模糊 25px */
5  transform: translateY(20px); /* 元素初始位移 20px */
6  transition: transform 0.5s ease-out, opacity 0.5s ease-out, filter 0.5s ease-out; /* 为 filter 添加动画 */
7}
8
9/* 当元素进入视口时,透明度变为 1,模糊度变为 0,且上移回原位 */
10.scroll-in {

有了思路之后就写好对应的指令 js
/plugins/scrollSpring.js

js
1// 导出一个 Nuxt 插件
2export default defineNuxtPlugin((nuxtApp) => {
3    // 定义一个自定义指令 'scroll-spring'
4    nuxtApp.vueApp.directive('scroll-spring', {
5        // 当元素被挂载到 DOM 中时调用的钩子
6        mounted(el) {
7            // 设置 Intersection Observer 的选项
8            const options = {
9                root: null, // 使用浏览器视口作为根元素
10                rootMargin: '0px', // 根元素的边距

这里我们利用 Intersection Observer ,当元素进入视口触发回调添加类名,移出视口则去掉类名

接下来我们只要在对应的元素引入就可以啦!
注意 scroll-itemv-scroll-spring 缺一不可,前者负责决定开始状态,后者是动画和结束效果

这里简单贴一个代码片段,也可以参考我主页对应的仓库~
/pages/index.vue

vue
1<div class="slogan font-jb-mono scroll-item" v-scroll-spring>
2          <p>Coding,</p>
3          <p>build a better world</p>
4          <p>together!</p>
5        </div>
6        <span class="slogan-cn scroll-item" v-if="locale === 'zh'" v-scroll-spring>{{ t('slogan.cn') }}</span>
7        <br/>
8        <div class="button-container scroll-item" v-scroll-spring>
9          <UButton to="https://github.com/grtsinry43" target="_blank"
10                   icon="i-grommet-icons:github" style="vertical-align: -4px"

最后效果

https://blogoss.grtsinry43.com/uploads/24/10/dfd9b723931112b166843ff4b28d68fa.gif/improved

COPYRIGHT
作者grtsinry43
版权年份© 2024
许可协议

利用Vue自定义指令(directives)实现全站动画效果》采用知识共享署名 4.0 国际许可协议

转载请注明出处并遵循 CC BY 许可协议条款

相关推荐

折腾记录|使用 Nuxt.js 重写个人主页,使用 SSR 优化 SEO ,实现一些期待已久的效果

在 22 年刚创建个人主页的时候,由于我的技术水平不够,只能用一些 wordpress type...

grtsinry43
9/19/2024
227
0
1
用一个月的时间写一个自己的博客系统——Grtblog的技术介绍

用一个月的时间写一个自己的博客系统——Grtblog的技术介绍

终于,历时一个多月的开发 ~~bug~~ 和测试,这个目前问题很多很不成熟很难用的系统终于上线了.....

grtsinry43
12/14/2024
1022
9
9

学习分享|跨域解决、安卓开发探索、油猴脚本探索

最近学习的一些内容,包括跨域问题及其解决方案,安卓开发的简单探索,OpenAI的api做了个小插...

grtsinry43
6/10/2024
105
2
2

六月初至七月中旬|前端学习简要总结,生活的小回顾

在这段时间里我通过完成多个项目,深入学习了前端和全栈开发的技术。主要使用了 Vue3、C++ W...

grtsinry43
7/12/2024
155
1
1
B 站直播弹幕的 WebSocket 获取尝试与抽奖程序实现

B 站直播弹幕的 WebSocket 获取尝试与抽奖程序实现

网上对于 B 站的直播 ws 协议研究已经很多了,但是一是相互 copy 未形成完整的解决方案,二是...

grtsinry43
1/17/2025
439
0
3
COMMENT 7273220598938079232

发表评论

来这里畅所欲言吧!
支持 Markdown 语法 0 / 3000

网站运行时间

0
0
0
0

在风雨飘摇之中

感谢陪伴与支持

愿我们不负热爱,继续前行