core: [vue-compat] @click not working on components

Version

3.1.2

Reproduction link

https://github.com/liamdebeasi/vue3-repro

Steps to reproduce

  1. Clone repo and run npm install.
  2. Run npm run serve to start up a dev server.
  3. Click the “Click me!” text and observe that nothing is logged to your Dev Tools Console.
  4. Quit the dev server and comment out the config.resolve.alias line in vue.config.js to disable the compat mode.
  5. Run the dev server again.
  6. Click the “Click me!” text and observe that this time the “Component was clicked!” text is logged to your Dev Tools Console.

What is expected?

I would expect that the click handler is fired regardless of whether or not I am using the compat build.

What is actually happening?

The click handler is only firing when not using the compat build.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

.native is listed as being fully supported in compat build.

@liamdebeasi Your app is missing is the second part of the webpack config described in the migration guide - setting the compiler to compat mode:

config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        return {
          ...options,
          compilerOptions: {
            compatConfig: {
              MODE: 2
            }
          }
        }
      })

After I added this to your repro, click worked.

@inspire22 .native is fully supported by the migration build. If you found a scenario where it doesn’t work as intended, please open a new issue with a reproduction so we can check it out.

@inspire22 The compiler config is not the solution in terms of Ionic.

Ionic exports Vue 3 components. But in compat mode, the app would treat them like Vue 2 components by default. You can do the following:

import {IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton} from "@ionic/vue";
import {defineComponent} from "vue";

IonButton.compatConfig = {
	MODE: 3
}

Which makes the alert pop up for me - without needing to add .native.

To make this less messy, you might have to come up with a clever wrapper or sth. Idea:

import {IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton} from "@ionic/vue";
import {defineComponent} from "vue";


// you would of course import this from a module in each of your components
function fixCompMode(components) {
	Object.entries(components).map(([name, component]) => {
		if (!component.compatConfig && name.startsWith('Ion')) {
			component.compatConfig = { MODE: 3 }
		}
	})
}

export default defineComponent({
	name: "Home",
	components: fixCompMode({
		IonContent,
		IonHeader,
		IonPage,
		IonTitle,
		IonToolbar,
		IonButton,
	}),
	methods: {

//...

This will add a very small one-time runtime overhead, but should not be harmful considering Vue 3 itself is faster than Vue 2.