Migrating a Quasar v1 app to v2: incremental Vue 2 compat path or full Vue 3 rewrite?
0 reputation · 03 Mar 2025, 10:38 UTC
0 reputation · 03 Mar 2025, 10:38 UTC
Our production app runs on Quasar v1 with Vue 2, and since v1 is in maintenance status we need to move to Quasar v2, which is built on Vue 3. The codebase makes heavy use of QTable with custom slots, QDialog, and the Notify plugin, plus a few third-party app extensions written for v1.
The constraint is that Quasar v2 is not a drop-in upgrade: the CLI split into @quasar/app-vite and @quasar/app-webpack, the config moved from quasar.conf.js to the new quasar.config format, and several component props, events, and v-model conventions changed to match Vue 3. Some of our code also relies on Vue 2 filters and this.$children patterns that have no direct equivalent. It is unclear whether the v1-era app extensions we depend on have v2-compatible releases.
Given these breaking changes, which migration strategy carries less risk for a mid-sized codebase?
Should we first port to Vue 3's migration build while staying on Quasar v1 patterns, or rewrite components directly against Quasar v2 idioms? How do we systematically inventory renamed props and events before touching the build tooling? And what is a practical way to verify QTable and Notify behavior parity after the switch?
29275 reputation · 03 Mar 2025, 19:19 UTC
For a mid-sized codebase, a direct rewrite (porting) to Quasar v2 idioms is the lower-risk path. While a full rewrite sounds daunting, the Vue 3 migration build (compat mode) is designed for Vue-only applications; it does not resolve the breaking changes inherent in the Quasar framework itself. Because Quasar v2 introduces a new CLI, updated configuration formats, and modified component APIs, you would be forced to manage two sets of breaking changes simultaneously if you chose the incremental path.
The Vue 3 migration build allows Vue 2 components to run in Vue 3, but it does not make Quasar v1 components compatible with Quasar v2. Since your app relies heavily on QTable and QDialog, you must update these to the v2 API regardless of the Vue version. Attempting an incremental path often results in a "hybrid state" that increases bundle size and complicates debugging without bypassing the actual work of updating the Quasar components.
this.$children $\rightarrow$ Use refs or a state management store (Pinia).Vue.prototype $\rightarrow$ Use provide/inject or global properties in the Vue 3 app instance.@quasar/app-vite (recommended for faster development) and migrate quasar.conf.js settings to the new quasar.config.js format.v-model implementations (which changed from value/input to modelValue/update:modelValue) and rename props based on the v2 documentation.To ensure behavior parity without manual regression testing of every edge case:
Notify.create() pattern and check that the CSS transition timings match your previous production feel.body-cell-[name]) between v1 and v2. Use a side-by-side browser window with the v1 production site and the v2 dev build, feeding both the same JSON dataset to verify rendering and sorting logic.Missing Diagnostic: Are your third-party app extensions primarily UI-based (Vue components) or logic-based (JavaScript plugins)? If they are deep UI integrations, the rewrite risk increases significantly.
Use comments to ask for clarification. Post a solution as an answer.
29,275 reputation · 03 Mar 2025, 21:35 UTC
A practical pre-build step is to inventory Quasar component bindings before touching @quasar/app-vite or @quasar/app-webpack. In Quasar v2 on Vue 3, QTable v-model targets modelValue instead of value, and pagination emits update:pagination rather than the v1 event names. A global search for :value, v-model, @input and @pagination on QTable, QDialog and Notify usage will surface the places that will break even if Vue 3 migration build is used.
Pair that with a quick scan for Vue 2-only patterns — filters in templates, this.$children, Vue.prototype — to separate Quasar API work from core Vue 3 idiom work. That inventory gives a concrete change set and avoids a hybrid state where build tooling is upgraded but component APIs are still v1.