quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.9k stars 3.51k forks source link

v-ripple crash with vue 3.2.32+ with composition API #13732

Closed NGPixel closed 2 years ago

NGPixel commented 2 years ago

What happened?

Using vue 3.2.32 or later and the vue composition API (<script setup>), adding v-ripple to an element such as q-item results in a crash with error TypeError: Cannot read properties of undefined (reading 'config')

The workaround, as found by @Trinovantes (https://github.com/quasarframework/quasar/issues/13154#issuecomment-1113273509), is to expose $q via defineExpose() in any component where v-ripple is used:

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()
defineExpose({ $q })

The components that accept v-ripple should be modified to automatically expose $q so that we don't have to use this workaround.


⚠️🛑 This issue was originally discussed in #13154 but was closed since the specific issue from the original post was fixed, but not v-ripple, hence this new issue. 🛑 ⚠️

What did you expect to happen?

v-ripple should work without the workaround detailed above.

Reproduction URL

https://github.com/NGPixel/broken-quasar-vripple-proof

How to reproduce?

  1. Clone the repo above
  2. Run yarn
  3. Run yarn dev

Flavour

Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)

Areas

Directives (quasar)

Platforms/Browsers

Firefox, Chrome, Safari, Microsoft Edge

Quasar info output

Operating System - Linux(5.10.102.1-microsoft-standard-WSL2) - linux/x64
NodeJs - 18.2.0

Global packages
  NPM - 8.9.0
  yarn - 3.2.0
  @quasar/cli - undefined
  @quasar/icongenie - Not installed
  cordova - Not installed

Important local packages
  quasar - 2.7.2 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
  @quasar/app-vite - 1.0.2 -- Quasar Framework App CLI with Vite
  @quasar/extras - 1.14.0 -- Quasar Framework fonts, icons and animations
  eslint-plugin-quasar - Not installed
  vue - 3.2.37 -- The progressive JavaScript framework for building modern web UI.
  vue-router - 4.0.16
  pinia - 2.0.14 -- Intuitive, type safe and flexible Store for Vue
  vuex - 3.5.1 -- state management for Vue.js
  vite - 2.9.1 -- Native-ESM powered web dev build tool
  eslint - 8.18.0 -- An AST-based pattern checker for JavaScript.
  electron - Not installed
  electron-packager - Not installed
  electron-builder - Not installed
  register-service-worker - 1.7.2 -- Script for registering service worker, with hooks
  @capacitor/core - Not installed
  @capacitor/cli - Not installed
  @capacitor/android - Not installed
  @capacitor/ios - Not installed

Quasar App Extensions
  *None installed*

Networking
  Host - 33900db279f2

Relevant log output

No response

Additional context

No response

gustavotoyota commented 2 years ago

Adding a ? in front of $q in quasar/src/directives/Ripple.js fixes it for me:

diff --git a/node_modules/quasar/src/directives/Ripple.js b/node_modules/quasar/src/directives/Ripple.js
index ebd27ab..b6abcbf 100644
--- a/node_modules/quasar/src/directives/Ripple.js
+++ b/node_modules/quasar/src/directives/Ripple.js
@@ -62,7 +62,7 @@ function showRipple (evt, el, ctx, forceCenter) {
 }

 function updateModifiers (ctx, { modifiers, value, arg, instance }) {
-  const cfg = Object.assign({}, instance.$q.config.ripple, modifiers, value)
+  const cfg = Object.assign({}, instance.$q?.config.ripple, modifiers, value)
   ctx.modifiers = {
     early: cfg.early === true,
     stop: cfg.stop === true,
rstoenescu commented 2 years ago
  1. Once again, just to be clear, this is due to a bug introduced in Vue 3.2.32.
  2. Guarding the instance.$q is not an option as it means that in some scenarios (like this one), Ripple won't work as advertised (it will not keep into account the global config for it).

Pushed a workaround in Quasar for this issue since the fix in Vue takes longer than expected. Fix will be available in Quasar v2.7.3