B
B
bituke2022-04-07 20:43:59
Vue.js
bituke, 2022-04-07 20:43:59

How to change the class of a specific object from an array?

There is an array with data that is output by the v-for loop

<div class="article" v-for="article, key in articles.slice(0, count)">
      <img :src="article.article_image">
      <h3>{{ article.title }} {{ key }} </h3>
      <p>{{ article.text }}</p>
      <p>{{ get_date(article.create_date) }}</p>
      <p>
      {{ article.like_users }}
      <svg @click='like(article.id, "like"), article.like_users+=1' title='оценить' xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
        <path d="..."/>
      </svg>
      </p>
    </div>


The task is to change the class, and maybe another attribute of one of the tags of this object when clicking on it.
Do I understand correctly that when clicking, it will be necessary to call a function into which we will pass the key of the object, then somehow get this object from the doom tree through js and already manipulate it as we please? Or is it much easier with vue? Please give the docks if there is, I searched a lot, I did not find anything satisfying.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander, 2022-04-08
@bituke

Do I understand correctly that when clicking, it will be necessary to call a function into which we will pass the key of the object, then somehow get this object from the doom tree through js and already manipulate it as we please?

Not! Why is everyone trying so hard to store things in the DOM?
DOM is about display, not about storage. The DOM needs to represent the state in some way, not the state of the DOM.
And this is wrong too:
<div class="article" v-for="article, key in articles.slice(0, count)">

If the information about the click should not live long (as long as the component is alive or the props have not changed), then you can do something like this:
<template>
  <div class="article"
    v-for="(article, key) in articlesToRender"
    :key="key"
 
    :class="{ clicked: article.clicked }"
    @click="setClicked(key)"
  >
    ...  
  </div>
</template>

<script>
  import copy from '@utils/copy-object.js'; // Функция, которая "глубоко" копирует объекты.

  export default {
    name: 'ComponentName',
    props: {
      articles: {
        type: Array,
        required: true
      },
      count: {
        type: Number,
        required: true
      }
    },
    data: () => ({
      modifedArticles: []
    }),
    watch: {
      articles(n) {
        this.modifedArticles = n.map(a => ({...copy(a), clicked: false}));
      }
    },
    computed: {
      articlesToRender(){
        return this.modifedArticles.slice(0, this.count)
      }
    },
    setClicked(id) {
      this.modifedArticles[id].clicked = true;
    }
  }
</script>

<style scoped>
  .article { /* Обычные стили */ }
  .article.clicked { /* Стили после клика*/ }
</style>

S
Sergey Sokolov, 2022-04-07
@sergiks

one option is to make this markup inside a standalone component. In which the object of the article is passed through props. The component independently processes a click on it and changes the class somewhere inside itself.
another option is to keep the sign of the article “clickable” (by default, false) in the artice object as well. And when drawing, take into account its value. By clicking with the index, change the sign in the source data to true (the markup will be redrawn).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question