VueJS Выберите только один элемент в v-for - PullRequest
0 голосов
/ 03 мая 2018

Я использую Vue v2

Я пытаюсь изменить только свойства выбранного элемента. Смотрите, когда ответ отмечен после щелчка, он должен измениться на красный цвет с текстом «Снять отметку». И наоборот: если кнопка будет нажата снова (которая теперь будет означать «Снять отметку»), она должна изменить цвет на зеленый, а текст будет «Отметить». Увы, это работает .... Тем не менее, мой код применяет изменения к каждому элементу внутри v-for; Я только хочу, чтобы это случилось с выбранным элементом.

Я думал об использовании Компонента, чтобы проверить, что что-то меняется, но сначала я хотел бы посмотреть, есть ли решения для этого. Любая помощь будет оценена

Вот мой код:

<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;
                });
    }

}

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Вы можете использовать $event.target при нажатии, если вам просто нужно переключить класс CSS. скрипка здесь

Но это правда, что проще, если пользователь имеет статус, например marked = true/false, вам просто нужно привязать класс, например:

<input :class="{ 'green-border': user.marked, 'red-border': !user.marked }">
0 голосов
/ 03 мая 2018

Проблема my code applies the change to every element, с которой вы столкнулись, вызвана тем, что каждый пользователь в v-for="user in users" использует один и тот же объект, чтобы указать, отмечен он или нет.

Если ваши users данные имеют одно свойство, например статус, для сохранения текущего статуса (например, отменить отметку, пометить и т. Д.), Это очень просто, просто перейдите к следующему состоянию, когда нажмите кнопку mark .

Если ваши 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))
    }
  }
})
.marked {
  background-color:green;
}

.unmark {
  background-color:yellow;
}
<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...