jerrybendy / vue-touch-events

Support simple touch events (tap / swipe / touch hold)
MIT License
537 stars 51 forks source link

Failed to resolve directive: touch #30

Open skjnldsv opened 5 years ago

skjnldsv commented 5 years ago

Using this library into another library and then importing the 2nd library doesn't work.

We have a Modal component on the https://github.com/nextcloud/nextcloud-vue library and we wanted to use your library, though when importing the modal component on another app, we get the Failed to resolve directive: touch error.

Though importign and using your library on the nextcloud-vue library is done properly:

import Vue from 'vue'
import Vue2TouchEvents from 'vue2-touch-events'

Vue.use(Vue2TouchEvents)

I'm guessing this is because you don't export your plugin as a ssr module or something webpack can understand and pack and bundle on other libraries. But I might be wrong! :)

EDIT: I was close, this is because you do not export the directive itself but only the {install:xxx, ...} object Vue.use requires. Please check https://github.com/Akryum/v-tooltip/blob/master/src/index.js for a working example. It exports the vue directive as well so that webpack can understand how things works and include everything.

jerrybendy commented 5 years ago

Maybe I got your point, but I didn't use ES6's export. I'm not sure whether it works or not if I change module.exports to export.

if (typeof module === 'object') {
-    module.exports = vueTouchEvents
+   exports.install = vueTouchEvents.install
+   exports.vueTouchEvents = vueTouchEvents
}
skjnldsv commented 5 years ago

It sill behave the same :confused: I think you need to restructure the vueTouchEvents objet and separate it from your install function. https://github.com/Akryum/v-tooltip/blob/e613e2b301740c68dd0f618b0101f75ea33c30dd/src/directives/v-tooltip.js#L215-L222

jerrybendy commented 5 years ago

You're right. I should restructure the code to separate the install function. But I can't understand the code you referenced.

export const directive = {
    options: defaultOptions,
    bind,
    update: bind,
    unbind (el) {
        destroyTooltip(el)
    },
}

Why does v-tooltip export a directive? What does it do? πŸ€”

skjnldsv commented 5 years ago

This is the default directive that vue can use in the directives component. Or with Vue.directive('directive, directive) instead of Vue.use which doesn't properly declare it it seems. (in plugin systems like nextcloud-vue or any big bundles like vuetify, vue-material...) https://vuejs.org/v2/guide/custom-directive.html

props: {
  ...
},
directives: {
  focus: {
    // directive definition
    inserted: function (el) {
      el.focus()
    }
  }
}
jerrybendy commented 5 years ago

OK, I see. I will restructure my code to support it 😬

Fragilem17 commented 5 years ago

Maybe first pull my feature.. might be easier then afterwards.

ChristophAnastasiades commented 5 years ago

Any news on this? I am having the same problem.

jerrybendy commented 5 years ago

I added a commit here #39 to support custom directives, but I can't make sure it can work well or not πŸ˜…

const touchDirective = require('vue2-touch-events').touchDirective

Vue.directive('touch', touchDirective)
ptrckdev commented 5 years ago

Not sure if this is a similar issue but i get the same warning so i don't want to make a new post.

Clean install of vue with the cli tool and just adding

Vue.use(Vue2Touch)

and adding this to a div

v-touch:swipe="swipeHandler"

breaks the code with

[Vue warn]: Failed to resolve directive: touch

What I can do, is to run the dev server without the v-touch line, write it back into my div, do a hot reload, and then everything works like it should. πŸ‘ If i reload my tab it breaks again tho. πŸ‘Ž

jerrybendy commented 5 years ago

@ptrckdev Which version did you use?

import Vue from 'vue'
import Vue2TouchEvents from 'vue2-touch-events'

Vue.use(Vue2TouchEvents)

This will run install function and register the v-touch directive.

ptrckdev commented 5 years ago

Fixed, didnt work with Vue for a year now and put the Vue.use under new Vue() in my main.js πŸ™„

jerrybendy commented 5 years ago

@ptrckdev Yep. You can't put Vue.use under new Vue.

thequiet commented 4 years ago

I added a commit here #39 to support custom directives, but I can't make sure it can work well or not πŸ˜…

const touchDirective = require('vue2-touch-events').touchDirective

Vue.directive('touch', touchDirective)

What aspects are you uncomfortable with? It seems with the latest version of vuetify-loader (at least in our build), the v-touch directive won't work as it conflicts with their own v-touch directive.

aezur commented 4 years ago

I had the same issue and it was caused by having 2 plugins in the same Vue.use. I changed Vue.use(Argon, Vue2TouchEvents); to

Vue.use(Argon);
Vue.use(Vue2TouchEvents);
jerrybendy commented 4 years ago

It seems to be a big problem. I will resolve this issue ASAP

BrianDavidYork-zz commented 4 years ago

Not sure if this is that same issue. When testing with vue test utils and jest I get this error for each instance of v-touch in my html:

      (found in <Component>)
    console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
      [Vue warn]: Failed to resolve directive: touch

I am importing it into my test like this: const touchDirective = require("vue2-touch-events").touchDirective;

describe("TEST", () => {
  const localVue = createLocalVue();
  localVue.use(Vuex);
  localVue.directive(touchDirective);

  const factory = propsData => {
    return mount(Component, {
      localVue
    });
  };

  it("isCompleted", async () => {
    const wrapper = factory();
    ...

Any idea how to fix this?

jerrybendy commented 4 years ago

@BrianDavidYork vue2-touch-events now exports a install function only. So that you can do this:

const vue2TouchEvents = require('vue2-touch-events');
// ...
localVue.use(vue2TouchEvents);
// ...
alekbless commented 3 years ago

Is there any option to define a custom directive when installing? I'am using Vuetify and the component "v-touch" seems to override this package.

import Vue2TouchEvents from 'vue2-touch-events';
Vue.use(Vue2TouchEvents);