Cannot render list using V-for in VueJs - vue.js

I am very new in Vue and I am trying to loop through an array. Don't exactly know what I am doing wrong but the list is not displaying on HTML. Here is the code below: This is an index file that is being rendered through a router view.
<template>
<div class="index container">
<div class="card" v-for="tournament in tournaments" :key="tournament.id">
<div class="card-content">
<h2 class="indigo-text">{{tournament.title}}</h2>
<ul class="tournaments">
<li v-for="(score,index) in tournamnet.scores" :key="index"></li>
<span class="chip">{{score}}</span>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'index',
data () {
return {
tournaments:[
{title:'Muthaiga golf Tournament',slug: 'muthaiga-golf-tournament',scores:['Round 1', 'Round 2', 'Round 3'],id:'1'},
{title:'Wilson Churchhill',slug: 'Wilson Churchhill',scores:['Round 1', 'Round 2', 'Round 3'],id:'2'},
]
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
Here is the router view index.js
import Vue from 'vue'
import Router from 'vue-router'
import index from '#/components/index'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'index',
component: index
}
]
})
And here is the app.vue
<template>
<div id="app">
<navbar />
<router-view/>
</div>
</template>
<script>
import navbar from '#/components/navbar'
export default {
name: 'App',
components:{
navbar
}
}
</script>
Any help will be highly appreciated.

Place your span inside the v-for
<ul class="tournaments">
<li v-for="(score,index) in tournament.scores" :key="index+'tournament'">
<span class="chip">{{score}}</span>
</li>
</ul>
Also, it is better not to use the index as a key, I added string 'tournament' to make it more unique.
Additionally, please make sure you got the spelling corrected for 'tournament'.
Link to official docs.

You have a typo on <li v-for="(score,index) in tournamnet.scores" :key="index"></li>
Mispelled tournament
If you look in the console you should see
vue.runtime.esm.js?2b0e:619 [Vue warn]: Property or method "score" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <Index> at src/components/index.vue
<App> at src/App.vue
<Root>

Related

How to make text interpolation work inside css functions and router links

I was trying to implement a reusable card component, so I printed them out inside variable properties that is changed image by image
This is my code. As for title, it works perfectly. I implemented it many times, so my issue is different. I also added this props' text inside mustaches, so I can change link and image out of my card, but it doesn't work, so I need your help. I might just not understand how text interpolation works. But I think that vue supports the way to create reusable cards within a component
<template>
<RouterLink class="card" to="{{ link }}">
<div class="card__background" style="background-image: url({{ image }})"></div>
<div class="card__content">
<h3 class="card__heading">{{ title }}</h3>
</div>
</RouterLink>
</template>
<script>
import { RouterLink } from 'vue-router';
export default {
props: ['link', 'image', 'title'],
created() {
console.log(this.link)
console.log(this.image)
console.log(this.title)
},
}
</script>
I think you need to use the v-bind directive. This directive allows you to bind the value of an HTML attribute to a dynamic expression.
Here's how you can modify your code to use the v-bind directive:
<template>
<RouterLink class="card" v-bind:to="link">
<div class="card__background" v-bind:style="{ backgroundImage: `url(${image})`
}"></div>
<div class="card__content">
<h3 class="card__heading">{{ title }}</h3>
</div>
</RouterLink>
</template>
<script>
import { RouterLink } from 'vue-router';
export default {
props: ['link', 'image', 'title'],
created() {
console.log(this.link)
console.log(this.image)
console.log(this.title)
}
}
</script>

VueJS: How can I pass params into a component?

I am new to vueJS.
What I want to do is passing parameters to a component, depending on the selection of the routes. Here is my App.vue:
<template>
<div id="main">
<header>
<h1 style="color:red">{{msg}}</h1>
</header>
<div>
<aside class="sidebar">
<router-link v-for="el in this.$router.options.routes" :to="el">
{{el.name}}
</router-link>
</aside>
<SubMenu></SubMenu>
<div class="content">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import SubMenu from './components/SubMenu.vue'
export default {
components: {
'SubMenu': SubMenu
},
data() {
return {
msg: 'Welcome to Your Vue.js App' }
}
}
</script>
<style>
#import 'style.css';
#import 'grid.css';
</style>
and the SubMenu component I would like to make dynamic:
<template>
<div>
something dynamic
</div>
</template>
How can I pass some parameters to use in the component?
thank you
Your App.vue can be like this:
<template>
<div id="main">
<header>
<h1 style="color:red">{{msg}}</h1>
</header>
<div>
<aside class="sidebar">
<router-link v-for="el in this.$router.options.routes" :to="el">
{{el.name}}
</router-link>
</aside>
<SubMenu :menuTitle="subMenuTitle"></SubMenu>
<div class="content">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import SubMenu from './components/SubMenu.vue';
export default {
components: {
SubMenu
},
data() {
return {
subMenuTitle: "This is the sub menu",
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style>
#import 'style.css';
#import 'grid.css';
</style>
The SubMenu.vue component could be like this:
<template>
<div>
<h2>{{ menuTitle }}</h2>
something dynamic
</div>
</template>
<script>
export default {
name: "SubMenu",
props: {
menuTitle: String,
}
}
</script>
In the SubMenu component that was used in App.vue, notice the colon that appears before the menuTitle attribute. When you do that before an attribute, the value of that attribute would be evaluated by Vue and passed to the component. You can pass literal Javascript expressions or items in your App.vue component.
In the SubMenu component, you can use the props in whatever way you can. If the prop's value is an array, you can use the v-for directive with it to create a list of items in the SubMenu.
Welcome to SO,
In Vue.js passing parameters to components is called "Props"
You can pass props to your SubMenu like below
<SubMenu :id="12345" someText="Some Text About Something" :dataArray="[1,2,3,4,5]" />
then inside your SubMenu component you can define Prop Types as below
props: ['dataArray']
or
props: {
dataArray: {
type: Array,
default: []
}
}
After that you can use the data you passed to your liking
You can also read up on this Vue Documentation regarding the Props, which has much more detailed explanations about various Props related stuff and sample code
Ok many thanks to both.
But what if I would like to pass something that depends on the voices in router-link? I mean, router-link prints a menu with 4 voices...what if I would like a behavior like this:
click on voice1 in router-link ---> pass this object ['input1', 'input2'] to SubMenu
click on voice2 in router-link ---> pass this other object ['input3', 'input4', 'input5'] to SubMenu
and so on.
thanks again :)

Implementing a reusable tabbed component using Vuejs

I'm trying to implement a tabbed reusable component in vueJs but I'm getting an error that a particular component is not defined. Below are both components
//TabComponent
<template>
<div>
<div class="row">
<div class="col-lg-12 col-xl-12">
<div class="card-box">
<ul class="nav nav-tabs nav-bordered">
<li v-for="tab in tabs" :key="tab" class="nav-item">
{{tab}}
</li>
</ul>
<div class="tab-content">
<component :is="selectedComponent"></component>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TabComponent',
props: [ selectedComponent, tabs ] //The error is coming from this line
}
</script>
I have imported it to this component and currently it shows the error
Uncaught ReferenceError: selectedComponent is not defined
//Entitlements component
<template>
<div>
<tab-component :tabs="tabs" :selectedComponent="selectedComponent" />
</div>
</template>
<script>
import TabComponent from "../../../components/TabComponent";
import List from "./Entitlements/List";
import MyEntitlements from "./Entitlements/MyEntitlements";
export default {
name: 'Entitlements',
components: {List, MyEntitlements, TabComponent},
data(){
return{
tabs: ['List', 'MyEntitlements'],
selectedComponent: 'List',
}
}
}
</script>
HTML attribute names are case-insensitive, so browsers will interpret
any uppercase characters as lowercase. That means when you’re using
in-DOM templates, camelCased prop names need to use their kebab-cased
(hyphen-delimited) equivalents (source)
Try with:
<tab-component :tabs="tabs" :selected-component="selectedComponent" />
Edit:
If you define props as an array, change the list with strings (see "Prop types" here):
props: [ 'selectedComponent', 'tabs' ]

vue-router: How to use view-router in more than one element?

A very simple example for using a vue-router in template is the following code:
<template>
<div id="app">
<router-view/>
</div>
</template>
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
what I understand is that the content of router-view will be switched by the relevant component to the path.
However, if I have a template with more than one element affected by router. For example,
<template>
<div id="app">
<h1> header </h1>
<router-view 1/>
<h1> Inner </h1>
<router-view 2/>
<h1> Footer </h1>
</div>
</template>
and let's say that router-view 1 and router-view 2 both can get different components based on the path.
In this case, how would you recommend me to use router?
Based on official doc, you have to use named-views.
Like that, you can have multiple router-view rendering differents components for the same path.
With your example, it becomes :
<template>
<div id="app">
<h1> header </h1>
<router-view /> // this will be the default
<h1> Inner </h1>
<router-view name="inner"/>
<h1> Footer </h1>
</div>
</template>
and your router will look like :
// Don't forget your imports
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: HeaderComponent, // Will render in default router-view
inner: InnerComponent // Will render in router-view named "inner"
}
}
]
})
More complex layouts are also describes in the official doc.

Why is my router-link tag not working with my bootstrap framework?

I am using vue.js to create a navigation task bar along with bootstrap for the frontend framework.
I configured the router in a router.js file I created.
router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//enter code here`import components
import levi from './containers/levi'
import product from './containers/product'
import price from './containers/price'
//application routes
const routes = [
{path: '/', component: levi },
{path: '/product', component: product },
{path:'/price', component: price }
]
//export router instance
export default new Router({
mode: 'history',
routes,
linkActiveClass:'is-active'
})
I created the containers with the files for the navigation bar.
price.vue
<template>
<div id = "price" >
What is the price!
</div>
</template>
<script>
export default{
name: 'price'
}
</script>
<style scoped>
</style>
product.vue
<template>
<div id = "product">
Understanding the levi product
</div>
</template>
<script>
export default {
name: 'product'
}
</script>
<style scoped>
</style>
The components folder has the navigation component
<template>
<div>
<div class="navbar navbar-default navbar-static-top">
<div class="container ">
levi
<button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse" name="button">
<span class="navbar-toggle-Menu">Menu</span>
</button>
<div class="collapse navbar-collapse"></div>
</div>
</div>
</div>
</template>
This div section contains the router-link tags that are not working properly
<div class="nav navbar-nav navbar-right">
<router-link to='/product'> product </router-link>
</div>
end tag for the router-link
<template></template>
<script>
export default {
name : 'navigation'
}
</script>
<style scoped = "true">
</style>
All the initial navigation links are no longer showing when I surround them with the router-link. How can I fix this?
You need to pass the instance of your router to your main Vue instance like so:
//your router is declared as default in its own file so
//in your main Vue instance...
import router from './my_router'
new Vue({
el: '#app',
router
})