Skip to content

quasar-v2.30.1

Latest

Choose a tag to compare

@rstoenescu rstoenescu released this 07 Sep 09:35
· 11 commits to dev since this release

Fixes

  • fix(ui): every directive guards its context again in updated/beforeUnmount -> Vue defers a directive's updated to the post-flush queue but runs beforeUnmount synchronously, so a queued updated can outlive the element's unmount and find its context already gone. v2.30.0 dropped the early return that covered this, and the hook threw a TypeError. In production Vue logs it; in development it rethrows, flushJobs never clears currentFlushPromise and nothing reactive is ever flushed again, freezing the app on whatever was painted. Reported for the four touch directives (a QScrollArea inside <keep-alive :include>, dropped from the cache in the same tick it re-renders), the guard is restored across all eleven: v-close-popup, v-intersection, v-morph, v-mutation, v-ripple, v-scroll, v-scroll-fire and v-touch-hold/v-touch-pan/v-touch-repeat/v-touch-swipe (#18543)
  • fix(QInfiniteScroll): decide the first load at mount, not from the observer's opening report -> since the sentinel took over the trigger condition in v2.30.0, the first load waited for the observer's opening report, which lands a frame after mount. An app that fetches its first page from @load and renders a loading placeholder taller than offset while that runs (from its own mounted hook, a nextTick or an async component) had already grown the content by then, so that report read "out of reach" and an observer never re-reports a state that merely holds: @load never fired and the placeholder waited for data nobody had asked for. The first load is decided on mount again, off the DOM as it stands, by the same reach test the observer applies, and it is no longer routed through the debounced poll, so a paused fake clock (Playwright's page.clock) does not hold it back either. A component mounted out of reach stays quiet as before, and the observer still owns every load after the first (#18542)
  • fix(Ripple): the argument and the modifiers follow runtime changes -> v-ripple re-read its argument and modifiers only when the value reference changed and only for an object value, so three things were frozen at mount: v-ripple:[color] with no value never picked up a new color, a modifiers object that changed while the value did not was ignored (QBtn hits this on its own, so toggling its round prop left the ripple starting from the press point instead of the center, or the other way round), and setting the value back to true after an object kept that object's options. All three now re-derive (#18541)
  • fix(utils/is): deepEqual() handles null-prototype objects -> comparing two objects created with Object.create(null) threw, because the valueOf fallback saw a missing method as an override of Object.prototype's and called it. Both conversion fallbacks now require an actual callable on both sides, so null-prototype objects, and objects whose own valueOf/toString is not a function, compare by their keys. Two objects of the same constructor where only one carries such an override are compared key by key too, instead of through that one side's conversion (#18540)
  • fix(QTree): let header slot content size its own icons -> the header-<name> slot defaults styled .q-icon and .q-avatar inside the node header at a specificity that tied with each component's own icon sizing and won on source order, so a QBtn placed in a header slot rendered a fixed 21px icon whatever its size prop said. The defaults are scoped through :where() and lose every tie, while still applying to plain slot icons (#16753)

Donations

Quasar Framework is an open-source MIT-licensed project made possible due to the generous contributions by sponsors and backers. If Quasar is useful in your workflow and you want to support ongoing maintenance, please consider the following: