Vuejs Cannot read property 'use' of undefined error - vue.js

I'm trying to integrate a Datatable plugin (https://www.npmjs.com/package/vuejs-datatable) in my Vue application and I'm getting an error in my console.
Uncaught TypeError: Cannot read property 'use' of undefined
at eval (vuejs-datatable.js?b015:1)
at Object.eval (vuejs-datatable.js?b015:1)
at eval (vuejs-datatable.js:4)
at Object../node_modules/vuejs-datatable/dist/vuejs-datatable.js (app.js:10170)
at __webpack_require__ (app.js:679)
at fn (app.js:89)
at eval (selector.js?type=script&index=0!./src/views/tables/data-table.vue:2)
at Object../node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/views/tables/data-table.vue (app.js:1438)
at __webpack_require__ (app.js:679)
at fn (app.js:89)
My dataTable.vue file:
<template lang="html">
<section class="data-table">
<datatable :columns="columns" :data="rows"></datatable>
</section>
</template>
<script lang="js">
import Vue from 'vue'
import DatatableFactory from 'vuejs-datatable'
export default {
name: 'DatatablePage'
}
Vue.use(DatatableFactory)
</script>
And whenever i try to use 'Vue.use(PluginName)' when integrating a plugin, i get the similar error. I'm new to VueJS. Is there anything i need to do ?

You need to add plugin before your main Vue instance is initialized; See using vue plugins here, which says:
Use plugins by calling the Vue.use() global method. This has to be
done before you start your app by calling new Vue().
For your case, move
import Vue from 'vue'
Vue.use(DatatableFactory)
to your main.js, so it looks like:
import Vue from 'vue'
Vue.use(DatatableFactory)
// some other code
new Vue({
...
})

Adding the following in weback.config.js seemed to do the trick:
module.exports = {
resolve: {
alias: {
...
'vuejs-datatable': 'vuejs-datatable/dist/vuejs-datatable.esm.js',
...
}
},
}
Based on discussion here:
https://github.com/pstephan1187/vue-datatable/issues/50

I faced the same error in my vue-app.
import Vue from 'vue';
import VueRouter from 'vue-router';
...some more imports here....
Vue.use(VueRouter);
...
The error was cannot read property 'use' of undefined. Which means, it had a problem with reading Vue. I checked my package.json and package-lock.json (for whether I installed in my local). Everything seemed ok. I had both Vue and Vue-router.
Deleting node_modules and re-installing worked for me.

Related

How to use an npm package component with Vite + Vue?

What would be the steps to add a component to Vite with Vue, as an npm package?
I assumed these:
npm install example
open src/App.vue and add import Example from 'example'
in App.vue, in <template>, add <Example />
Is that correct?
I am trying to install and use vue-select like so, but it's not working:
The process you described is correct, but you must also register the component before you can use it (within components: { ... }).
Since you mentioned you're using vue-select, I will use that as an example.
Step #0 - Install
As you've already done, ensure your project is initialized (npm init), then run yarn add vue-select / npm i vue-select.
Step #1 - Initialize
In your main.js, import and register with:
import VSelect from 'vue-select';
Vue.component('v-select', VSelect);
/* rest of your Vue initialization here */
Step #2 - Use Component
<v-select :options="[{label: 'Canada', code: 'ca'}]"></v-select>
You'll also need to import the stylesheet in your CSS, with:
#import 'vue-select/src/scss/vue-select.scss';
Real Example
If you want to see a full example, I am using this package in one of my projects, I'm registering the component in my main.js and using it ThemeSelector.vue.
Also, if your project is large and/ or you're only using this component in one place, then a better approach would be to import it into the component that's using it. This is done in a similar way, but you must also register it under components: { ... } for it to be accessible within your <template>.
Your screenshot shows you're importing vSelect in a <script> block, and expecting it to be automatically registered for the component's template. That would only work in a <script setup> block.
However, your GitHub repo (which seems to be different from the screenshot you posted) reveals other issues in your code:
You're using Vue 2 code to globally register the v-select component in your Vue 3 app. In Vue 3, global component registration is done from the application instance (i.e., returned from createApp()).
// main.js
import VSelect from 'vue-select';
// Vue.component('v-select', VSelect); ❌ Vue 2 code
import { createApp } from 'vue'
import App from './App.vue'
createApp(App)
.component('v-select', VSelect) ✅
.mount('#app')
You're using #import (CSS syntax) to import your SCSS file in the <script> block. Either move the CSS into a <style lang="scss"> block; or remove the # prefix, which would create a valid import for <script>.
<script setup>
// #import 'vue-select/src/scss/vue-select.scss'; ❌ The # prefix is invalid in <script>
import 'vue-select/src/scss/vue-select.scss'; ✅
</script>
<!-- OR -->
<style lang="scss">
#import 'vue-select/src/scss/vue-select.scss';
</style>
Your project is missing sass, which is required to process SCSS files. You can install it as a dev dependency with:
$ npm i -D sass
Here's a demo with the fixes pointed out above.

Vue Test Util can't find BootstrapVue html elements in Nuxt.js

I have a project in Nuxt.js and I am trying to test it using Vue Test Util which works effectively except on files where I use BootstrapVue custom html elements.
When I run npm test this error displays for every BootsrapVue html element.
console.error
[Vue warn]: Unknown custom element: <b-container> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <Anonymous>
<Root>
How can I prevent this?
You need to setup bootstrap-vue in your Jest enviroment, using a Jest setup file.
Create the setup file:
// #/jest-setup.js
import Vue from 'vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)
Then configure Jest's setupFiles to load it:
// #/jest.config.js
module.exports = {
setupFiles: ['./jest-setup.js'],
}

Use Vue component after Webpack build

I have a CMS that delivers static HTML pages. For that CMS, I want to develop components with Vue that then can be used in the CMS individually.
As I understood, Vue is the perfect solution for that.
As TypeScript gets more and more common, I want to use TypeScript with Babel and Webpack, so the CLI project gave me a perfect boilerplate.
When I run npm run build, I get an index.html in the dist folder with my <div id="app"></div>-container. This could be my root element/template in CMS, and then just pass the components in it.
Sadly, everything in the app-container is rendered out.
I already registered my components inside the main.ts file, and removed the line render: (h)=>h(App), but it also replaces my container contents.
Main.ts:
import Vue from 'vue';
import App from './App.vue';
import ButtonLink from './components/ButtonLink.vue';
Vue.config.productionTip = false;
// Adding the component to my Vue context
Vue.component('ButtonLink', ButtonLink);
new Vue({
// render: (h) => h(App),
}).$mount('#app');
Excerpt of index.html in dist dir:
<div id=app>
<ButtonLink href="https://google.com">A link </ButtonLink>
</div>
Link to full project: https://gitlab.com/cedricwe/vue-problem/tree/master
What did I do wrong? Is this even possible?
It looks like you're using in-DOM templates without the runtime compiler, which would yield this browser console warning:
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
(found in <Root>)
The runtime compiler is excluded by default to reduce the bundle size. You could enable it in a Vue CLI project with the runtimeCompiler flag in vue.config.js in the root of your project:
module.exports = {
runtimeCompiler: true
}
What you really want to do is provide your Vue instance a "mounting point". In this case we normally use the el option something along the lines of this would work instead:
import Vue from 'vue';
import App from './App.vue';
import ButtonLink from './components/ButtonLink.vue';
Vue.config.productionTip = false;
new Vue({
el: '#app', // mounts this instance to #app but doesn't render it
components: {
ButtonLink // optionally have it local to your instance vs global
}
});

Vuetify Styles not visible

I am a beginner in the world of Vue, so please bear with my foolish question(s).
I have a boilerplate code for a Vue project which I cloned from:
Vue Enterprise Boilerplate
I wanted to use Vuetify components, so I followed the following steps:
1. Cloned the vue-enterprise-boilerplate
2. npm install vuetify --save
3. In my main.js I added the vuetify dependency like:
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify);
4. I am using Vue CLI 3 (which comes with the boilerplate), also I have installed the CCS Loader.
5. Now in my app.vue, I have a simple button like:
<v-app>
<v-btn color="primary">Test</v-btn>
</v-app>
But when I run the app, I only see the outline of the button, but the styles are missing. Here is a screenshot below:
Also here is the dev-tools snapshot:
As you can see, the vuetify.min.css is being referenced, I am unable to debug why this is not behaving as per the Vuetify guides.
What steps am I missing?
What fixed the issue for me was the adding of class .v-application at the top most html tag (or the first one after template tag). Usually if I add <v-app> it all works but for some reason using vuitify 2.0.4 this didn't worked (may be because I'm not using vue-cli and webpack but parcel.js).
So adding this class solved the same issue for me.
EDIT
Actually I just found why v-app was ignored. Since I'm using vuetify 2.0.4. without vue-cli and webpack I need to include the vuetify components by my self like so:
import Vue from 'vue'
import Vuetify, {
VCard,
VImg,
VCardTitle,
VBtn,
VCardActions,
VCardText,
VProgressCircular,
VSpacer,
VDialog,
VDivider,
VAlert,
VApp,
} from 'vuetify/lib'
Vue.use(Vuetify, {
components: {
VCard,
VImg,
VCardTitle,
VBtn,
VCardActions,
VCardText,
VProgressCircular,
VSpacer,
VDialog,
VDivider,
VAlert,
VApp,
},
})
import 'material-design-icons-iconfont/dist/material-design-icons.css';
export default new Vuetify({})
Which is then imported in the vue app like this:
import Vue from "vue";
import vuetify from './src/vuetify'
import VocabularyApp from "./src/App.vue";
new Vue({
vuetify,
render: h => h(VocabularyApp)
}).$mount('#app-tutor');
So v-app wasn't working as I didn't included it in the list of components that I need for my app to work. More you can find here.
Welcome to the vuetiful world of vue.
You are looking into the shadow dom, please inspect the button element not the div element inside button element. The parent button element of the div will have classes like .primary .error based on the prop you give.
See the screenshot:
I hope this helps.
In my case I used stylus and had the css.requireModuleExtension = false option in vue.config.js. Styles just didn't load. Switching it to the true or removing this option did the trick.
// vue.congif.js
module.exports = {
// ...
css: {
// ...
requireModuleExtension: true
}
// ...
}

[Vue warn]: Failed to resolve directive: clipboard

I'm using https://github.com/zhuowenli/vue-clipboards. But when i tried this it doesn't work. I'm new to vue and nuxt js. and there is an error on the console that says [Vue warn]: Failed to resolve directive: clipboard. BTW i have already installed clipboard.
Template
<button v-clipboard='message'>Copy</button>
Script
import VueClipboards from 'vue-clipboards'
export default {
components: { VueClipboards },
data () {
return {
message: 'asdad'
}
}
}
This same issue is mentioned here:
https://github.com/Inndy/vue-clipboard2/issues/4
You can solve it adding the component in the main.js file. By doing that, you are making it global.
https://vuejsfeed.com/blog/copy-texts-to-clipboard-using-vue-clipboard2
Best regards
I got the same error here
Resolved it by
import VueClipboard from 'vue-clipboard2';
Vue.use(VueClipboard);
You have to import Vue & use it
import Vue from 'vue'
import vueClipboards from 'vue-clipboards'
Vue.use(vueClipboards)
...
Don't forget to remove the components: { VueClipboards },
import vueClipboards from 'vue-clipboards'
Vue.use(vueClipboards)
Import it to the main component and it works for me!!
Even before importing it to the current component I removed the "components: { VueClipboards }" but still it was not working. I just imported it to component instead of importing it to the Main.js file.