syropian / vue-tribute

A Vue.js wrapper for Zurb's Tribute library for native @mentions
https://syropian.github.io/vue-tribute/
MIT License
201 stars 24 forks source link

error on tribute.js #33

Closed ditaharyu closed 4 years ago

ditaharyu commented 4 years ago

when try i used it i'll check in runkit first, then found error window is not defined :( image

and same when i used it in my vue (nuxt) image

i will very happy if u could fix this, thanks before :)

syropian commented 4 years ago

As you can see in the RunKit error output, this is not an issue with this library, but the core Tribute library. Since it works on the concept of DOM elements, it likely needs a DOM context, whereas, as far as I know, RunKit uses a Node runtime.

amdp commented 4 years ago

Hi, having a similar error in nuxtjs: "Since it works on the concept of DOM elements, it likely needs a DOM context, whereas, as far as I know, RunKit uses a Node runtime." I do not understand this, could you explain it a little bit more?

syropian commented 4 years ago

@amdp Environments like RunKit, and Nuxt's server-side rendering engine use Node instead of the browser to do their jobs. JavaScript that runs in a Node environment has no concept of a window object, because it doesn't run inside a web browser. In this case, you should create a Nuxt plugin that runs on the client only — see https://nuxtjs.org/guides/directory-structure/plugins#vue-plugins and https://nuxtjs.org/guides/directory-structure/plugins#client-or-server-side-only

amdp commented 4 years ago

Thank you very much, so I created a vue-tribute.js in the plugins directory:

import Vue from 'vue'
import VueTribute from 'vue-tribute'

Vue.use(VueTribute)

then I inserted it into the nuxt.config.js:

...
plugins: [
    { src: '@plugins/vue-tribute.js' }, // EDIT, USE INSTEAD: { src: '@plugins/vue-tribute.js', mode: 'client' }
  ],
...

now I get document is not defined when I run the example provided in the code:

...
menuContainer: document.querySelector(".menu-container")
...

I got it working using window.document, but it just loaded the page with no mention possibility. The console was asking to import VueTribute in the page locally, not as a plugin, when imported it worked, but on reload it showed the "window is not defined" again

amdp commented 4 years ago

I will try with this:

https://deltener.com/blog/common-problems-with-the-nuxt-client-only-component/

syropian commented 4 years ago

@amdp Your plugin entry should also contain a mode:

{ src: '@plugins/vue-tribute.js', mode: 'client' }

For the menu container it's likely safer to use refs instead of document.querySelector

amdp commented 4 years ago

Ok I set menuContainer: null, in data and moved this.menuContainer = document.querySelector(".menu-container") in mounted:

  mounted() {
    this.menuContainer = document.querySelector(".menu-container")
    this.options.menuContainer = this.$refs.menuContainer;
  },

Yes I set { src: '@plugins/vue-tribute.js', mode: 'client' } in nuxt.config.js too. Now I get it working only if:

load the page, which loads with no mention functionality, then edit the page adding:

<script>
import VueTribute from 'vue-tribute'
export default {
  components: {
    VueTribute
  },
...

and NOT reloading. The HMR updates the page but keeps the window set. If I reload, the page import VueTribute from 'vue-tribute' goes over the plugin and gives me 'window is not defined' again

syropian commented 4 years ago

@amdp I built a CodeSandbox example that shows it working correctly — https://codesandbox.io/s/peaceful-gates-dvwhb

amdp commented 4 years ago

Hi, thank you very much. The main problem was using the component function in the js file

import Vue from "vue"
import VueTribute from "vue-tribute"

Vue.component("VueTribute", VueTribute)

rather than the standard

import Vue from 'vue'
import VueTribute from 'vue-tribute'

Vue.use(VueTribute)