Global Components in Nuxt JS - vue.js

I have built some components such as modals and reviews that I want to use and reuse just about everywhere in my site.
I have made a single global.js file in the plugins folder, So iv'e just registered this in my nuxt.config.js file once.
In my global.js file i've imported vue and called the components
import Vue from 'vue';
Vue.component('component-modal', () => import('#/components/modal'));
Vue.component('component-modal-other', () => import('#/components/modalOther'));
Vue.component('component-reviews', () => import('#/components/reviews'));
The reason for this is that now I don't have to do component import on every instance that I want to use it for I just call the component <my-component>.
However I've just switched to Universal mode and i'm now getting hydration warnings that are all coming from my global.js components file that I made in my plugins folder.
Should I not have a global.js file and each component that I want to use globally have it's own file in the plugins folder? Or do I just need to import the component when I need it locally in the file that is requiring it?
What is the best way to re-use and register global mini components that I have created?
Vue Warning
The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render
The only way I can avoid this warning is not to put my components into a global.js component file and register it with Nuxt plugins. Only use the component import into each instance which kind of defeats the purpose of global components

try this
import Modal from '#/components/modal'
Vue.component('Modal', Modal)
in your view
</modal>

Related

Nuxt.js Client-Side Only Component

I'm using plotly.js in my Nuxt.js project, and I kept receiving an error, saying document not defined, when plotly.js was imported. Nuxt.js documentation doesn't provide clear instruction on how one can make a component load and generate client-side only.
To overcome this issue, the component you're using must be placed inside the client-only environment:
<client-only>
<component ...></component>
</client-only>
Furthermore, you need to store the component's .vue file somewhere other than the components directory that Nuxt.js automatically creates, because, during the build process, Nuxt.js automatically collects all of these files in order to bundle them, which will invoke the import for plotly.js inside the component. I created a directory called components-lazy and placed the component there.
Finally, you have to lazy-import the component in the page, layout or parent component, you're intending to use it in. I used the following syntax for this task:
export default {
...
components: {
Plotly: () => import('#/components-lazy/Plotly'),
...
}
...
}
This will ensure that this particular component is only imported and rendered client-side.

How to import external Vue components from .js file via web URL?

I want to be able to use Vue components distributed over CDN without the need to npm install them - in my single-file Vue components.
I do not understand how to import them by URL to compiled component.
Example of components I want to import is
https://unpkg.com/vueperslides (from https://antoniandre.github.io/vueper-slides/#installation)
As I understand there is a way to load JS file in mounted() hook or something, but I don't understand how to import exports from it after.
Answers I tried include
https://markus.oberlehner.net/blog/distributed-vue-applications-loading-components-via-http/
How to add external JS scripts to VueJS Components
and many others.
I am building a web app using Quasar Framowrk on Vue.js v2

Include Style From NPM Package Component Into WebComponent

I am building a webcomponent package using Vue CLI 3 and single file components. We have a shared package our-awesome-shared-controls that contain basic site components such as a collapsible container.
Inside my component, I import and reference the collapsible container and wrap my content in it. When I build as an app the styles from the imported components are included and everything looks great, however; when I target wc (WebComponent) using the vue-cli the style for the imported component (collapsible container) are not included.
Is there a way for me to tell the vue cli that it should include those styles? If not would there be a way to import those styles? The imported components have their style set to scoped so I'm not sure if that makes a difference.

Vue-test-utils using mixin for vee-validate in nuxt

I'm trying to test if validation works for a form with vee-validate and vue-test-utils. I also use nuxt and have created a custom plugin which install vee-validate and provides two custom computed properties as a mixin.
The problem is that I need a way to use these mixins within a localVue instance, however, I cannot just import the whole file as it results in vee-validate being installed two times on the main vue instance. I also cannot just say localVue.use(MyCustomVeeValidatePlugin) because the plugin doesn't have an install method ("plugins" in nuxt are somewhat different than in vue).
What works is creating a file which exports isFormValid and isFormChanged and then have the plugin import these methods. Then I also need to import these methods in the test file and create a mixin for the localVue instance. I would much rather prefer defining the mixin in a single plugin file. I know this is very specific but has anyone had a similar problem? I could imagine rewriting the plugin to be more like it is defined in the Vue.js docs (with an install method) and install it somehow.
Plugin:
import Vue from "vue";
import VeeValidate from "vee-validate";
Vue.use(VeeValidate);
//create global mixin for checking if form is valid
//note: every input element needs a name
Vue.mixin({
computed: {
isFormValid() {
return Object.keys(this.fields).every(key =>
this.fields[key].valid);
},
isFormChanged() {
return Object.keys(this.fields).some(key =>
this.fields[key].changed);
}
}
});
As far as I know, based on the recommendations I read in "Testing VueJs Applications (https://www.manning.com/books/testing-vue-js-applications), the author, who is also the main author of the vue-test-utils recommends:
I’ve already spoken about why you should use a localVue constructor and avoid installing on the base constructor. This is especially important for Vue Router. Always use a localVue to install Vue Router in tests. You must make sure that no file in your test suite imports a file that calls Vue.use with Vue Router. It’s easy to accidentally import a file that includes Vue.use. Even if you don’t run a module, if the module is imported, then the code inside it will be evaluated.
Based on that recommendation, I moved Vue.use() calls out of files like store.js and router.js and into main.js, which isn't used during testing.

Nightwatch.js E2E - can it test Vue.js Single File Components Loaded via Vue Router

Our case is:
Vue.js
Vuex
Vue Router
Single File Components
Vue Router repo has examples for Nightwatch.js E2E testing, but not for single file components.
When we tried, the result of tests of loading components, with
.assert.elementPresent
where not consistent. We tested clicking a router-link and looked for loading the corresponding single file component (SFC). That is, the current component was replaced on the page by the loaded component.
Our navigation is through a Vue Material drawer drawer. But we believe this is not ann essential element. But we may be wrong here.
Was someone able to get consistent results of tests of loading of such components?