What migrating a Vuetify 2 dashboard to Vue 3 actually took

2026-11-03来源 dev.to VueEnglish

Vue 2 reached end of life on 31 December 2023. Vuetify 2 followed on 25 January 2025. If your admin panel still runs on them, it gets no security fixes, and every SOC 2 or ISO 27001 review asks why.

To show what the move involves, I migrated a well-known open-source app in public: Creative Tim's Vuetify Material Dashboard (MIT, 1.3k GitHub stars). The full branch is here: https://github.com/SayedEsmail/vuetify-material-dashboard. Every commit handles one concern and lists the breaking changes it fixed, so the commit log reads as the migration plan. I wrote the plan, did the work with an AI coding assistant, and reviewed every change myself at the end.

The starting point

  • Vue 2.6, Vuetify 2.2, Vuex 3, Vue Router 3, Vue CLI 4 on webpack 4.
  • 33 single-file components and 5,620 lines of JavaScript and Vue.
  • 553 lines of custom SASS written against Vuetify 2's internal class names.

The target was Vue 3.5, Vuetify 3, Pinia, Vue Router 4 and Vite.

Step 0: delete before you migrate

Seven of the 33 components could not be reached. Five views had no route, and two components were only used by those views. A form-validation library was registered globally and never used. The test suite still asserted the Vue CLI scaffold text, so it could never pass.

Deleting that first removed a third of the code before any migration work started. It is the cheapest saving in every migration, and an audit finds it in an afternoon.

Why Vuetify 2 projects can't migrate "gradually"

The usual Vue 2 path is the @vue/compat build: run on Vue 3 in compatibility mode, then fix warnings one by one. That path is closed when the app uses Vuetify 2, because Vuetify 2 cannot run on Vue 3 at all. The UI layer has to move in one step.

So the order matters:

  1. Tooling first: Vue CLI to Vite, then the new dependency set.
  2. App bootstrap: createApp, createVuetify, the i18n adapter.
  3. State and routing: Vuex to Pinia, Router 3 to 4. These are mechanical.
  4. Vue-2-only plugins: the chart wrapper had no Vue 3 version, so it became a 56-line local component on Chartist 1.x.
  5. Vuetify, from the outside in: layout shell, then the shared component library, then the views.
  6. The custom CSS layer last.

Where the real work is

Component APIs changed a lot, but those changes are well documented: v-list-item-content is gone, activator slots give props instead of on and attrs, v-tabs-items became v-window. I hit 43 distinct breaking changes and logged each one. That list is now the checklist I run in every audit.

The expensive surprises were elsewhere:

  • Custom CSS on framework internals. 470 lines targeted classes like .theme--light, .v-size--default and .v-card__text. Not one of them exists in Vuetify 3. Nothing errors. The styles silently stop applying.
  • Behaviour that changed without an error. In Vuetify 3, a navigation item linked to / stays highlighted on every page unless you mark it exact. Alerts now clip anything positioned outside them. The build stays green and the UI is subtly wrong.
  • Bugs that were already there. The theme colour picker never reached dark mode because it read a property that was never defined. Turning the sidebar image back on stored the value true instead of an image URL. Neither was caused by the migration, but a migration is when someone finally reads every line.

The result

  • Vue 3.5, Vuetify 3.13, Pinia, Vue Router 4, Vite 8, ESLint 10.
  • 26 components, 3,644 lines of JavaScript and Vue, and 350 lines of SASS in one file.
  • The same 8 routes and the same behaviour, minus the two bugs above.
  • A test suite that runs: every route renders in the full layout with zero Vue warnings.

What I'd tell a team planning this

  1. Run an inventory first. Dead code, undeclared dependencies and tests that can't pass are common, and they change the scope.
  2. Budget for CSS and visual QA, not only for component syntax.
  3. If you use Vuetify 2, plan the UI layer as one cut-over, behind a feature branch, with route-level smoke tests in place before you start.
  4. Decide the target versions up front. Vuetify 4 is out now. Going to Vuetify 3 first is still the shorter step from Vuetify 2, and 3 to 4 is a much smaller change.

If your product still runs on Vue 2, Nuxt 2 or Vuetify 2, I do a fixed-price migration readiness audit: a written report with the dead code, the breaking changes that apply to your codebase, the risks, and a fixed quote for the migration.

Sayed Esmail · https://github.com/SayedEsmail · https://linkedin.com/in/sayed-esmail-khattab

原文:https://www.a8q9.cn/en/article/what-migrating-a-vuetify-2-dashboard-to-vue-3-actually-took-2748cb.html

相关文章