Vue JS - применить определенные классы к элементам в v-for l oop в соответствии с данными из предыдущих элементов в цикле - PullRequest
0 голосов
/ 04 марта 2020

Извините за длинный заголовок, у меня такое ощущение, что это странно конкретный c крайний случай, с которым не приходится сталкиваться многим людям.

Какой-то фон, я работаю над веб-приложением для отслеживания P C ремонт нашего магазина. В настоящее время у нас есть один, который мы приобрели и имеем доступ к исходному коду благодаря авторскому методу распространения. Каждый ремонт обозначается рабочим заказом, каждый из которых имеет примечания. В старом приложении заметки содержат имя пользователя, дату его публикации, а также кнопки редактирования и удаления (если вы являетесь администратором или автором) слева и заметку справа. Если пользователь, разместивший заметку, изменяется при переходе по списку, он меняет их местами, поэтому заметка находится слева, а пользователь справа, т. Е.

user1 - note text
note text - user2
user3 - note text
user3 - note text
note text - user1

Старое приложение делало это с обычным PHP, в файле php, заполненном до краев утверждениями эха. Новое приложение, над которым я работал, имеет laravel бэкэнд (для использования таких вещей, как Eloquent) с Vue JS веб-интерфейсом (для помощи с живыми обновлениями в веб-сокетах). Таким образом, на странице «Рабочее задание» есть компонент для списка заметок, который берет список заметок, назначенных этому рабочему заданию, в качестве реквизита и перебирает все заметки с помощью v-for. Я хотел имитировать c функцию переключения ориентации из предыдущей настройки. Я могу добиться переключения, настроив каждую заметку в качестве контейнера сетки и применив к первому или последнему порядку столбец, содержащий информацию о пользователе. То, с чем я борюсь, - это попытка найти способ переключения, какой класс применяется при изменении пользователя.

Сначала у меня был атрибут данных, отслеживающий текущий класс, поэтому, когда пользователь изменился, я мог проверить, что это за класс, и переключить его на противоположный. Однако это вызвало бесконечный рендер l oop, так как весь список заметок будет рендериться каждый раз при изменении этого атрибута. Он выполнил sh то, что я хотел сделать визуально, но это вызвало серьезные проблемы с производительностью. Затем я попытался использовать refs, поэтому, когда пользователь изменился, я мог получить предыдущую запись в списке из массива refs и проверить его классы, чтобы увидеть, в каком классе порядка он должен был соответствующим образом установить класс заказа для следующих элементов. Однако это не сработало, потому что массив refs не будет заполняться до тех пор, пока не будет закончен рендеринг списка, и мне нужно было установить класс в том виде, в котором он рендерился. Я попытался использовать вычисляемое свойство, но оно не может принимать аргументы (т. Е. Индекс массива, в котором я находился в данный момент, для сравнения с index-1), и даже если бы он мог, я не смог найти способ проверить текущее кэшированное значение этого свойства при расчете нового.

Вот код, с которым я работаю для справки, в настоящее время с любым из предыдущих подходов, которые я пытался удалить, поэтому в настоящее время переключение пользователей не происходит.

 <template>
    <ul class="list-unstyled">
        <li class="row no-gutters mb-2" v-bind:key="index" v-for="(note, index) in this.notes">
            <note-form-modal :modal-id="'note'+note.noteid+'editModal'" :populate-with="note"></note-form-modal>
            <div class="col-md-1 d-flex flex-column mx-md-3">
                <div class="text-center p-0 m-0">{{note.noteuser}}</div>
                <div class="text-muted text-small text-center p-0 m-0">{{getHRDate(note.notetime)}}</div>
                <div class="btn-group justify-content-center p-0 m-0">
                    <template v-if="authusername === note.noteuser || authusername === 'admin'">
                        <button class="btn btn-sm btn-primary m-1" data-toggle="modal" :data-target="'#note'+note.noteid+'editModal'"><i class="fas fa-fw fa-edit"></i></button>
                        <button class="btn btn-sm btn-danger m-1"><i class="fas fa-fw fa-trash-alt"></i></button>
                    </template>
                </div>
            </div>
            <div class="col-md-10">
                <div class="card m-2">
                    <div class="card-body p-2">
                        {{ note.thenote }}
                    </div>
                </div>
            </div>
        </li>
    </ul>
</template>
<script>
import dateMixin from '../mixins/dateMixin'
export default {
    mixins:[dateMixin],
    props: ['initialnotes', 'authusername', 'noteType', 'woid'],
    data () {
        return {
            notes: Object.values(this.initialnotes),
            currentOrder: 'order-first',
            newNote: {
                notetype: this.noteType,
                thenote: '',
                noteuser: this.authusername,
                woid: this.woid
            }
        }
    },
    mounted () {
        Echo.channel('wonotes.'+this.noteType+'.'+this.woid)
            .listen('WorkOrderNoteAdded', (e) => {
                this.notes.push(e.note)
            })
            .listen('WorkOrderNoteEdited', (e) => {
                let index = this.notes.findIndex((note) => {
                    return note.noteid === e.note.noteid
                })
                this.notes[index] = e.note
            })
            .listen('WorkOrderNoteDeleted', (e) => {
                let index = this.notes.findIndex((note) => {
                    return note.noteid === e.noteid
                })
                this.notes.splice(index, 1)
            })
    },
    methods: {
        createNote () {
            axios.post('/api/workorders/notes', this.newNote)
                    .then((response) => {
                        $('#note'+this.noteType+'add').collapse('hide')
                        this.newNote.thenote = ''
                    })
        }
    }
}
</script>

noteType существует, потому что у нас есть два разных типа заметок: одну, которую видит клиент, и ту, которую видят только технические специалисты.

Есть ли что-то очевидное, что я упускаю, я только что спроектировал это что-то не так, я пытаюсь сделать что-то невозможное? Любая помощь будет принята с благодарностью, я здесь, в конце этой веревки.

1 Ответ

0 голосов
/ 04 марта 2020

В итоге я нашел решение этой проблемы, но не уверен, что он лучший, но здесь все идет.

В основном я поддерживаю массив, параллельный массиву notes, который определяет, какой класс order- классифицирует каждый массив Индекс должен иметь. Поскольку он зависит от атрибута notes, я делаю его вычисляемым свойством, чтобы я мог использовать атрибут notes и он автоматически обновляется при изменении списка заметок. Файл теперь выглядит следующим образом (с некоторыми кодами, относящимися к публикации новых заметок и удалению редактируемых заметок, для ясности)

<template>
    <ul class="list-unstyled">
        <li class="row no-gutters mb-2" v-bind:key="index" v-for="(note, index) in this.notes">
            <div class="col-md-1 d-flex flex-column mx-md-3" :class="noteOrders[index]">
                <div class="text-center p-0 m-0">{{note.noteuser}}</div>
            </div>
            <div class="col-md-10">
                <div class="card m-2">
                    <div class="card-body p-2">
                        {{ note.thenote }}
                    </div>
                </div>
            </div>
        </li>
    </ul>
</template>
<script>
export default {
    props: ['initialnotes'],
    data () {
        return {
            notes: this.initialnotes,
        }
    },
    computed: {
        noteOrders () {
            return this.getNoteOrders(this.notes)
        }
    },
    methods: {
        getNoteOrders(notes) {
            let noteOrders = []
            notes.forEach((note,index) =>{
                if (index === 0) {
                    noteOrders[index] = 'order-first'
                } else if (note.noteuser !== notes[index-1].noteuser) {
                    if (noteOrders[index-1] === 'order-first') {
                        noteOrders[index] = 'order-last'
                    } else {
                        noteOrders[index] = 'order-first'
                    }
                } else {
                    noteOrders[index] = noteOrders[index-1]
                }
            })
            return noteOrders
        }
    }
}
</script>

Возможно, найдутся лучшие решения, и я призываю всех, кто с этим сталкивается, публиковать свои если они есть, но, поскольку я нашел решение, которое работает для меня, я решил опубликовать его для всех, кто столкнулся с той же проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...