.github/workflows/ci.yml

Issue终结者
2025-12-24 23:36
阅读 1921

Vue 生态玩明白了,才敢投大厂前端岗

去年秋招被面到 Vue 响应式原理直接挂掉后,我默默删掉了简历里“精通 Vue”那行字。现在大三下,趁着秋招前最后的窗口期,我把自己关在家里两个月,从零搭了个完整的 Vue3 + TypeScript + Vite 项目,顺便把整个生态摸了个底朝天。今天这篇就当是阶段性复盘——不讲八股文,只聊实战中踩过的坑、调过的动画、和后端联调时差点掀桌的瞬间。


起因:产品经理说要“丝滑交互动效”

事情得从上个月说起。我在远程实习的 startup 团队接了个新需求:做一个类似 Notion 的文档协作工具原型,重点要求“交互丝滑、动画自然”。PM 甚至甩了句:“参考 Figma 那种流畅度。”我表面点头,心里已经翻白眼——Figma 是 Electron + Canvas,咱这 Web 端用 Vue,能一样?但 deadline 在即,只能硬着头皮上。

我本来想直接上 GSAP 或 Anime.js,但转念一想:既然是 Vue 项目,不如深入用好它的生态,看看 Composition API + <Transition> + 自定义指令能不能搞定。结果这一试,直接把我拉进了 Vue 深水区。


为什么没选 React?真不是偏见

很多人问我:“现在大厂不是都用 React 吗?你干嘛死磕 Vue?”
说实话,我 React 也写过(课程项目+小 side project),它确实灵活,生态庞大。但这次选 Vue,一是团队技术栈统一,二是——开发体验真的爽

Vite 冷启动 200ms,HMR 几乎无感;SFC(单文件组件)把 template/script/style 封装在一起,逻辑和视图高度内聚;再加上 Composition API,代码组织比 Options API 清晰太多。尤其在做复杂交互动画时,响应式数据驱动 DOM 变化,比手动操作节点舒服一百倍。

当然,React Hooks 也很强大,但对我这种喜欢“声明式动画”的人来说,Vue 的 <Transition><TransitionGroup> 简直是开箱即用的神器。比如下面这个列表项删除动画:

<template>
  <TransitionGroup name="list" tag="ul">
    <li v-for="item in items" :key="item.id" class="item">
      {{ item.text }}
      <button @click="remove(item.id)">×</button>
    </li>
  </TransitionGroup>
</template>

<style scoped>
.list-move,
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
.list-move {
  transition: transform 0.5s ease;
}
</style>

就这么几行,列表增删就有流畅位移动画。要是用 React,得自己维护 key、用 CSSTransition 或 framer-motion,配置更繁琐。我不是说 React 不好,只是 Vue 在“快速实现精致交互动效”这件事上,对前端友好度拉满


项目架构:从零搭建一个生产级 Vue3 应用

我这次项目托管在 GitHub 上(私有仓库,别找了 😏),结构如下:

my-docs-app/
├── src/
│   ├── components/     # 通用组件(带动画)
│   ├── views/          # 页面级组件
│   ├── composables/    # 自定义组合函数(如 useDrag, useLocalStorage)
│   ├── services/       # API 请求封装
│   ├── stores/         # Pinia 状态管理
│   └── main.ts
├── public/
├── vite.config.ts
└── package.json

关键技术选型:

类别 技术栈 理由
构建工具 Vite 快!快!快!
状态管理 Pinia 更简洁的 Store,TypeScript 支持一流
HTTP 客户端 Axios + interceptors 统一处理 loading、错误、token
动画 Vue 内置 Transition + 自定义指令 减少第三方依赖
UI 框架 无(纯手写 CSS) 为了精准控制动效细节
代码规范 ESLint + Prettier 强迫症必备

特别提一句 Pinia —— 真香!比 Vuex 轻量太多,Store 直接导出函数,不用 modules 嵌套,测试也方便。比如用户状态:

// stores/user.ts
import { defineStore } from 'pinia'
import { api } from '@/services'

export const useUserStore = defineStore('user', () => {
  const profile = ref<User | null>(null)
  const loading = ref(false)

  const fetchProfile = async () => {
    loading.value = true
    try {
      profile.value = await api.get('/user/me')
    } finally {
      loading.value = false
    }
  }

  return { profile, loading, fetchPrfile }
})

和后端联调:那些让我想砸键盘的时刻

前端再炫酷,没数据也是白搭。我们后端用的是 NestJS(TypeScript 写的,还算友好),但接口文档更新永远慢半拍。最崩溃的一次是上周五晚上 11 点,我做好了一个拖拽排序功能,结果发现后端接口居然不支持 PATCH /docs/order,只接受全量替换!

当时真的想冲进 Slack 问后端兄弟:“你是认真的吗?全量替换怎么保证并发安全?!”
最后妥协方案:前端本地先更新顺序,发个 debounced 请求,等后端下周加接口。这就是现实:再好的前端架构,也扛不住后端 API 设计反人类。

不过我也学乖了:现在每次开工前,先和后端对齐 OpenAPI spec,用 Swagger mock 数据。Vite 的 proxy 也配好了:

// vite.config.ts
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})

动画实战:让交互相“呼吸”

回到核心需求——丝滑动画。除了 Vue 内置 Transition,我还写了两个自定义指令来增强体验:

  1. v-fade-in:元素进入时淡入 + 微移
  2. v-draggable:让任意元素可拖拽(配合 useDrag composable)

比如这个卡片组件:

<template>
  <div v-fade-in class="card" v-draggable>
    <slot />
  </div>
</template>

指令实现(简化版):

// directives/fadeIn.ts
export const fadeIn = {
  mounted(el: HTMLElement) {
    el.style.opacity = '0'
    el.style.transform = 'translateY(10px)'
    requestAnimationFrame(() => {
      el.style.transition = 'opacity 0.3s, transform 0.3s'
      el.style.opacity = '1'
      el.style.transform = 'translateY(0)'
    })
  }
}

浏览器兼容性方面,主要测了 Chrome、Safari 和 Firefox 最新版。Edge 基本和 Chrome 一致。移动端用 iOS Safari 测试过,硬件加速开启后帧率很稳(记得给动画元素加 transform: translateZ(0) 触发 GPU)。

性能优化上,避免在 v-for 里放复杂计算;动画尽量用 transformopacity,不触发布局重排。Chrome DevTools 的 Performance 面板帮我揪出了几个掉帧点——原来是某个 watcher 没加 deep: false,导致每次输入都全量 diff。


GitHub 实践:从提交信息到 CI/CD

虽然是个人项目,但我完全按团队标准来:

  • commit message 用 Conventional Commits(feat:, fix:, chore:)
  • 分支策略:main + feature branches
  • PR 模板强制填写改动点、测试方式

还配了简单的 GitHub Actions,跑 lint + typecheck:

name: CI
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
      - run: pnpm install
      - run: pnpm lint
      - run: pnpm type-check

虽然没上自动化部署(穷学生买不起云服务器 😭),但流程走一遍,对工程化理解深了不少。以后面试被问“你们项目怎么保证代码质量”,总算能说出点东西了。


总结:Vue 生态,不止是框架

折腾完这个项目,我对 Vue 的理解从“会用”变成了“知道怎么用好”。它的生态不是一堆零散工具,而是一个高度协同的体系:Vite 提速开发,Pinia 管理状态,Composition API 组织逻辑,内置 Transition 处理动画——各司其职,又无缝衔接。

当然,我也清楚 Vue 的局限:大型团队协作时,React 的灵活性可能更合适;SSR 场景下 Nuxt 虽强,但 Next.js 社区更大。但对我这种喜欢快速产出、注重交互细节的开发者来说,Vue3 + TS + Vite 的组合拳,真的香。

秋招在即,我不再盲目追新框架,而是把一个技术栈吃透。毕竟,能用 Vue 做出媲美 React 的体验,才是真本事

对了,如果你也在准备前端秋招,欢迎来我 GitHub 看代码(Star 一下更好哈哈)。深夜写代码的路上,咱们一起卷!

评论 0

最热最新
暂无评论
Issue终结者Lv.1
0
影响力
0
文章
0
粉丝