How to bind a variable prop to a v-for slot - javascript

I'm trying to have a list component, which renders a list of router-links with a scoped slot for each of the router-link. The to-prop of the router-link should be configurable by the parent.
The parent component should be able to configure the to-prop of the router link, without having to implement the router-link itself. Or if it has to implement the router-link itself, the list component should be able to pass classes to every router-link.
I've created a codepen showing the problem that I want to solve. Of course if you have any questions about it or if anything's unclear let me know.
https://codepen.io/Buffalom/pen/KKPmJPx
This is a summary of what I'm trying to achieve:
<router-link v-for="item in items" to="/" class="abc">
<!-- :to should be configurable by the parent -->
<slot :item="item"></slot>
</router-link>
I expect the parent to be able to render a list with a given array of items but configure each router-links to-prop itself.
Update
The ideal way I'd like to take would be something like this in the parent component:
<List :items="items" :to="`/1/${item.name}`">
...
As the item in the to-prop each item in items would be used on the v-for router-link in the list component itself. Kind of like a reverse scoped-slot...^^

Is this what you're looking for? You just need to make to a dynamic prop.
<router-link v-for="item in items" :to="item.url" class="abc">
<!-- :to should be configurable by the parent -->
<slot :item="item"></slot>
</router-link>
Update
If you don't have the url, look into vue-router named routes. Taken from the doc and adapted lightly:
const router = new VueRouter({
routes: [
{
path: '/1/:itemName',
name: 'item',
component: MyItemPage
}
]
})
<router-link
v-for="item in items"
:to="{ name: 'item', params: { itemName: item.name }}"
class="abc"
>
<slot :item="item"></slot>
</router-link>

Related

Nested pages in Nuxt 3

I have structute like
/pages/
section/
index.vue
out[id].vue
index.vue has side menu with ids. How to render out[id].vue inside index ?
Like Nuxt nested pages but in Nuxt3.
Can I nest not child page?
It is possible to display nested routes with <NuxtPage>.
source
More about <NuxtPage>: https://nuxt.com/docs/api/components/nuxt-page#nuxtpage
Works with
/pages/
section.vue
section/
index.vue
out[id].vue
In section.vue wrap in layout.
<template>
<div>
<NuxtLayout>
<NuxtLink to="section/">index</NuxtLink>
<NuxtLink to="section/out1">out1</NuxtLink>
<NuxtLink to="section/out2">out2</NuxtLink>
<NuxtPage />
</NuxtLayout>
</div>
</template>

Adding #click events dynamically inside v-for loop

I have an array passed as a prop to fill in a v-for loop for a v-menu in vuetify. The menu items need to have #click events assigned and the names of the functions are passed in the array as a string (one example is the "CanResolve" event which you see in the parent component) and then inserted into the v-on:click="item.clickFunctions" for each menu button. I am currently storing the functions in the child component and it is not working but ultimately I would like to store the functions in the parent component and have the #click events call those if possible. The one example is the myButtonEventHandler method stored in the parent component which is suppose to be triggered by the CanResolve event in the child theme. For some reason this event is not even being triggered when dynamically created like this in the v-for and #click.
Child component which has the following menu which needs click events filled from array passed as prop
<v-menu bottom
right>
<template v-slot:activator="{ on, attrs }">
<v-btn light
icon
v-bind="attrs"
v-on="on">
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</template>
<v-list>
<template v-for="(item,index) in menus">
<v-list-item v-if="item.isActive" :key="index" link>
<v-list-item-title #click="$emit(item.clickFunction)">{{item.title}}</v-list-item-title>
</v-list-item>
</template>
<v-list-item :href="docxLocation(filedir)" download link>
<v-list-item-title>Download</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
Component implemented in parent component:
<embeddedPDF #CanResolve ="myButtonEventHandler" v-bind:filedir="pdfLocation(item.Draft_Path)" v-bind:canvasid="'draft-canvas-'+item.Round" :menus="menuItemsArray[item.Round-1].menus"></embeddedPDF>
You need to add emit event in the child component and pass whatever you want to send to the parent as the second param.
Then in the parent component, you receive that even and assign to a function.
Child component
`
<div v-for="{ item, idx } in items" :key="item.id">
<button #click="$emit('handleItemClick', idx)">{{ item }}</button>
</div>
`
parent component template
<div>
<ChildComponent #handleItemClick="handleChildItemClick" />
</div>
parent component methods
methods: {
handleChildItemClick(idx) {
console.log(idx);
},
},

How to pass href parameter from parent vue component to child component?

Good evening!
I'm trying to create a page in Vue, parsing it into components, and rendering content using json. And it seems to be nothing complicated, but there is a problem.
But why is the href parameter in the wrong place? Please tell me, I have been unable to solve this riddle for several hours.
index.vue
<template>
<section>
<Hero
v-for="(hero, index) in heroes"
:title="hero.title"
:description="hero.description"
:more="hero.more"
:href="hero.href"
:key="index"
/>
</section>
</template>
Hero.vue
<template>
<div>
<h2>{{ title }}</h2>
<p>{{ description }}</p>
<a :href="href">{{ more }}</a>
</div>
</template>
<script>
Result
<section>
<div href="/create">
<h2>Create and share your photo stories.</h2>
<p>
Photosnap is a platform for photographers and visual storytellers. We make
it easy to share photos, tell stories and connect with others.
</p>
<a>Get an Invite </a>
</div>
...
</section>
You probably forgot to define href as a prop in your Hero component.
Make sure you have added href as prop in your Hero component.
props: {
href: {
type: String,
required: true
}
}

Remove component from template for certain pages in Vue2

I'm working on a Vue2 app.
It consists of a base template (App.vue) that looks like this:
<template>
<v-app>
<div id="app">
<NavigationBar></NavigationBar>
...
</div>
</v-app>
</template>
And various components (i.e., Home.vue, Login.vue, Navigation.vue etc...)
Being part of the main template, the NavigationBar is displayed in each component.
I would love to remove the NavigationBar only in the Login.vue component.
What could be the best way to achieve this?
Thanks

In VueJS, how do I use load in a view based on what is populated in my JS?

I am new to Vue.JS and require a little help as I am stuck with some logic.
I have been given a project to building and as I am under NDA I can only show comparative code examples.
In one View (Bars), which is brought into the viewport of the application using the router, I have a simple for loop.
<ul class="bar-listings">
<li v-for="bar in bars">
<router-link to="{bar.barPage}">
<div class="item">
<div class="item-bd">
<h2>{{ bar.barName }}</h2>
</div>
</div>
</router-link>
</li>
</ul>
Then in my JS file conatining all my data, I have this (Only one object for now)
export default [
{
barName: "The Tropicana Bar",
barPage: "views/bars/Tropicana",
}
];
The title displays correctly on Bars so the loop is pulling the data correctly.
However, I will have a .vue file for each bar, which also uses the data from my JS file. See below:
<template>
<div class="content-wrapper">
<h1>{{ getBarByIndex({ bars, index }).barName }}</h1>
</div>
</template>
<script>
import bars from "./../../data/bars";
export default {
data() {
return {
bars: bars
};
},
methods: {
getBarByIndex({ bars = [], index = 0 }) {
return bars[index] || {}
}
}
};
</script>
So what I need to solve is how do I make the <a v-bind:href=""> load the view for this bar?
What I think you can do, is to have a child component inside your component, you can leverage this by using nested routes in your router-view, additionally, you can pass props as an object to your router components, parent or child, whatever you need.
Basically, you will have a main router view, but inside your component, you will have another router-view which renders child components.
See: Nested Routes
See: Passing Props to Route components

Categories