在 Vue 前端(Vue2/Vue3 通用)载入 JSON 格式的动图
在 Vue 前端(Vue2/Vue3 通用)载入 JSON 格式的动图,核心是使用 Lottie 动画库(由 Airbnb 开发,专门解析 JSON 动画文件)。以下是分步骤的完整实现方案,包含环境配置、组件集成、动画控制等核心功能:
一、核心原理
JSON 格式的动图(如 Lottie 动画)本质是通过 JSON 文件描述动画的关键帧、路径、属性变化等信息,再由 Lottie 库解析并渲染为 SVG/Canvas 动画。相比 GIF/APNG,它支持矢量无损缩放、体积更小、可交互控制(暂停 / 播放 / 反向)。
二、前置准备
-
获取 JSON 动画文件
- 设计工具导出:用 Adobe After Effects 制作动画,通过「Bodymovin」插件导出为 JSON 格式(Bodymovin 插件下载);
- 在线资源:从 LottieFiles 下载现成的 JSON 动画(免费 / 付费资源);
- 本地存放:将 JSON 文件放在项目
src/assets/animations/
目录下(如menu.json
、loading.json
)。
-
安装 Lottie 依赖
Lottie 官方提供lottie-web
库,支持 Vue/React 等框架,执行以下命令安装:# npm 安装 npm install lottie-web --save# yarn 安装 yarn add lottie-web
三、Vue 组件集成(Vue2/Vue3 通用)
以下以「菜单按钮 JSON 动图」为例,实现完整的动画载入与控制逻辑。
1. 基础版:自动播放的 JSON 动图
适用于无需交互的场景(如装饰性动画、加载动画)。
<template><div class="animation-container"><!-- 动画容器:用于承载 Lottie 渲染的动画 --><div ref="lottieRef" class="lottie-box"></div></div>
</template><script>
// 1. 引入 Lottie 库
import lottie from 'lottie-web';export default {name: 'LottieAnimation',data() {return {animationInstance: null, // 存储动画实例(用于后续控制)};},mounted() {// 2. 组件挂载后初始化动画this.initLottie();},beforeUnmount() {// 3. 组件销毁前释放动画资源(避免内存泄漏)if (this.animationInstance) {this.animationInstance.destroy();}},methods: {initLottie() {// 加载 JSON 动画并渲染this.animationInstance = lottie.loadAnimation({container: this.$refs.lottieRef, // 动画容器(通过 ref 获取 DOM)renderer: 'svg', // 渲染方式:svg(推荐,矢量无损)/ canvas / htmlloop: true, // 是否循环播放(true/false/数字,如 3 表示循环3次)autoplay: true, // 是否自动播放// 两种加载 JSON 的方式(二选一):path: require('@/assets/animations/menu.json'), // 方式1:通过路径加载(推荐,支持按需加载)// animationData: require('@/assets/animations/menu.json'), // 方式2:直接导入 JSON 数据(适合小文件)});// 可选:监听动画事件(如播放完成、帧变化)this.animationInstance.addEventListener('complete', () => {console.log('动画播放完成(仅非循环时触发)');});},},
};
</script><style scoped>
.animation-container {/* 父容器样式,根据布局调整 */display: flex;align-items: center;justify-content: center;padding: 20px;
}.lottie-box {/* 动画尺寸:与设计稿一致,支持百分比/固定像素 */width: 60px; height: 60px;cursor: pointer; /* 如需点击交互,添加指针样式 */
}
</style>
2. 进阶版:可交互控制的 JSON 动图
适用于需要手动控制的场景(如点击切换动画状态、暂停 / 播放)。
<template><div class="interactive-animation"><!-- 动画容器 --><div ref="lottieRef" class="lottie-box" @click="toggleAnimation"></div><!-- 控制按钮 --><div class="control-buttons"><button @click="playAnimation">播放</button><button @click="pauseAnimation">暂停</button><button @click="reverseAnimation">反向播放</button></div></div>
</template><script>
import lottie from 'lottie-web';export default {name: 'InteractiveLottie',data() {return {animationInstance: null,isPlaying: true, // 标记当前是否在播放};},mounted() {this.initLottie();},beforeUnmount() {if (this.animationInstance) {this.animationInstance.destroy();}},methods: {initLottie() {this.animationInstance = lottie.loadAnimation({container: this.$refs.lottieRef,renderer: 'svg',loop: false, // 关闭自动循环(手动控制)autoplay: true,path: require('@/assets/animations/menu.json'),});// 监听播放状态变化this.animationInstance.addEventListener('play', () => {this.isPlaying = true;});this.animationInstance.addEventListener('pause', () => {this.isPlaying = false;});},// 1. 点击动画容器切换播放/暂停toggleAnimation() {if (this.isPlaying) {this.animationInstance.pause();} else {this.animationInstance.play();}},// 2. 播放动画playAnimation() {this.animationInstance.play();},// 3. 暂停动画pauseAnimation() {this.animationInstance.pause();},// 4. 反向播放动画reverseAnimation() {this.animationInstance.setDirection(-1); // 设置方向:-1 反向,1 正向this.animationInstance.play();},},
};
</script><style scoped>
.interactive-animation {display: flex;flex-direction: column;align-items: center;gap: 15px;padding: 20px;
}.lottie-box {width: 80px;height: 80px;
}.control-buttons {display: flex;gap: 10px;
}button {padding: 6px 12px;border: 1px solid #1890ff;background: #fff;color: #1890ff;border-radius: 4px;cursor: pointer;transition: all 0.3s;
}button:hover {background: #1890ff;color: #fff;
}
</style>
四、关键配置说明
Lottie 的 loadAnimation
方法支持以下核心参数,根据需求调整:
参数名 | 类型 | 说明 |
---|---|---|
container | DOM 元素 | 必选,动画渲染的容器(通过 Vue 的 ref 获取) |
renderer | 字符串 | 可选,渲染方式:svg (推荐,矢量无损)、canvas (性能好)、html |
loop | 布尔 / 数字 | 可选,是否循环:true (无限循环)、false (仅播放一次)、3 (循环 3 次) |
autoplay | 布尔 | 可选,是否自动播放:true (默认)、false |
path | 字符串 | 可选,JSON 文件路径(如 require('@/assets/animations/xxx.json') ) |
animationData | JSON 对象 | 可选,直接传入 JSON 数据(适合小文件,避免额外请求) |
name | 字符串 | 可选,动画名称(用于多动画管理) |
五、常见问题解决
-
JSON 动画加载失败
- 检查路径:确保
path
中的 JSON 文件路径正确(如@/assets/animations/menu.json
,@
对应src
目录); - 检查文件格式:确保 JSON 文件语法正确(可通过 JSON 校验工具 验证);
- 跨域问题:若 JSON 文件放在 CDN 上,需确保服务器开启 CORS 跨域支持。
- 检查路径:确保
-
动画尺寸异常
- 给
lottie-box
容器设置固定宽高(如width: 100px; height: 100px
),避免自适应导致拉伸; - 通过 Lottie 实例调整尺寸:
this.animationInstance.setSize(120, 120); // 动态设置宽高(单位px)
- 给
-
Vue3 中
this.$refs
获取不到 DOM
Vue3 组合式 API 中需用ref
函数获取 DOM,示例:<script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import lottie from 'lottie-web';const lottieRef = ref(null); // 替代 Vue2 的 this.$refs.lottieRef let animationInstance = null;onMounted(() => {animationInstance = lottie.loadAnimation({container: lottieRef.value, // 注意:Vue3 需用 .value 获取 DOMpath: require('@/assets/animations/menu.json'),loop: true,autoplay: true,}); });onBeforeUnmount(() => {if (animationInstance) animationInstance.destroy(); }); </script>
六、总结
- 核心流程:安装
lottie-web
→ 准备 JSON 动画文件 → 组件中通过lottie.loadAnimation
初始化 → (可选)添加交互控制; - 优势:矢量无损缩放、体积小、可交互、跨平台(Web / 移动端通用);
- 适用场景:按钮动效、加载动画、广告 Banner、页面过渡动画等。
按照以上步骤,即可在 Vue 前端轻松载入并控制 JSON 格式的动图,替代传统的静态图片或低质量动图。