How can I snapshot test a Vue SFC page in Nuxt that only contains a layout using jest - vue.js

How can I snapshot test a Vue SFC page in Nuxt that only contains a layout using jest.
For example:
<script>
export default {
layout: 'some-layout-name'
};
</script>
I get an error because it is lacking the template part, I could not make it generate a snapshot in snapshot testing in jest.
[Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Anonymous>
<Root>
at warn (node_modules/vue/dist/vue.runtime.common.dev.js:621:15)
at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4024:9)
at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8392:10)
at init (node_modules/vue/dist/vue.runtime.common.dev.js:3112:13)
at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5958:9)
at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5905:9)
at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6455:7)
at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3933:19)

You need to ensure you have a <template> element in your Single File Component SFC.
Example.
<template>
<div/>
</template>
<script>
export default {
layout: 'some-layout-name'
};
</script>
N.B. Without the <template> element in your SFC, you'll continue to get the error experienced.
render function or template not defined in the component.

Related

Importing a third party vue component inside an npm package

I am developing an npm package. And I use third party library components inside my package. But I am having trouble importing components inside a package. For example with https://github.com/rlemaigre/Easy-DnD:
My CustomPackageComponent.vue:
<template>
<div>
<drop-list :items="[1, 2]">
<template v-slot:item="{item}">
<drag :key="item">
{{ item }}
</drag>
</template>
</drop-list>
</div>
</template>
<script>
import Vue from "vue";
import {DropList, Drag} from "vue-easy-dnd";
export default {
data() {
return {
someVar: 'foo'
}
},
components: {DropList, Drag}
}
</script>
And next in my index.js file:
import CustomPackageComponent from './components/CustomPackageComponent'
export {
CustomPackageComponent
}
Finally I use in my app. SomeAppComponent.vue:
<template>
<div>
<custom-package-component/>
</div>
</template>
<script>
import {CustomPackageComponent} from '#my-package-scope/some-name'
export default {
components: {CustomPackageComponent},
}
</script>
I have errors:
[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'on')"
found in
---> <DropList>
...
TypeError: Cannot read properties of undefined (reading 'on')
at setCurrentInstance (app.js?id=be8d63a4f2dc42c0bbb5:70359:21)
at normalized (app.js?id=be8d63a4f2dc42c0bbb5:72030:9)
at Proxy.renderSlot (app.js?id=be8d63a4f2dc42c0bbb5:71709:13)
at app.js?id=be8d63a4f2dc42c0bbb5:69361:1276
at Proxy.renderList (app.js?id=be8d63a4f2dc42c0bbb5:71658:22)
at Proxy.__vue_render__$4 (app.js?id=be8d63a4f2dc42c0bbb5:69361:1229)
at VueComponent.Vue._render (app.js?id=be8d63a4f2dc42c0bbb5:72308:28)
at VueComponent.updateComponent (app.js?id=be8d63a4f2dc42c0bbb5:72748:27)
at Watcher.get (app.js?id=be8d63a4f2dc42c0bbb5:73932:33)
at new Watcher (app.js?id=be8d63a4f2dc42c0bbb5:73922:51)
[Vue warn]: Error in beforeMount hook: "TypeError: Cannot read properties of undefined (reading 'off')"
found in
---> <BVTransporter>
...
TypeError: Cannot read properties of undefined (reading 'off')
at setCurrentInstance (app.js?id=be8d63a4f2dc42c0bbb5:70357:51)
at VueComponent.Vue._render (app.js?id=be8d63a4f2dc42c0bbb5:72330:13)
at VueComponent.updateComponent (app.js?id=be8d63a4f2dc42c0bbb5:72748:27)
at Watcher.get (app.js?id=be8d63a4f2dc42c0bbb5:73932:33)
at new Watcher (app.js?id=be8d63a4f2dc42c0bbb5:73922:51)
at mountComponent (app.js?id=be8d63a4f2dc42c0bbb5:72765:5)
at VueComponent.Vue.$mount (app.js?id=be8d63a4f2dc42c0bbb5:79061:12)
at VueComponent.Vue.$mount (app.js?id=be8d63a4f2dc42c0bbb5:81625:18)
at init (app.js?id=be8d63a4f2dc42c0bbb5:136420:13)
at createComponent (app.js?id=be8d63a4f2dc42c0bbb5:139300:9)
[Vue warn]: Error in nextTick: "TypeError: Cannot read properties of undefined (reading 'removeAttribute')"
TypeError: Cannot read properties of undefined (reading 'removeAttribute')
at Array.updateAttrs (app.js?id=be8d63a4f2dc42c0bbb5:140051:13)
at patchVnode (app.js?id=be8d63a4f2dc42c0bbb5:139636:62)
at updateChildren (app.js?id=be8d63a4f2dc42c0bbb5:139515:9)
at patchVnode (app.js?id=be8d63a4f2dc42c0bbb5:139641:29)
at VueComponent.patch [as __patch__] (app.js?id=be8d63a4f2dc42c0bbb5:139804:9)
[Vue warn]: Error in nextTick: "TypeError: Cannot read properties of undefined (reading 'on')"
found in
---> <BVTransporter>
...
If I use this code without package everything is ok. I think, that is's something with vue lifecycle, but I don't have any idea how it fix.
Maybe I need to register my package by another way.
I use npm link for local development.
Also I try to import with Vue.Component(...) in CustomPackageComponent.vue:
<template>
<div>
<drop-list :items="[1, 2]">
<template v-slot:item="{item}">
<drag :key="item">
{{ item }}
</drag>
</template>
</drop-list>
</div>
</template>
<script>
import Vue from "vue";
import {DropList, Drag} from "vue-easy-dnd";
Vue.component('drop-list', DropList);
Vue.component('drag', Drag);
export default {
data() {
return {
someVar: 'foo'
}
},
}
</script>
But I have this error:
[Vue warn]: Unknown custom element: <drop-list> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <CustomPackageComponent> at packages/packages/someScope/someName/src/components/CustomPackageComponent.vue
...

Error while moving component from application to a library

I am having troubles while creating a library of components in top of Vuetify 2.x.
I have created a simple navigation-drawer wrapper:
<template>
<v-navigation-drawer app v-model="drawer">
<v-list-item>
<v-list-item-content>
<v-list-item-title class="title">
Application
</v-list-item-title>
<v-list-item-subtitle>
subtext
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-navigation-drawer>
</template>
<script>
export default {
name: 'MySidebar',
data: () => ({
drawer: null,
}),
};
</script>
When this component is placed inside my application, it works as expected. However, when the same component is on a library, the application crashes.
<template>
<v-app>
<my-sidebar/>
</v-app>
</template>
<script>
import MySidebar from 'my-library/src/components/MySidebar.vue'; // Error
import MySidebar from './src/components/MySidebar.vue'; // Works
export default {
name: 'App',
components: {
MySidebar,
},
};
</script>
On the first import, the application fails to get the this.$vuetify object, but when I console.log(this.$vuetify), it is there.
Some of the console messages:
TypeError: Cannot read property 'breakpoint' of undefined
at VueComponent.isMobile (VNavigationDrawer.ts?6ca0:193)
at Watcher.get (vue.runtime.esm.js?f9ee:4473)
...
[Vue warn]: Error in getter for watcher "isMobile": "TypeError: Cannot read property 'breakpoint' of undefined"
found in
---> <VNavigationDrawer>
<MySidebar> at my-library/src/components/MySidebar.vue
<VApp>
<App> at src/App.vue
<Root>
...
TypeError: Cannot read property 'breakpoint' of undefined
at VueComponent.isMobile (VNavigationDrawer.ts?6ca0:193)
at Watcher.get (vue.runtime.esm.js?f9ee:4473)
...
[Vue warn]: Error in created hook: "TypeError: Cannot read property 'application' of undefined"
found in
---> <VNavigationDrawer>
<MySidebar> at my-library/src/components/MySidebar.vue
<VApp>
<App> at src/App.vue
<Root>
Additional Information:
My Library has vuetify as dev dependency for development proposes
I am using the library via npm link
With some help from the Vuetify team, I found out that the problem was that Webpack was using Vuetify from the library instead of using from the app. This was caused by the use of npm link on my-app to use my-library together with Vuetify installed as dev-dependency on my-library.
Some possible solutions:
On my-library, use npm install --only=prod instead of npm install. This will prevent the conflict by not installing Vuetify on the library.
On my-app, add the following lines to vue.config.js:
const path = require('path');
module.exports = {
publicPath: process.env.VUE_APP_PUBLIC_PATH,
configureWebpack: {
resolve: {
alias: {
/* Use vuetify from my-app, not from my-library */
vuetify: path.resolve(__dirname, 'node_modules/vuetify'),
},
},
},
};
This will tell explicitly to Webpack to chose the Vuetify installation from my-app.
Other solutions that did not fit my requirements:
Stop using npm link
Do not install Vuetify on my-library, install it only on my-app
I had the exact same issue and solved it by deleting the node_modules folder in the component library folder (i.e. rm -rf my-library/node_modules in your case).

How to register component directly vuetify-date-range picker ? Cannot get custom element

I intall https://github.com/praveenpuglia/vuetify-daterange-picker in my currently vue app with vuetify i follow the docs. but it get me an error.
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
//in main.js
//and in my component
//package.json
//error
From link you provided:
// If you want to register this as a global component then
// in main.js
import VDateRange from 'vuetify-daterange-picker';
import 'vuetify-daterange-picker/dist/vuetify-daterange-picker.css';
Vue.use(VDateRange);
And in your components you can use VDateRange with name v-date-range:
<template>
<div>
<v-date-range :options="dateRangeOptions" #input="onDateRangeChange"></v-date-range>
</div>
</template>

[Vue warn]: Failed to mount component: template or render function not defined

I want to use an npm module which is based on Vue:
Persian Date & Time Picker For Vue.js
because I'm not familiar with node.js, I used wzrd.in to get a window.vuePersianDatetimePicker object:
https://wzrd.in/standalone/vue-persian-datetime-picker#latest
I used it in my code(I only include contents of my body tag):
<div id="app">
<date-picker></date-picker>
</div>
<script src="vue.js"></script>
<script src='https://wzrd.in/standalone/vue-persian-datetime-picker#latest'></script>
<script>
Vue.component('date-picker',vuePersianDatetimePicker)
new Vue({
el: "#app",
});
</script>
but I cannot use it and get the following error:
[Vue warn]: Failed to mount component: template or render function not defined.
I looked at the contents of vuePersianDatetimePicker object and found the solution.
I should have used vuePersianDatetimePicker.default instead of vuePersianDatetimePicker

Component inside another component not working - webpack - Vue.js 2

I am totally new to Vue.js and hence I feel the issue is very simple. Here is my Test.vue component:
<template>
<p>Hello Worldd</p>
</template>
<script>
export default {
name : 'test'
}
</script>
I am trying to display this "Hello Worldd" in another component called UserDevices.vue. Here is the contents of that file:
<template>
<div>
<test></test>
<p>test</p>
</div>
</template>
<script>
import Test from './Test'
export default {
name: 'UserDevices',
components: {Test}
}
I am getting an error says:
[Vue warn]: Unknown custom element: <test> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <UserDevices> at src/components/UserDevices.vue
<App> at src/App.vue
<Root>
I am using webpack scaffold for vue as template. Isn't this the correct approach to do this?
You are using a .vue file, meaning that vue-loader is looking for a script section enclosed in <script> tags. But, because you are not closing the script tag with </script>, vue-loader will just ignore that section of the .vue file (without any warning).
The template of the Vue component will still get loaded, but the Vue instance's model (with all of its data properties, methods, component, etc.) will not. This is why Vue can't find the <test> component.