New to Vue, and I want to loop through each category and then display posts.
<section v-for="(category) in (categoryList)">
<h2>{{category.title}}</h2>
<div v-for="(post) in (sortedActivity, filteredList)">
{{post.title}}
</div>
</section>
Something like the above.
The sortedActivity function is a simple sort and filteredList function is a search.
But how do I parse {{category.title}} to those functions within computed? I assume I want to update the current instance state with the category title? But not sure the easiest way to do that within the loop as it will change. Or if there is another method (not literal)?
Thanks
I assume you wish to first search for a category using filteredList and then sort using sortedActivity. In that case, you can use:
<section v-for="category in categoryList">
<h2>{{ category.title }}</h2>
<div v-for="post in sortedActivity(filteredList(category.title))">
{{ post.title }}
</div>
</section>
However, in general, you should create another sub-component like the following:
<category-posts :category="category" v-for="category in categoryList">
</category-posts>
Where each category-posts would be:
<section>
<h2>{{ category.title }}</h2>
<div v-for="post in sortedActivity(filteredList(category.title))">
{{ post.title }}
</div>
</section>
This would help you keep outer and inner loop separate and avoid recomputation of inner for-loop. Also, do not forget to use key attribute.
Related
I am having this issue and I can not find my way around it without duplicating lots of code.
I have an array of entries coming from an axios request. Everything will go in an ul.
If I am doing it like this, everything is ok:
resource-index.blade.php
<ul>
<li v-for="entry in entries" :key="entry.id" >
<div>
<div>
<a :href="entry.links.show">
<x-button-icon color="gray-400">
#include('partials.svg.outline-eye')
</x-button-icon>
<span class="ml-3">{{ __('View') }}</span>
</a>
</div>
<div>
<a :href="entry.links.edit">
<x-button-icon color="gray-400">
#include('partials.svg.pencil')
</x-button-icon>
<span class="ml-3">{{ __('Edit') }}</span>
</a>
</div>
</div>
</li>
</ul>
However, in case I want to try to extract some of that stuff in different components, the details I am sending from Vue no longer get passed to the component.
resource-index.blade.php
<ul>
<li v-for="entry in entries" :key="entry.id" >
<div>
<x-grid-list-item-button label="{{ __('View') }}" :href="entry.links.show">
<x-slot name="icon">
#include('partials.svg.outline-eye')
</x-slot>
</x-grid-list-item-button>
<x-grid-list-item-button label="{{ __('Edit') }}" :href="entry.links.edit">
<x-slot name="icon">
#include('partials.svg.pencil')
</x-slot>
</x-grid-list-item-button>
</div>
</li>
</ul>
And here is the grid-list-item-button.blade.php
<div>
<a href="{{ $href }}">
#if($icon)
<x-button-icon color="gray-400">
{{ $icon }}
</x-button-icon>
#endif
<span class="ml-3">{{ $label }}</span>
</a>
</div>
I already tried:
moving the href="entry.links.show" in a named slot;
passing the data with v-bind: v-bind:href="entry.links.show";
::href="entry.links.show"
Can someone please tell what am I doing wrong or at least point me in the right direction with this?
Thanks!
If I got you right: You are trying to pass data from Vue.Js to Laravel-Components. Unfortunately this is not possible. Blade gets processed on the server-side where Vue.Js is not yet available. So the variable entry.links.show do not yet exist in Laravel (only available on client-side) and therefore cannot be passed to the Laravel-Component. After the HTML got rendered by Blade and passed to the Browser, Vue.Js can pick it up and replicate your template for the v-for and generate your list. At this point your 'link'-variables get available.
Solutions:
You could extract your code to a Vue.Js-Component rather than a Laravel-Component. This would be interpreted on client-side.
An other solution would be to generate this list through Blade so you could use Laravel-Components.
In my vue template I have:
<ul>
<li>slide a</li>
<li>slide b</li>
....
</ul>
But I want to pass in each slide from the parent using a slot, so:
<carousel>
<img src="abc.jpg">
<img src="xyz.jpg">
</carousel>
But how can I loop out what is passed in to each li? So I want to end up with:
<ul>
<li><img src="abc.jpg"></li>
<li><img src="xyz.jpg"></li>
....
</ul>
Also I want to be able to pass in any dom element via the slot to the list element.
As Michael said, you can achieve this behavior via scoped slots.
In your carousel component, the template will look like this :
<ul>
// TODO : Add a :key with a unique identifier
<li v-for="item in items">
<slot name="item" :item="item">
{{ item }}
</template>
</li>
</ul>
And when using the component, you will do something like this :
<carousel :items="images">
<img #item="{ src }" :src="src">
</carousel>
Depending on your images data, you may need to get the source from another property.
In my first example, I have in my component's template:
<div id="hello">hello world</div>
When console.log(this.$refs['hello']) is called in myMethod(), I get undefined in the console.
In my second example, I have:
<div v-for="item in data">
<div :id="'hello-'+item.id">hello {{ item.id }}</div>
</div>
When console.log(this.$refs['hello-1']) is called in myMethod(), I also get undefined in the console.
What's wrong in my code ?
You cannot get element with refs by giving that element id. You should bind ref to that element. Here is an example:
<div v-for="item in data" :key="item.id">
<div :id="'hello-'+item.id" :ref="'hello-'+item.id">hello {{ item.id }}</div>
</div>
And also don't forget to bind key to your iterating elements with v-for
How can I update the accordion-item title using a v-for loop inside F7+Vue ? I need each accordian-item title to be set to the Title of each object inside the myList array that is being looped over using the v-for.
Here is example below:
<f7-list-item v-for="value in myList" accordion-item title="{{value.Title}}">
<f7-accordion-content>
<f7-block>
<p>{{value.foo}}</p>
<p>{{value.boo}}</p>
</f7-block>
</f7-accordion-content>
</f7-list-item>
</f7-list>
Due to the time required for me to wrap my head around how I would use the current F7+Vue Accordion with a v-for to inject the title element... it seems that this is not possible. I could be wrong. I ended up resolving this by using the standard non f7+vue components...
example:
<div class="list accordion-list">
<ul>
<li class="accordion-item" v-for="value in myList">
<a href="#" class="item-link">
<div class="item-content">
<div class="item-inner">
<div class="item-title">{{value.Title}}</div>
</div>
</div>
</a>
<div class="accordion-item-content">
<div class="block">
<p>{{value.foo}}</p>
<p>{{value.boo}}</p>
</div>
</div>
</li>
</ul>
</div>
I'd like to create a custom element that loops through an array and applies the to each item in the array. For example, the view template of the custom element would contain something like:
<div repeat.for="i of items">
<div with.bind="i">
<slot></slot>
</div>
</div>
When I remove the repeat.for and with.bind attributes, the slot displays a single time. Is there a way to make it repeat for each item in the list?
No, you cannot use slots with repeat.for or bind today. To do this you have to use replaceable parts. For example:
<div repeat.for="i of items">
<div with.bind="i">
<template replaceable part="content"></template>
</div>
</div>
Usage:
<my-component>
<template replace-part="content">Some Content - ${somePropertyOfI}</template>
</my-component>
Runnable example: https://gist.run/?id=29aa1c1199f080c9ba0e72845044799b