I'm trying to create a vue app for budget tracking and I have a BudgetItems component that I want to render in the /budget route. All the other components and raw HTML render but this one component does not
This is the BudgetItems component:
<template>
<div>
<BudgetItem v-for="item in Items" v-bind:key='item.id' v-bind:Item="item" />
</div>
</template>
<script>
import BudgetItem from './BudgetItem'
export default {
name: 'BudgetItems',
components: {
BudgetItem,
},
props: [
'Items'
]
}
</script>
And this is the BudgetItem component I used to render a single item:
<template>
<div class="budgetitem">
<h1>{{item.title}}</h1>
<h1>{{item.value}}</h1>
</div>
</template>
<script>
export default {
name: 'BudgetItem',
props: [
'Item'
]
}
</script>
Last of all, this is the Budget page view:
<template>
<div class="budget">
<Nav />
<h1>Budget</h1>
<BudgetItems v-bind:Items="items" />
</div>
</template>
<script>
import Nav from "../components/Nav"
import BudgetItems from "../components/BudgetItems"
export default {
name: 'Budget',
components: {
Nav,
BudgetItems,
},
data(){
return{
items: [
{
id: 1,
income: false,
title: "Item 1",
value: 200
},
{
id: 2,
income: true,
title: "Item 2",
value: 500
},
{
id: 3,
income: false,
title: "Item 3",
value: 10
},
]
}
}
}
</script>
Also, when I look in the vue dev tools tab, the component appears, it just doesn't show on the screen
You need to change the v-bind declarations to lower case. Replace each instance of Items and Item with items and item.
Vue.JS doesn't like it if you capitalise props when using binding.
Please read this for more explanation.
Essentially, browsers treat all attribute names as lowercase. As a result, it interprets "Items" as being "items".
Budget page view:
<BudgetItems v-bind:items="items" />
BudgetItems:
<BudgetItem v-for="item in items" v-bind:key='item.id' v-bind:item="item"/>
props: [
'items'
]
BudgetItem:
props: [
'item'
]
Once you make these changes, it works perfectly as seen here:
Related
I am facing one problem while working with v-select component. V-select component is not showing selected item... It is showing options in dropdown but after selecting it is showing blank in select box.
This is the problem-
Dropdown is showing.. but not showing anything after selecting.
Like this.. It is blank.
Here is my code
<template>
<div>
<v-select
label="broadcast"
v-model="broadcast_"
:options="broadcasters"
:reduce="(broadcast) => broadcast.id"
>
<template v-slot:option="option">{{ option.name }}</template>
</v-select>
</div>
</template>
<script>
import Vue from "vue";
import vSelect from "vue-select";
Vue.component("v-select", vSelect);
export default {
data() {
return {
broadcasters: [
{
name: "ABC Live",
id: 1,
},
{
name: "Disney",
id: 3,
},
{
name: "24x7 Broadcast",
id: 4,
},
],
broadcast_: "",
};
},
watch: {
broadcast_(val) {
console.log(val); //It prints desire data (i.e broadcast id)
},
},
};
</script>
I don't know exactly what you wanted with your :reduce statement.
But if you change your code where
label="broadcast"
to
label="name"
or
label="id"
You will get the text in the selectbox
in my app i need to add components to the dom after fetching data from an api
i have a component called Carousel and a component called Home
so i don't know how many carousels i need in my Home component
the question is : how can i add components using for loop from inside methods:{}
My Code :
Home.vue
<template>
<div>
<template
v-for="widget in widgets"
v-bind:is="Carousel">
{{ widget }}
</template>
</div>
</template>
<script>
import Carousel from './widgets/Carousel.vue'
export default {
components: {
Carousel
},
data() {
return {
page_content: [],
widgets: [],
}
},
created() {
this.getHomeContent();
},
methods:
{
addWidget() {
this.widgets.push('Carousel')
},
getHomeContent() {
window.axios.get(window.main_urls["home-content"]).then(response => {
this.page_content = JSON.parse(JSON.stringify(response.data));
this.addWidget()
});
}
}
}
</script>
Carousel.vue
<template>
<div>
<div :class="this.type == 'full' ? '' : 'container'">
Slider
</div>
</div>
</template>
<script>
export default
{
name:'Carousel',
props:[
'type',
'showTitle',
'dots',
'controls',
'data'
],
methods:
{
}
}
</script>
How to create as much carousels is i need using loop
the above code just give me a string 'carousel'
i want the component to be rendered
Here is a working example of dynamic components with properties
<div>
<template v-for="item in widgets">
<component :is="item.name" :name="item.name" v-if="item.name==='carousel'"></component>
</template>
</div>
The data in widgets
widgets: [
{name: 'carousel'},
{name: 'carousel'},
{name: 'test'},
{name: 'carousel'},
]
then it will create three components.
I created a test component like this to check this
components: {
'carousel': {
template: "<div>Dynamic component {{name}}</div>",
props: ["name"]
}
},
I'm building a Vuetify app in combination with Vuex and vue-router. Some of the views uses the default navigation drawer, but others has different items in their navigation drawers. This documentation say I can pass props to view components. So I implement it like this:
routes/index.js
{
path: '/courses/:courseId/lessons/:lessonId',
name: 'Course 1',
components: {
default: () => import('#/views/ViewLesson.vue'),
sidebar: () => import('#/components/CourseNavBar/CourseNavBar.vue')
},
props: {
items: [
{ text: "Link 1", href:"/link1" },
{ text: "Link 2", href:"/link2" }
]
}
}
src/App.vue
<template>
<v-app>
<v-app-bar
app
color="primary"
dark
>
<h1>My Project</h1>
</v-app-bar>
<v-navigation-drawer><router-view :items="items" name="sidebar"/></v-navigation-drawer>
<v-content>
<router-view />
</v-content>
</v-app>
</template>
But apparently,
src/components/CourseNavBar.vue
<template>
<!-- <v-navigation-drawer :value="1"> -->
<v-list dense>
<navbar-item v-for="(item, i) in items" :key="i" :item="item" >
{{ item.text }}
</navbar-item>
</v-list>
<!-- </v-navigation-drawer> -->
</template>
<script>
import NavBarItem from './NavBarItem.vue'
export default {
props: {
items: Array
},
components: {
'navbar-item': NavBarItem
}
}
</script>
But <CourseNavBar>'s props is still undefined. What am I doing wrong here?
There are a few issues...
Replace = with :...
items: [
{ text:"Link 1", href:"/link1" },
{ text:"Link 2", href:"/link2" }
]
And the sidebar component (not router-view) should be in the slot for the navigation-drawer...
<v-navigation-drawer><sidebar :items="items"></sidebar></v-navigation-drawer>
Demo: https://codeply.com/p/oNInfpTwvK
In your
routes\index.js
you need to define the props option for each of the named views:
{
path: '/courses/:courseId/lessons/:lessonId',
name: 'Course 1',
components: {
default: () => import('#/views/ViewLesson.vue'),
sidebar: () => import('#/components/CourseNavBar/CourseNavBar.vue')
},
props: {
default: true,
sidebar: true,
items: [
{ text: "Link 1", href: "/link1" },
{ text: "Link 2", href: "/link2" }
]
}
}
And following on from what #Zim said, you've used "=" instead of ":" when assigning the href value to the props items array.
You can use <router-view name="sidebar"/> to output the named component.
I have a problem to read the passed data via props in Vue.js from parent to child. I have a list of components
components: [
{
name: "Cart Overview",
component: "CartOverview",
props: this.shopperCart
},
{
name: "Bank Account Overview",
component: "BankAccountOverview",
props: {}
},
{ name: "Verification", component: "Verification", props: {} },
{
name: "Completion Message",
component: "CompletionMessage",
props: {}
}
]
The variable "shopperCart" is set by a request from a backend.
Template of the parent component
<div class="modal-body">
<component
:is="checkoutComponents[currentStep].component"
v-bind="checkoutComponents[currentStep].props"
></component>
</div>
The user can navigate through the components with a next step button who sets the variable currentStep.
Example of one child component
<template>
<div>
<h1>Cart Oerview</h1>
{{ shopperCart }}
</div>
</template>
<script>
export default {
name: "CartOverview",
props: {
shopperCart: { type: Object, default: () => {} }
},
mounted() {
console.log("shopperCart", this.shopperCart);
}
};
</script>
The components lie on a modal. The log output only shows up displaying undefined when I refresh the page, where I can open the modal.
Can someone please help me?
Best regards,
A. Mehlen
I found myself a solution. I changed in the parent component the v-bind with :data
<div class="modal-body">
<component
:is="checkoutComponents[currentStep].component"
:data="checkoutComponents[currentStep].props"
></component>
</div>
and in the child component the name of the prop
<template>
<div>
<h1>Cart Oerview</h1>
{{ data }}
</div>
</template>
<script>
export default {
name: "CartOverview",
props: {
data: { type: Object, default: () => {} }
},
mounted() {
console.log("shopperCart", this.data);
}
};
</script>
Now it works :-)
In my project, I use vue.js.
I want to display content of list with nested loop。 In parent page, i have defined:
<template>
<div>
<detail-header></detail-header>
......
<detail-list></detail-list>
</div>
</template>
The component of detail-list is :
<template>
<div>
<div v-for="(item, index) of list" :key="index">
<div class="item-title border-bottom">
<span class="item-title-icon"></span>
{{item.title}}
</div>
<div v-if="item.children" class="item-children">
<detail-list :list="item.children"></detail-list>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'DetailList',
props: {
list: Array
},
data () {
return {
list: [{
title: 'adult',
children: [{title: 'threePeople',children: [{ title: 'threePeople-w'}]}, {title: 'fivePeople'}]
}, {
title: 'student'
}, {
title: 'child'
}, {
title: 'offer'
}]
}
}
}
</script>
unlucky, I got a error message:
Duplicated key 'list' of list: [{ in detail-list
who can help me ?
If you want this to work, keep the list in props (and remove it from DetailList's data) and define in your parent page's data.
So the first DetailList and its children will have the list as a prop.
So you'll have in the parent page :
<template>
<div>
<detail-header></detail-header>
......
<detail-list :list="list"></detail-list>
</div>
</template>
<script>
export default {
name: 'Parent',
data () {
return {
list: [{ ... the list ... }]
}
}