thecodealer / vue-panzoom

Vue plugin to zoom/pan dom elements
MIT License
88 stars 20 forks source link

prototype is not defined for vue3 (with inertia.js) #31

Closed kfina91 closed 3 years ago

kfina91 commented 3 years ago

I'm trying to get this to run with laravel/inertia + vue3.

app.js (I added 2 lines to the boilerplate from laravel/jetstream with inertia, see comments)

require('./bootstrap');

// Import modules...
import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';

const el = document.getElementById('app');

import panZoom from 'vue-panzoom' // I added this line...

createApp({
    render: () =>
        h(InertiaApp, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: (name) => require(`./Pages/${name}`).default,
        }),
})
    .mixin({ methods: { route } })
    .use(panZoom) // and this line
    .use(InertiaPlugin)
    .mount(el);

MyComponent.vue

<template>
    <div>
        <panZoom>
            Test
        </panZoom>
    </div>
</template>

<script>
export default {

}
</script>

I get the following error _Uncaught TypeError: Cannot set property '$panZoom' of undefined at Object.install (app.js:50218) at Object.use (app.js:8680) at Module../resources/js/app.js (app.js:23584) at webpack_require (app.js:50873) at app.js:51035 at Function.webpack_require.O (app.js:50910) at app.js:51037 at app.js:51039_ this corresponds to the following code in dist/vue-panzoom.esm.js:123

var PanZoomPlugin = {
    install: function install(Vue, options) {
        var _name = options && options.componentName ? options.componentName : PanZoomComponent.name;
        Vue.component(_name, PanZoomComponent);
        Vue.prototype.$panZoom = panZoom; // it crashes here...
    }
};

package.json

...
   "dependencies": {
        "vue-panzoom": "^1.1.4"
    },
    "devDependencies": {
        "@inertiajs/inertia": "^0.8.4",
        "@inertiajs/inertia-vue3": "^0.3.5",
        "@inertiajs/progress": "^0.2.4",
        "@tailwindcss/forms": "^0.2.1",
        "@tailwindcss/typography": "^0.3.0",
        "@vue/compiler-sfc": "^3.0.5",
        "axios": "^0.21",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "postcss-import": "^12.0.1",
        "tailwindcss": "^2.0.1",
        "vue": "^3.0.5",
        "vue-loader": "^16.1.2"
    }

Note: I also tried in app.js

import Vue from 'vue';
import panZoom from 'vue-panzoom';
Vue.use(panZoom);

but this leads to (when running npm run dev): WARNING export 'default' (imported as 'Vue') was not found in 'vue' and (in the browser): Cannot read property 'use' of undefined (in the line Vue.use(panZoom))

Any help would be much appreciated! Thanks in advance!

thecodealer commented 3 years ago

The issue seems to be with your Vue import. It seems Vue isn't being imported as the 'undefined' is referring to the Vue instance.

kfina91 commented 3 years ago

Thanks for the quick answer! I have searched where the problem with my Vue import, but don't see a problem there.

I tried setting up an empty vue3 project with just panZoom and it failed with the same error message. But it should be much easier to reproduce.

  1. Install vue-cli ( https://cli.vuejs.org/ )
  2. vue create vue3_test_panZoom
  3. npm install vue-panzoom
  4. Modify src/main.js to:
    
    import { createApp } from 'vue'
    import App from './App.vue'
    import panZoom from 'vue-panzoom'

createApp(App).use(panZoom).mount('#app')

5. Add `<panZoom>Test</panZoom>` to src/App.vue
6. npm run serve

Getting the same error as in my last post. I am not familiar with the internal workings of the Vue app instance and how hooking custom components work, but maybe they changed something in vue3 regarding that?

P.S. By setting a breakpoint in the browser it seems that in the installation function:

var PanZoomPlugin = { install: function install(Vue, options) { var _name = options && options.componentName ? options.componentName : PanZoomComponent.name; Vue.component(_name, PanZoomComponent); Vue.prototype.$panZoom = panZoom; } };


Vue is set to some object it contains various properties, only prototype is undefined.
![image](https://user-images.githubusercontent.com/72922128/114241923-48bfd480-998a-11eb-8338-6ed680202e5f.png)
thecodealer commented 3 years ago

Hi, I've fixed this in v1.1.5. Kindly update and try again. I didn't realize this change in Vue 3. Thanks for reporting this.

kfina91 commented 3 years ago

Hey, everything is working fine now. Thank you for the update!