How to register custom Vue components? - javascript

I promise I've read every related post I can find, but I'm getting any clear answers (as far as I can tell, but I'm new to Vue).
Details:
I'm using Vue v2.5.15
We are using webpack (I've read that this may affect how I have to use components)
I'm attempting to use this range slider component. I've tried to follow the documentation, but I keep getting an error stating [Vue warn]: Unknown custom element: <vue-slider> - did you register the component correctly?. I've tried reading the documentation and probably 20 different posts, but I'm still not getting this. Here is basically what I have in my JS file:
<!-- HTML -->
<div id="app">
<vue-slider
v-model="sliderRange"
:min="minPriceBase"
:max="maxPriceBase"
></vue-slider>
</div>
// Javascript
import Vue from 'vue';
import VueSlider from 'vue-slider-component';
import 'vue-slider-component/theme/default.css';
export default {
components: {
VueSlider
}
}
Vue.component('VueSlider', VueSlider);
var vm = new Vue({
el: '#app',
data: {},
components: {
VueSlider: window['vue-slider-component']
}
});
I've also read through the Vue docs on components and I can't figure what I'm doing wrong. How do I correctly register my component?
Update:
I've discovered that if I use:
components: {
VueSlider
}
Instead of:
components: {
VueSlider: window['vue-slider-component']
}
Then I stop getting error mentioned above. Instead I get an error stating [Vue warn]: Invalid prop: type check failed for prop "min". Expected Number, got Boolean. But think it's progress? Why would `window['vue-slider-component'] be necessary?

Looking at the docs, i think you tried to do all the different import variants at the same time
new Vue({
el: '#app',
components: {
VueSlider: window['vue-slider-component']
}
})
seems to be the suggested way of accessing the component that was appended to the window if you do a direct import via the script by adding
<script src="./node_modules/vue-slider-component/dist/vue-slider-component.umd.min.js"></script>
(which you aren't doing)
Then there is two more ways, you can install the component globally by using
// main.js
import VueSlider from 'vue-slider-component'
import 'vue-slider-component/theme/default.css'
Vue.component('VueSlider', VueSlider)
which would then make the vue-slider available to all the components in your application, so you don't have to import it multiple times. If you do this, you won't have to also define it locally. And finally the third option is to import it only locally:
// App.vue
import VueSlider from 'vue-slider-component'
import 'vue-slider-component/theme/default.css'
export default {
components: {
VueSlider
}
}
This would make the slider component only available to a single component. In your case, you can decide to either go for option 1:
import VueSlider from 'vue-slider-component'
Vue.component('VueSlider', VueSlider);
or option 2:
import VueSlider from 'vue-slider-component'
import 'vue-slider-component/theme/default.css'
export default {
components: {
VueSlider
}
}
The error you are seeing now by the way, is that your minPriceBase that you're referencing is not a Number, you would have to set that data on the instance:
import VueSlider from 'vue-slider-component'
import 'vue-slider-component/theme/default.css'
export default {
components: {
VueSlider
},
data () {
return {
minPriceBase: 0,
maxPricebase: 10
}
}
}
Be aware that in your code you pasted the export before your vue instance, you don't need to export anything there, you just need to define that component on the vue instance:
import VueSlider from 'vue-slider-component'
var vm = new Vue({
el: '#app',
data: {},
components: {
VueSlider
}
});
you should be able to get rid of this in your example, it doesn't do anything:
export default {
components: {
VueSlider
}
}

Recently, there was same problem and there was also 500 server side rendering error.
Anyway, I fixed and used that by using require.
if (process.browser) { // I am not sure if it is needed for you.
const VueSlider = require('vue-slider-component');
Vue.component('VueSlider', VueSlider);
Vue.use(require('vue-slider-component/theme/default.css'));
}
...
<vue-slider ...>
...
</vue-slider>

Related

Vue 2.7 getCurrentInstance() trying to get properties like $vuetify

I'm trying to migrate from vuetify 2.6 to 2.7 because of composition-api but I'm getting a lot of errors when trying to get properties of the Vue instance, for example I'm using vue with Vuetify and I have a separed "helper" to try to get the $vuetify instance but everytime I'm getting undefined even when I'm trying to get the property from a setup() in the App.vue I get undefined, same thing happened when trying to get the $route property of vue-router from the instance with getCurrentInstance() then only solution I had with the router was using an internal composable of vue-router/composables to get the route.
Another thing that also happens is that the getCurrentInstance() sometimes returns null.
My main.js looks like:
import Vue from 'vue'
...
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
...
Vue.config.productionTip = false
new Vue({
router,
store,
vuetify,
render: h => h(App),
}).$mount('#app')
./plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib/framework'
Vue.use(Vuetify)
export default new Vuetify({
preset
...
})
App.vue
<template>...</template>
<script>
import { getCurrentInstance } from 'vue'
export default{
setup(){
console.log( getCurrentInstance().proxy, getCurrentInstance().proxy.$vuetify )
// returns: {}, undefined
// sometimes returns null, undefined
}
}
</script>
versions:
"vue": "^2.7.11"
"#vue/cli-service": "~5.0.8"
"vuetify": "^2.6.11"
Anyone knows what it could be?, Thanks.
Edited: Can't reproduce in vue v2.7.12. I tried vue v2.7.11 and can reproduce your issue. There is a severe regression in v2.7.11, please upgrade your vue.
Here is a minimal example of v2.7.12.
https://stackblitz.com/edit/vitejs-vite-fjpdck
getCurrentInstance().proxy does return a VueComponent and getCurrentInstance().proxy.$vuetify gets the vuetify instance successfully.
By the way, the recommended way to get $route instance in setup is
import { useRoute } from 'vue-router/composables' // need vue-router v3.6
export default{
setup(){
const route = useRoute()
}
}

Vue / Vuex. Vuex store properties not accessible from my component

I have a vue app, and a component. The component is registered and rendering just fine. I just imported vuex to help with state management. I am using typescript and vue-class-decorator for better type safety.
My app look like so: .ts
// load vuex stores
let store = require('./store/store.ts');
// register components here...
Vue.component('my-component', require('./components/MyComponent.vue'));
// initialize vue applications here...
const app = new Vue({
el: '#app',
store
});
I can console.log the store and see that store is indeed required correctly.
Here's my store: .ts
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
active: false,
},
getters: {
isActive: state => state.active
}
});
Here's my component: .ts
import { Vue, Component, Prop } from 'vue-property-decorator'
import axios from 'axios'
#Component
export default class MyComponent extends Vue {
#Prop(String) route?: string
resent: boolean = false
loading: boolean = false
// constructor
mounted (): void {
if (!this.route) {
throw new Error("The route property is missing");
}
}
get myActiveState (this :Vue): any {
console.log(this.$store);
return this.$store.getters.isActive;
}
}
It doesn't matter what I try, I cannot access the stores state property. I can console log this.$store and I do indeed get the correct store, same if I put a breakpoint in and inspect I can directly access the active property, but if I try and console log this.store.state.active or this.store.getters.isActive, then I get an error.
[Vue warn]: Error in render: "TypeError: Cannot read property 'isActive' of undefined"
I can put a breakpoint in and inspect the console to double check the contents of each property. Everything looks good. BUT i cannot access the property with $store.state.active I have to do $store.default.state.active.
What is going on here? Why can I not access the state when it's coded? Additionally trying to code this.$store.default.state.active gives me a build error property does not exist on type Store<any>
This guy applies a nice solution to this problem https://www.youtube.com/watch?v=V9MmoBAezD8
in a nutshell, you have to create a shims-vuex.d.ts to solve this problem, as documented by vuex v4.0.0 release
the State type will be exported from your store/index.ts and it should be a representation of your state
import { State } from './store/index.ts';
declare module '#vue/runtime-core' {
interface ComponentCustomProperties {
$store: Store<State>;
}
}
// Vuex#4.0.0-beta.1 is missing the typing for `useStore`. See https://github.com/vuejs/vuex/issues/1736
declare module 'vuex' {
export function useStore(key?: string): Store<State>;
}

Implement npm package custom component VueJS

I'm trying to use the following npm-package to bypass X-frame options:
https://www.npmjs.com/package/x-frame-bypass
Which requires the following tag to be inserted inside your HTML:
<iframe is="x-frame-bypass" src="https://example.org/"></iframe>
When I install the package, and add the following lines to my App.js
import {FontAwesomeIcon} from '#fortawesome/vue-fontawesome'
import {xframe} from 'x-frame-bypass' <-- importing the npm package
library.add(faCoffee, faLink, faUser, faSync, faArrowLeft, faPlay, faCheck, faTimes, faEdit, faPause, faStepForward, faCog, faUserCircle, faInfoCircle, faSignOutAlt, faImages)
Vue.use(spatial)
Vue.use(progress)
Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.component('x-frame-bypass', xframe) <-- adding the xframe component
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {
App
},
template: '<App/>'
})
The console throws the following error:
Vue warn: Unknown custom element: <x-frame-bypass> - did you register the component correctly?
So I went into the Vue component in which I use the iframe, and add this to the components:
import xframe from 'x-frame-bypass'
export default {
name: 'Component',
components: {
Button,
'x-frame-bypass': xframe
},
But then the console says the following:
Failed to mount component: template or render function not defined.
What is the right way to make this possible? or is it not possible to make this work?
Seems like you are making a small mistake in syntax.
why are you doing
import {xframe} from 'x-frame-bypass' in your root
and
import xframe from 'x-frame-bypass' in your component
let us know if that helps

How to import a js class in main.js file of a vue.js project and use it in all the components instead of importing in each component?

I have written some JS classes that I would like to import in the app.js/main.js file of my vue.js project so that I can instantiate them in the components. Right now I am having to import the same JS class in all the components where I need the class individually.
I've tried the import in the main.js file but the components don't recognize it.
in the main.js file, I am importing like as follows
import Permissions from './Permissions'
However, when I want to instantiate the Permissions class in my component like
data() {
permissions: new Permission({
some object properties...
})
}
the component doesn't know what Permissions is.
How do I let the component know what Permissions class is?
To do it in the vue way, you can create your own plugin or mixin. See detailed instructions here
So, you can create a permissions plugin in permissions-plugin.js
import Permissions from './Permissions'
const PermissionsPlugin = {
install(Vue, options) {
// This adds the $getPermissions method to all instances
Vue.prototype.$getPermissions = function(properties) {
return new Permission({
some object properties...
})
}
}
};
Then you have to tell vue to use your plugin:
import Vue from 'vue'
import PermissionsPlugin from './permissions-plugin.js'
import App from './App.vue'
// The plugin is loaded here.
Vue.use(PermissionsPlugin)
new Vue({
el: '#app',
render: h => h(App)
});
And lastly now from any component you should be able to use your function like:
this.$getPermissions(properties)

export 'AddPlaceModal' was not found in '~/components/AddPlaceModal.vue'

I just started using nuxt for vue. I added a component in the /components folder and I am trying to use it in one of my pages.
Unfortunately, I get this warning, upon compilation:
"export 'AddPlaceModal' was not found in '~/components/AddPlaceModal.vue'
I am trying to use it via:
<script>
import {mapActions, mapGetters} from 'vuex';
import {AddPlaceModal} from '~/components/AddPlaceModal.vue';
export default {
components: {
'add-place-modal': AddPlaceModal
},
...
The component itself looks like:
<script>
export default {
data() {
googleLocation: null;
},
...
Any ideas why this may be?
You need to import from default export, not a named export
import AddPlaceModal from '~/components/AddPlaceModal.vue';
you have to remove the curly brackets
do this:
instead of:

Categories

Resources