Vue.js load component theme without Vue.use - vue.js

I am using Cool-Select and it requires the following code to load its theme:
import VueSelect from 'vue-cool-select'
Vue.use(VueSelect, {
theme:'material-design'
})
The problem is that I do not want to have to import the entire vue code in order to just use a theme. Also, the components works fini without the theme import; just missing css.
Is it possible to import the theme locally instead in the components part like this?
import { CoolSelect } from 'vue-cool-select'
components:{
CoolSelect,
// import theme here
},

VueSelect is a plugin, i.e. it has install method that will be called when provided to Vue.use. This doesn't affect the application except that it loads styles that are specific to this component.
Since styles weren't exported from the package and are loaded only on plugin installation, this is the only way how CoolSelect component can have its styles loaded without forking the package:
Vue.use(VueSelect, {
theme:'material-design'
})

Related

Nuxt avoid import of client-side script for server-side rendering

In my nuxt.js application, I have a script that imports an NPM package which is only compatible with browser contexts (it references document, location, window, etc.)
Is there a way to exclude this from SSR?
import thing from "#vendor/thing"; // causes `document not defined` error
export default showThing(){
if (process.client) {
thing();
}
}
I can use the method with process.client but this file is still imported in my components.
You could import it dynamically rather than in every context.
As explained in my answer here: https://stackoverflow.com/a/67825061/8816585
In your example, that would be something like this
export default showThing(){
if (process.client) {
const thing = await import('#vendor/thing')
thing()
}
}

How to import javascript library in main.js for global availability throughout vue app?

My main.js contains import "mathjs"; and seems to be working fine within main.js as
console.log(median(5,4,6,1));
> 4.5
median() is however not available outside of main.js, i.e. in components. After reading this answer, I assumed that the simple import should be enough for global availability throughout the vue app?
In general when you are working with modern modules or a bundler like webpack, you have to import mathjs in every module (think file) you want to use it.
What is often done in the vue context, is adding the library to the Vue context itself with a plugin.
See https://v3.vuejs.org/guide/plugins.html#writing-a-plugin
So this should be as easy as:
const mathjsPlugin = {
install(app){
app.config.globalProperties.$mathjs = mathjs;
}
}
const app = createApp(...);
app.use(mathjsPlugin);
// inside of a component
export default {
created(){
console.log(this.$mathjs....);
}
}
I personally think explicitly importing is a cleaner approach, but if mathjs is used in most of the components, this approach can make sense
in main.js import all as math then add it as global property :
import * as math from 'mathjs'
const app=createApp({....})
app.config.globalProperties.$math =math
then in any component you could use it like this.$math.theFunctionName

Can not read property "document" of undefined - ApexCharts

I'm attempting to import apexcharts into my nuxt project. I've used both the vanilla lib and vue wrapper.
Simply importing the library causes the following error
Like I said, i've attempted importing both
import ApexCharts from "apexcharts"
and
import VueApexCharts from "vue-apexcharts"
Both return the same error.
Is this something I have to configure in the nuxt.config.js file?
This is because you are using Nuxt.js which does SSR for you. Since document does not exist on the server-side it will break.
To work around it there a couple of approaches:
First you can create a plugin/apex.js which is responsible for registering your components
import Vue from 'vue';
import ApexChart from 'vue-apexcharts';
Vue.component('ApexChart', ApexChart);
and in your nuxt.config.js make sure to load the plugin file on the client-side:
module.exports = {
// ...
plugins: [
// ...
{ src: '~/plugins/charts', ssr: false }
],
// ....
};
Now you can reference the ApexChart component anywhere in your app, also make sure to wrap it with ClientOnly component to prevent Nuxt from attempting to render it on the server-side:
<ClientOnly>
<ApexChart type="donut" :options="chartData.options" :series="chartData.series" />
</ClientOnly>
The other approach is you can import Apex charts as async components, which do not get rendered on the server-side, but it has been a hit and miss with this approach, feel free to experiment.
Generally when using Nuxt or any SSR solution, be careful of the libraries you use as they might have an implicit dependency on the execution environment, like requiring browser-specific APIs in order to work like window or document.

TypeError: Cannot read property 'components' of undefined in Vue2

I'm using mixins in the subset components of app.vue without any problems, everything is good and works fine, but when I want to use it into the app.vue component, i'm having error in console.
<script>
/* eslint-disable */
import PanelUser from "./layouts/PanelUser";
import Auth from "./mixins/Auth";
export default {
name: "App",
mixins: [Auth],
components: {
PanelUser
},
};
</script>
I also can not use the router; when I use it, the page is completely white and nothing is displayed.
I have found how to check this situation.
First, you could see that the error threw at checkComponents method, move your mouse on and left click.
Second, add a break point, and then refresh the page.
Third, maybe you could find that some mixins or components which are referenced show undefined.
In my case, the second mixin is undefind.
Finally, check the reference or the mixin file. I found the reason is that I copied the mixin from another file and forgot to rename the mixin at declare part.
That's all, try to check by yourself. :)
You need to change:
import PanelUser from "./layouts/PanelUser";
To
import {PanelUser} from "./layouts/PanelUser";
And
import Auth from "./mixins/Auth";
To
import {Auth} from "./mixins/Auth";
The error is mixin related.
Make sure your mixins being used in your components are correct. (eg. name, esm import path etc.)
import samplePackage from "sample-package";
import anotherMixin from "another-package/path/to/mixin";
export default {
mixins: [
samplePackage.sampleMixin,
anotherMixin
]
}
After a couple hours of debugging, I found in our case the culprit was vuelidate. We tried to migrate from Webpack to Vite, keeping Vue 2.7, and vuelidate 3.
Importing:
import { validationMixin } from 'vuelidate'
console.log(validationMixin // undefined in production build
printed only undefined after a vite build
After reading about issues related to non-ESM imports (#1, #2) I tried to change the import to vuelidate/src:
import { validationMixin } from 'vuelidate/src/index'
console.log(validationMixin) // works!
// import the validators from "lib" though, src threw an require-js error for me
import { required, email, minLength } from "vuelidate/lib/validators"

Unknown html tag warning of Bootstrap-Vue.js support in WebStorm

I'm using WebStorm 2017.2.4 and webpack Vue.js project. I have added bootstrap-vue.js to my project and would like to see hints for it and components support.
But instead of that I have got "Unknown html tag" warning.
BTW: bootstrap-vue works as expected when running project.
Do you have any suggestions how to make it work?
UPDATED on 2019/07/30
PHPShtorm(WebStorm) was updated to 2019.2 and now they added better support for vuejs libraries:
https://blog.jetbrains.com/webstorm/2019/07/webstorm-2019-2/#development_with_vue
I've just tested and it works.
OLD answer
I solved this issue by adding components manually.
According to: https://bootstrap-vue.js.org/docs/#individual-components-and-directives
I created new file, e.g. bootstrap.js then register globally components which required
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import Vue from 'vue';
import navbar from 'bootstrap-vue/es/components/navbar/navbar';
import container from 'bootstrap-vue/es/components/layout/container';
// ...
Vue.component('b-navbar', navbar);
Vue.component('b-container', container);
// ...
It work for me in phpstorm 2018.1
Bootstrap vue uses very dynamic way of defining components. I am using PyCharm with vuejs extension which is unable to resolve the components when registered using
import { Layout } from 'bootstrap-vue/es/components'
Vue.use(Layout)
What I use to do is make a new file bootstrap.js in components directory, and register all bootstrap components I would use like
import Vue from 'vue'
import bContainer from 'bootstrap-vue/es/components/layout/container'
import bRow from 'bootstrap-vue/es/components/layout/row'
import bCol from 'bootstrap-vue/es/components/layout/col'
Vue.component('b-container', bContainer);
Vue.component('b-col', bCol);
Vue.component('b-row', bRow);
and then import this file in main.js
import './components/bootstrap'
Just a little cleaner solution.
#Updated: There're two ways to fix "Unknown html tag" warning: (Global and Local Registration)
Global Registration :
You should have to register your component globally Vue.component(tagName, options) before creating the new Vue instance. For example:
Vue.component('my-component', {
// options
})
Once registered, a component can be used in an instance’s template as a custom element, <my-component></my-component>. Make sure the component is registered before you instantiate the root Vue instance. Here’s the full example:
HTML:
<div id="example">
<my-component></my-component>
</div>
JS:
// global register
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
// create a root instance
new Vue({
el: '#example'
})
Which will render HTML::
<div id="example">
<div>A custom component!</div>
</div>
Local Registration :
You don’t have to register every component globally. You can make a component available only in the scope of another instance/component by registering it with the components instance option:
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
// ...
components: {
// <my-component> will only be available in parent's template
'my-component': Child
}
})
The same encapsulation applies for other registerable Vue features, such as directives.
Read more at https://v2.vuejs.org/v2/guide/components.html#Using-Components
#Before Updated:
In WebStorm, a library is a file or a set of files whose functions and methods are added to WebStorm's internal knowledge in addition to the functions and methods that WebStorm retrieves from the project code that you edit. In the scope of a project, its libraries by default are write-protected.
WebStorm uses libraries only to enhance coding assistance (that is, code completion, syntax highlighting, navigation, and documentation lookup). Please note that a library is not a way to manage your project dependencies.
Source: https://www.jetbrains.com/help/webstorm/configuring-javascript-libraries.html
Simply, upgrade WebStorm from version 2017.2.4 to 2017.3 which fixed this issue. It is tested.