vue faile to load mount component - vue.js

I have to do some simple thing.
I have to generate different select options to generate different data.
So I create component and I passing array with values, but only in theory xD
When I go to road i got error cold:
app.js:37990 [Vue warn]: Failed to mount component: template or render
function not defined.
found in
---> <SelectComponent> at resources/js/components/SelectComponent.vue
<ExampleComponent> at resources/js/components/ExampleComponent.vue
<Root>
My component is simple for test do,
<h1> test connection </h1>
<script>
export default {
name: 'SelectComponent',
data () {
return {}
}
}
</script>
my main component
import SelectComponent from './SelectComponent.vue';
export default {
components: {
SelectComponent,
},
mounted() {
console.log('Component mounted.')
},
}
where is my issue?

If you look at the documentation you'll see that the HTML should be wrapped in the <template> element. So change your component to:
<template>
<h1> test connection </h1>
</template>
<script>
export default {
name: 'SelectComponent',
data () {
return {}
}
}
</script>

Related

Vue 3, what can be the cause of "Failed to resolve component" error?

I am trying to include one component into another component, but I am getting the error "Failed to resolve component: applications-overview-table" in the browser console.
Parent component "src/pages/ApplicationsOverview.vue":
<template>
<q-page class="flex flex-center">
<applications-overview-table></applications-overview-table>
</q-page>
</template>
<script>
import ApplicationsOverviewTable from '../components/application/OverviewTable.vue';
export default {
name: 'ApplicationsOverviewPage',
components: [ApplicationsOverviewTable],
setup() {
console.log('loading applications overview');
return {};
},
};
</script>
<style></style>
Child component "src/applications/OverviewTable.vue":
<template>
<div class="q-pa-md">
<q-table title="Aanvragen" :rows="rows" :columns="columns" row-key="name" />
</div>
</template>
<script>
const columns = [ ... ];
const rows = [ ... ];
export default {
name: 'ApplicationsOverviewTable',
setup() {
return {
columns,
rows,
};
},
};
</script>
I can see that the parent component is being loaded, because the console message "loading applications overview" is being shown in the console.
I can also see that the path to OverviewTable.vue is correct, because if I change the path I get another error.
I tried to change <applications-overview-table> to <ApplicationsOverviewTable> but this gives me the same error (with the tag-name different of course).
It is right that I should change the CamelCase component name to dash-case in the templete, isn't it?
What am I doing wrong?
components option has an object as value not an array, it should be :
components: {ApplicationsOverviewTable},
this a shorthand of :
components: {
ApplicationsOverviewTable : ApplicationsOverviewTable
},

vue-chartjs load data from parent component

I have a component for a LineChart, here is the code :
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: ['data', 'options'],
mounted () {
this.renderChart(this.data, this.options)
}
}
</script>
I want to use this component in another one as I can affect data to data and options value of the component Chart.vue.
I'm new to VueJS and can't understand an example like that in vue-chartjs doc.
Here is my component that will be the parent one, and what I've done from now :
<template>
<div class="dashboard">
<chart></chart>
</div>
</template>
<script>
import Chart from '#/components/Chart'
export default {
name: 'DashBoard',
components: {
'chart': Chart
},
mounted () {},
data () {
return {
datacollection: null
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Where does your data come from?
Your example code is weird, as you are not passing your data as props.
So no wonder, that nothing shows up.
You have to pass your datacollection to your chart component.
<chart :data="datacollection" />
And keep in mind, that if you are using an API your data will arrive async. So the component mounts, renders the chart but your data is not there. So you need to add a v-if to be sure that your api call is finished.

Why this.$listeners is undefined in Vue JS?

Vue.js version: 2.4.2
Below component always print this.$listeners as undefined.
module.exports = {
template: `<h1>My Component</h1>`,
mounted() {
alert(this.$listeners);
}
}
I register the component and put it inside a parent component.
Can someone tell me why?
You have to understand what $listeners are.
this.$listeners will be populated once there are components that listen to events that your components is emitting.
let's assume 2 components:
child.vue - emits an event each time something is written to input field.
<template>
<input #input="emitEvent">
</input>
</template>
<script>
export default {
methods: {
emitEvent() {
this.$emit('important-event')
console.log(this.$listeners)
}
}
}
</script>
parent.vue - listen to the events from child component.
<template>
<div class="foo">
<child #important-event="doSomething"></child>
</div>
</template>
<script>
import child from './child.vue'
export default {
data() {
return {
newcomment: {
post_id: 'this is default value'
}
}
},
components: { child },
methods: {
doSomething() {
// do something
}
}
}
</script>
With this setup, when you type something to the input field, this object should be written to the console:
{
`important-event`: function () { // some native vue.js code}
}
I added the following alias to my webpack.config.js file and this resolved the issue for me:-
resolve: {
alias: {
'vue$': path.resolve(__dirname, 'node_modules/vue/dist/vue.js')
}
},

Pass data from one component to all with $emit without using #click in VueJS

Trying to learn vuejs I got to the question how to pass any data from one component to all, using $emit but without using any #click.
It is possible some how that the data to be just available and grab it any time, without using the click?
Let's say we have this example with normal #click and $emit.
main.js
export const eventBus = new Vue()
Hello.vue
<template>
<div>
<h2>This is Hello component</h2>
<button
#click="emitGlobalClickEvent()">Click me</button>
</div>
</template>
<script>
import { eventBus } from '../main'
export default {
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods: {
emitGlobalClickEvent () {
eventBus.$emit('messageSelected', this.msg)
}
}
}
</script>
User.vue
<template>
<div>
<h2>This is User component</h2>
<user-one></user-one>
</div>
</template>
<script>
import { eventBus } from '../main'
import UserOne from './UserOne.vue'
export default {
created () {
eventBus.$on('messageSelected', msg => {
console.log(msg)
})
},
components: {
UserOne
}
}
</script>
UserOne.vue
<template>
<div>
<h3>We are in UserOne component</h3>
</div>
</template>
<script>
import { eventBus } from '../main'
export default {
created () {
eventBus.$on('messageSelected', msg => {
console.log('From UserOne message !!!')
})
}
}
</script>
I want to get this message : Welcome to Your Vue.js App from Hello.vue in all components, but without #click, if is possible.
You can create another Javascript file which holds an Object with your initial state. Similar to how you define data in your components.
In this file your export your Object and import it in all Components which need access to this shared state. Something along the lines of this:
import Store from 'store';
data() {
return {
store
}
}
This might help:
https://v2.vuejs.org/v2/guide/state-management.html
At this point if you app grows even more in complexity you might also start checking out Vuex which helps to keep track of changes(mutations) inside of your store.
The given example is essential a very oversimplified version of Vuex.

Existing component throw: Unknown custom element

I'm trying to use a component in another component. On the created event, I can log this component and it returns the good object. However for some reasons, the component doesn't seem to be included. VueJS do not understand the validation tag.
Any ideas?
<template>
<main>
<validation :validate="$v.email" :model="'email'"></validation>
</main>
</template>
<script>
import { Validation } from 'components/helpers'
export default {
name: 'login',
component: { Validation },
created() {
// it works. print the component with his path
window.console.log(Validation)
}
}
</script>
[Vue warn]: Unknown custom element: - did you register
the component correctly? For recursive components, make sure to
provide the "name" option.
In components/helpers I have two file:
1) index.js
export { default as Validation } from './Validation'
2) Validation.vue
<template>
<div>
<span class="form__validation" v-if="validate && !validate.required">Required</span>
<template v-if="validation[model]">
<span class="form__validation" v-for="error in validation[model].messages">{{ error }}</span>
</template>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'validation',
data() {
return {
L: L
}
},
props: ['model', 'validate'],
computed: {
...mapGetters({
validation: 'getValidation'
})
}
}
</script>
Changing component for components did the trick. Shame on me :)