Component does not show in vue - vue.js

I do not get vue components really .... I have a vue component in my html and want to show it, but it does not show anything, what do I do wrong?
What is the proper way to register and show a component in vue? Can someone give me a simple example for a beginner? :)
This is my code:
HTML
<div id="na-vue-app">
<activity-filter>
<template>
'Some Text'
</template>
</activity-filter>
</div>
Vue
new Vue({
el: '#na-vue-app'
});
const filterActivity = Vue.extend({
data: function () {
return {
distance:100,
}
},
mounted() {
},
methods: {
}
});
Vue.component('activity-filter', filterActivity);

Look at this pen: https://codepen.io/Nartub600/pen/oopBYJ
HTML
<div id="app">
<my-component msg="Hi!">
</my-component>
</div>
JS
Vue.component('my-component', {
props: ['msg'],
template: '<p>{{ msg }}</p>'
})
var app = new Vue({
el: '#app'
})
It's the easiest form to try components I think

Related

How to display stub component when component is not found in vue

I am trying to catch situation, when component is not found, ie:
{
template: '<some-unknown-component></some-unknown-component>'
}
At that moment, Vue warns us with unknown custom element: <some-unknown-component>...
I would like to step in when some-unknown-component is not found and then use another component instead, like stub-component:
{
name: 'stub-component',
props: ['componentName'],
template: '<p>component ${componentName} does not exists, click here to create...</p>'
}
UPDATE: I am looking for solution without changing the template itself, so no v-if and component added.
Vue exposes a global error and warning handler. I managed to get a working solution by using the global warnHandler. I don't know if it is exactly what you are looking for, but it may be a good starting point. See the working snippet (I think it is quite self explanatory).
Vue.config.warnHandler = function (err, vm, info) {
if (err.includes("Unknown custom element:")) {
let componentName = err.match(/<.*>/g)[0].slice(1, -1)
vm.$options.components[componentName] = Vue.component('stub-component', {
props: ['componentName'],
template: `<p>component "${componentName}" does not exists, click here to create...</p>`,
});
vm.$forceUpdate()
} else {
console.warn(err)
}
};
new Vue({
el: '#app',
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<unknown-component></unknown-component>
</div>
Vue stores the details of all the registered components in the $options.component property of the Vue instance.
So, you can check for the component availability using this.$options.component and if the component is present then load the component otherwise load the other component.
In the below example, suppose you have two different components and you want to load them on the availability, then you can create a computed property on the basis of it, load the component as needed.
var CustomComponent = Vue.extend({ template: '<h2>A custom Component</h2>' });
var AnotherComponent = Vue.extend({ template: '<h2>Custom component does not exist.</h2>' });
new Vue({
el: "#app",
components: {
CustomComponent,
AnotherComponent
},
computed: {
componentAvailable () {
return this.$options.components.CustomComponent
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-if="componentAvailable">
<custom-component />
</div>
<div v-else>
<another-component />
</div>
</div>

How to pass data into components in vue.js?

I have this
<template id="vButton">
<button v-bind:title="name">{{name}}</button>
</template>
<div id="app">
<ti-button></ti-button>
</div>
js
Vue.component('ti-button', {
props: ['name'],
template: '#vButton'
});
var vm2 = new Vue({
el: '#app',
data: {
name : 'hi'
}
});
I want the button to have innerText and title attribute to say 'hi'. But it does not. Does anyone know why?
Ref: https://v2.vuejs.org/v2/guide/components.html
Thanks
Vue.component('ti-button', {
props: ['name'],
template: '#vButton'
});
var vm2 = new Vue({
el: '#app',
data: {
name: 'hi'
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<script type="text/x-template" id="vButton">
<div>
<button>{{name}}</button>
<button>{{$root.name}}</button>
</div>
</script>
<div id="app">
<ti-button name="first_button"></ti-button>
</div>
UPD:
Do you mean you don't see this?
You are doing things mostly right, you just need to pass your data to your prop using a v-bind:
<ti-button v-bind:name="name"></ti-button>
Static values can be passed without v-bind but for dynamic values like you are attempting to pass you need to bind the prop. Check out the static/dynamic prop documentation for more information.
And here is a working demo: https://codepen.io/egerrard/pen/qJpzMQ

How to pass multiple props from parent to child component in Vue

I'm trying to pass two properties from parent to child, but for some reason this isn't working and all the examples I've found refer to passing a single property. What I've tried to do is:
Parent vue component:
<template>
<div class="statistics_display">
<multiLineChart :rowsA="reading['A'].price_stats" :rowsB="reading['B'].price_stats"></multiLineChart>
</div>
</template>
multiLineChart vue component:
export default {
name: 'MultiLineChart',
props: ['rowsA', 'rowsB'],
mounted: function() {
console.log(this.rowsA);
}
the console log is returning undefined. If I executethe exact same code and pass a single prop, it returns the expected prop contents. What am I missing?
HTML attributes are case-insensitive, so
<multiLineChart :rowsA="reading['A'].price_stats" :rowsB="reading['B'].price_stats"></multiLineChart>
Are actually bound to props: ['rowsa', 'rowsb'].
If you want props: ['rowsA', 'rowsB']to work, use, in the template: :rows-a="..." and :rows-b="...".
See it working below.
Vue.component('multilinechart', {
template: "#mtemplate",
props: ['rowsA', 'rowsB'],
mounted: function() {
console.log(this.rowsA, this.rowsB);
}
})
new Vue({
el: '#app',
data: {
reading: {A: {price_stats: 11}, B: {price_stats: 22}}
}
});
<script src="https://unpkg.com/vue#2.5.13/dist/vue.min.js"></script>
<div id="app">
<div class="statistics_display">
<multiLineChart :rows-a="reading['A'].price_stats" :rows-b="reading['B'].price_stats"></multiLineChart>
</div>
</div>
<template id="mtemplate">
<div>I'm multilinechart</div>
</template>

Vue: remove a component when other is completely loaded

<template>
<div id="app">
<Loading></Loading>
<Content></Content>
</div>
</template>
<script>
import Loading from './Loading.vue'
import Content from './Content.vue'
export default {
name: 'App',
components: {
Loading,
Content
}
}
</script>
What is the best and elegant way to handle a loading component and remove it (or vue component or change styles) when all page is loaded?
I tried with v-cloack, but I think its not working beyond data stuff.
I tried with mounted, but doesn't seems to work.
v-cloak is to hide un-compiled mustache bindings until the Vue instance is ready. So you can use v-if to show/hide loading component.
var child1 = Vue.extend({
template: "<div>Loading...</div>"
});
var child2 = Vue.extend({
template: "<div>After Component loaded</div>",
});
var app = new Vue({
el: "#vue-instance",
data: {
loading: true
},
mounted() {
var vm = this;
setTimeout(function() {
vm.loading = false;
}, 1000);
},
components: {
child1,
child2
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.1/vue.js"></script>
<div id="vue-instance">
<child1 :name="name" v-if="loading"></child1>
<child2 :name="name" v-if="!loading"></child2>
</div>

How get data from from Vue Template?

I have got next HTML:
<div id="app">
<component :is="currentView"></component>
</div>
Vue code:
var GuestMenu = Vue.extend({
template: `
<input v-model="username">
`});
Vue.component('guestmenu', GuestMenu);
var App = new Vue ({
el: '#app',
// template: '<usermenu></usermenu>',
data:
{
currentView: "guestmenu",
username: ""
}
})
I need to get username from v-model. The problem that all examples show how to get it's directly, but my data placed in template...
http://jsfiddle.net/u9L569ku/
I believe that this is what you want to achieve. Basically, there is a parent-child realtionship in your example but the communication was not set up correctly. The username in your component was not bound to the username in the Vue instance's data.
jsfiddle
html
<div id="app">
<component :username.sync="username" :is="currentView"> </component>
{{username}}
</div>
javascript
var GuestMenu = Vue.extend({
props : ['username'],
template: `<input v-model="username">`
});
Vue.component('guestmenu', GuestMenu);
var App = new Vue ({
el: '#app',
data: {
currentView: "guestmenu",
username: ""
}
})