使用Vue JS从阵列为每张卡创建带模态的卡片

问题描述 投票:0回答:2

我使用v-for成功创建了6个来自阵列的卡。问题是我也在尝试为每张卡片创建一个Modal,其中包含每张卡片的唯一卡片细节。例如:Modal中卡片的标题,链接,作者,img,类别

我能够生成模态但它显示所有卡的第一张卡的详细信息。

如果你看小提琴,你可以看到这一点。

如何使用自己的卡详细信息为每张卡生成模态?

我正在使用bootstrap 4

class Project {
    constructor(title, link, author, img, category) {
        this.title = title,
        this.link = link,
        this.author = author, 
        this.img = img,
        this.category = category
    }
}

new Vue({
	el: '#app',
	data: {
        currentFilter: 'ALL',
        projectList: [
            new Project (
                'Ecommerce', 
                '#', 
                'Dessert Tools za', 
                'https://placeimg.com/460/180/any',
                'DESIGN'
          ),
            new Project (
                'BITC Management', 
                'https://digitalassetmanagement.com/', 
                'Widen',
                'https://placeimg.com/420/180/any',
                'DESIGN'
            ),
            new Project (
                'Landing Page', 
                'https://meet-a-geek.today/', 
                'Contenforces', 
                'https://placeimg.com/430/180/any',
                'DEVELOPMENT'
            ),
            new Project (
                'Online Training', 
                'https://www.smarttraining.com/', 
                'Smart Training LCC',
                'https://placeimg.com/440/180/any',
                'DEVELOPMENT'
            ),
            new Project (
                'Univesity & Jobsite Portal', 
                'https://micencostagebank.nl/index_september.php', 
                'Contenforces', 
                'https://placeimg.com/470/180/any',
                'COLABORATION'
            ),
            
            new Project (
                'Product Funnel', 
                'http://prettyexcellent.com/applecider/', 
                'A. A. Ron',
                'https://placeimg.com/480/180/any',
                'DEVELOPMENT'
            )
        ], 
    },

	methods: {
		setFilter: function setFilter(filter) {
			this.currentFilter = filter;
        } 
    }
    
});
.section-subnav {
/* margin: $margin-xl 0; */


} 

.title {
text-align: center;       
/* font-size: $font-lg; */
font-weight:normal;
/* padding: $margin-sm 0; */
}

.submenu {
text-align: center;
/* font-size: $font-sm; */
/* margin-bottom: $margin-md; */

}

.filter {    
padding: 6px 6px;
cursor: pointer;
border-radius: 6px;
transition: all 0.35s;
}

.filter.active {
box-shadow:0px 1px 3px 0px #00000026;
}
.filter:hover {
background:lightgray;
}     

.projects {
display: flex;
flex-wrap: wrap;    
justify-content: center;
}

p {
text-align: center;
/* font-size: $font-sm; */      
}

a {
/* font-size: $font-sm; */
color: #fff;
}

.projects-leave-to{
transform: translatey(30px);
opacity:0;
}

.project {
transition: all .35s ease-in-out;
margin: 0 10px;
width: 250px;
height: auto;
transition: all .35s ease-in-out;	   
}

.project-image {
max-width: 100%;
height: auto;
}

.project-description {
margin: 20px 10px;
text-align: center;    
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app">     


        <section class="section-subnav" id="submenu-sec">
            <h3 class="title">Projects</h3>

            <div class="filters submenu">
                <span class="filter" v-bind:class="{ active: currentFilter === 'ALL' }" v-on:click="setFilter('ALL')">ALL</span>
    
                <span class="filter" v-bind:class="{ active: currentFilter === 'DESIGN' }" v-on:click="setFilter('DESIGN')">DESIGN</span>
    
                <span class="filter" v-bind:class="{ active: currentFilter === 'DEVELOPMENT' }" v-on:click="setFilter('DEVELOPMENT')">DEVELOPMENT</span>
    
                <span class="filter" v-bind:class="{ active: currentFilter === 'COLABORATION' }" v-on:click="setFilter('COLABORATION')">COLABORATION</span>
            </div>
        
       
            <div class="container">          

                <transition-group class="projects" name="projects">               
                    
                    <div class="rounded project" v-if="currentFilter === project.category || currentFilter === 'ALL'" v-bind:key="project.title" 
                        v-for="project in projectList"> 
                        
                         <!-- Modal pop up -->
                        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true" v-for="project in projectList">
               
                            <div class="modal-dialog" role="document">
                                <div class="modal-content" >
                                        
                                    <div class="modal-header"> 
                                        <img class="project-image " v-bind:src="project.img">  
                                    </div>
                            
                                    <div class="modal-body">
                                            <p class="project-title">{{project.title}}</p>
                                        <h5 class="modal-title" id="exampleModalLongTitle">
                                         
                                        </h5>
                                    
                                    </div>
                                        
                                    <div class="modal-footer">
                                        <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
                                    </div>
                                        
                                </div> 
                            </div>
                        </div>
                                                            
                        <div class="border shadow border-ligh project-image-wrapper mb-5">
                                               
                            <img class="project-image " v-bind:src="project.img">                    
                        
                            <div class="project-description">
                                <p class="project-title">{{project.title}}</p>

                                <a :href="project.link" class="btn btn-danger" target="_blank">View Website</a>

                                <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#myModal">
                                    View Details
                                </button>
                            </div>                           
                        </div>                                           
                    </div>         
                                    
                </transition-group>                
            </div><!-- container end -->          
            
        </section> 
        
    </div>

这是一个小提琴链接Jsfiddle

javascript vue.js modal-dialog v-for
2个回答
0
投票

您需要数据中的唯一ID。您可以将其分配给模态ID

:id="'myModal'+ project.id"

否则按照答案中提到的@Lassi的说明进行操作。

我在你的小提琴中分叉并在模态ID &&按钮数据目标中传递project.title。

 <div class="modal fade" :id="'myModal-'+project.title.replace(/[\W_]+/g,'_')" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true" v-for="project in projectList">
......
<button type="button" class="btn btn-danger" data-toggle="modal" :data-target="'#myModal-'+project.title.replace(/[\W_]+/g,'_')">
                                View Details
                            </button>

小提琴:https://jsfiddle.net/3zv7jope/

下面是传递索引的例子

v-for="(project, index) in projectList" :id="'myModal-'+index"

小提琴:https://jsfiddle.net/g3u50fpz/


0
投票

首先,你有重复的v-for,所以你应该从模态元素中删除v-for。

你的模态在循环中,所以对于DOM中的每个项目都有一个隐藏的模态元素。它们都具有相同的id,即myModal。单击视图详细信息时,将显示第一个项目的第一个模式。

解决此问题的一种方法是为每个元素添加唯一的模态ID。例如,如果我们想在数组中使用项索引,我们可以添加使用以下构造id的方法。现在每个元素都有一个从myModal0到myModal5的唯一ID。当您单击查看详细信息并且Bootstrap搜索模式以打开它时,知道正确的模态是什么。

                    <div class="modal fade" :id="'myModal' + i">
                    <button type="button" :data-target="'#myModal' + i">
© www.soinside.com 2019 - 2024. All rights reserved.