我正在使用Vue v2
我试图仅更改所选元素的属性。请注意,在点击后标记响应时,应将其更改为红色,并显示“Unmark'”文本。反之亦然:如果再次点击按钮(现在会说“Unmark'”),它应该变为绿色,文字将是“标记”。唉,它有效....但是,我的代码将更改应用于v-for中的每个元素;我只希望发生在所选元素上。
我已经考虑过使用Component来检查某些事情是否发生了变化,但首先我想知道是否有解决方案。我们将非常感谢您的帮助
这是我的代码:
<div class="search-results">
<div class="activity-box-w" v-for="user in users">
<div class="box">
<div class="avatar" :style="{ 'background-image': 'url(' + user.customer.profile_picture + ')' }">
</div>
<div class="info">
<div class="role">
@{{ '@' + user.username }}
</div>
<div>
<div>
<p class="title">@{{ user.customer.name }}
@{{user.customer.lastname}}
</p>
</div>
</div>
</div>
<div class="time">
<input type="button" class="btn btn-sm btn-primary" v-on:click.prevent="markUser(user)" v-model="text"
v-bind:class="[{'green-border':notMarked}, {'red-border':marked}]" v-cloak v-if="!action"
:disabled="action"></input>
</div>
</div>
</div>
现在为剧本:
new Vue({
el: '#engage-panel',
data: {
users: [],
mark: {'id' : '', 'marks' : ''},
text: 'Mark', //Migth change to Unmark later on
action: false,
marked: null,
notMarked: null,
},
methods:
{
markUser: function(user){
this.mark.id = user.id;
this.action= true;
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name="csrf-token"]').attr('content');
this.$http.put('/mark/user', this.mark).then(response => {
if(response.body === "marked")
{
this.mark.marks="true";
this.text = 'Unmark';
this.marked= true;
this.notMarked= false;
this.action= false;
}else{
this.mark.marks="false";
this.text = 'Mark';
this.marked= false;
this.notMarked= true;
this.action= false;
}
}).catch(e => {
this.action= false;
});
}
}
答案 0 :(得分:1)
您遇到的问题my code applies the change to every element
是由v-for="user in users"
中的每个用户使用一个相同的对象来指示它是否已标记。
如果您的users
数据有一个属性状态以保存当前状态(例如取消标记,标记等),则非常简单,只需点击标记按钮即可切换到下一个状态。
如果您的users
数据没有该属性,则需要创建一个字典,然后将已点击的用户保存为密钥,用户的状态将为该值。
以下是一个演示:
app = new Vue({
el: "#app",
data: {
users1: [{'name':'abc', 'status':'none'},
{'name':'xyz', 'status':'none'}],
users2: [{'name':'abc'}, {'name':'xyz'}],
selectedUsers: {}
},
methods: {
getNextStatusBaseOnRoute: function (status) {
if(status ==='marked') return 'marked'
let routes = {'none':'unmark', 'unmark':'marked'}
return routes[status]
},
markUser1: function (item) {
item.status = this.getNextStatusBaseOnRoute(item.status)
},
markUser2: function (item) {
let status = item.name in this.selectedUsers ? this.selectedUsers[item.name] : 'none'
// remember to use vue.$set when adding new property to one object
this.$set(this.selectedUsers, item.name, this.getNextStatusBaseOnRoute(status))
}
}
})
&#13;
.marked {
background-color:green;
}
.unmark {
background-color:yellow;
}
&#13;
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
<h2>Case 1: </h2>
<div v-for="(item, index1) in users1" :key="'1'+index1">
<span>{{item.name}}:</span><span :class="[item.status]">{{item.status}}</span><button @click="markUser1(item)">Mark</button>
</div>
<h2>Case 2: </h2>
<div v-for="(item, index2) in users2" :key="'2'+index2">
<span>{{item.name}}:</span><span :class="[item.name in selectedUsers ? selectedUsers[item.name] : 'none']">{{item.name in selectedUsers ? selectedUsers[item.name] : 'none'}}</span><button @click="markUser2(item)">Mark</button>
</div>
</div>
&#13;
答案 1 :(得分:1)
如果您只需要切换css类,可以在点击时使用$event.target
。
fiddle here
但是,如果用户具有类似marked = true/false
的状态,则更容易,例如,您只需要绑定类:
<input :class="{ 'green-border': user.marked, 'red-border': !user.marked }">
答案 2 :(得分:0)
对于Vue3,还可以存储被选元素的索引
<ul role="list" class="">
<li class="relative" v-for="(image, index) of images" :class="selectedImage == index? 'border-indigo-500 border-2': 'border-transparent'" >
<div @click="selectedImage = index" class="">
<img :src="image" alt="" class="object-cover pointer-events-none group-hover:opacity-75">
</div>
</li>
</ul>