Изменение цвета фона на сетке DIV в Vue.js без изменения фона другого - PullRequest
0 голосов
/ 22 июня 2019

Я могу легко изменить цвет фона элемента в Vue, используя событие @click, но у меня возникают проблемы с большой сеткой, меняющей цвет фона по порядку на основе массива / объекта состояний / цветов.

Я пытался привязать стиль и класс к объекту данных, но я изменяю сразу всю сетку вместо каждого отдельного элемента. Я использую Vue уже неделю или две, и я застрял на этом. Я буду прикреплять его к моему Laravel API, чтобы динамически выдвигать дни, и в основном буду использовать каждый элемент сетки для включения, выключения, возможно или нуля сотрудника (неизвестного или неопределенного). Также в каждом углу элементов сетки будут находиться 3 маленькие иконки (логические, вкл. / Выкл.), Чтобы добавить дополнительные параметры о том, оплачивается ли оплата, как рассчитывается и разрешены ли они OT.

<template>
    <div id="app">
        <heading class="mb-6">Scheduler</heading>
        <form>
            <div class="flex mb-4">
                <div class="bg-gray-400 w-1/3 h-12">
                    <label for="budgets">Select Budget</label><br>
                    <select class="form-control form-select mb-3 w-full" id="budgets" v-model="budgetSelect">
                        <option selected="selected" disabled>--</option>
                        <!-- start the budget select loop -->
                        <option v-for="(budget,index) in budgets" :key="index" :value="index">
                            {{ budget.name }} -- {{ budget.subject }}
                        </option>
                    </select>
                </div>
                <div class="bg-gray-400 w-1/3 h-12">
                    <label v-if="budgetSelect!=null" for="series">Select Series</label><br>
                    <select v-if="budgetSelect!=null" class="form-control form-select mb-4 w-full" v-model="seriesSelect" id="series">
                        <option selected="selected" disabled>Select a Series</option>
                        <!-- start the series select loop -->
                        <option v-for="(series,index) in seriesArray" :key="index">
                            {{ series.name }}
                        </option>
                    </select>
                </div>
                <div class="bg-gray-400 w-1/3 h-12">
                    <label v-if="seriesSelect!=null" for="events">Select Event</label><br>
                    <select v-if="seriesSelect!=null" class="form-control form-select mb-3 w-full" v-model="eventSelect" id="events">
                        <option selected="selected" disabled>Select an Event</option>
                        <!-- start the event select loop -->
                        <option v-for="(event,index) in events" :key="index">
                            {{ event.name }}
                        </option>
                    </select>
                </div>
            </div>
        </form>
        <div v-if="eventSelect!=null" class="p-4 flex">
            <h1 class="text-2x1">
                Week of June 16th, 2019
            </h1>
        </div>
        <!-- to conditionally hide this grid -->
        <!--  v-if="eventSelect!=null" -->
        <div class="flex justify-center">
            <div class="square-header">
                <div class="square-header-content"></div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Sunday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Monday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Tuesday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Wednesday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Thursday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Friday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Saturday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Sunday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Monday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Tuesday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Wednesday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Thursday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Friday</div>
            </div>
            <div class="square-header">
                <div class="square-header-content">Saturday</div>
            </div>
        </div>

<!-- start the rows -->
<!-- start the rows -->
<!-- start the rows -->

        <div v-for="index in 7" :key="index" class="flex justify-center">
            <div class="square">
                <div class="square-content" style="vertical-align:middle;">User </div>
            </div>
            <div v-for="index in 14" :key="index" 
                @click="changeDayState(dayCode,state,index)"
                class="square bg-danger">
                    <div class="square-content"></div>
            </div>
        </div>
    </div>

</template>
<script>
export default {
    data(){
        return {
            // main vars
            startDay: 'Sunday',
            weekSpan: 2,
            dayCode: [
                {key: 'on', value: '#21b978'},
                {key: 'off', value: '#e74444'},
                {key: 'maybe', value: '#ffeb3b'},
                {key: 'empty', value: 'var(--white-50)'}
            ],
            state: 'on',
            bgColor: {
                backgroundColor: ''
            },


            // attribute icon paramaters
            icons: {
                straightTime: {
                    placement: '',
                    url: ''
                },
                overTime: {
                    placement: '',
                    url: ''
                },
                billable: {
                    placement: '',
                    url: ''
                }
            },

            // begin budget drop down
            budgetSelect: null,
            budget: {
                id: "",
                name: "",
                subject: "",
            },
            budgets: [],

            // begin series drop down
            seriesSelect: null,
            series: {
                name:"",
            },
            seriesArray: [],

            // begin event drop down
            eventSelect: null,
            event: {
                name: "",
            },
            events: [],

            // begin day drop down
            daySelect: null,
            day: {
                scheduled_date: "",
                user:"",
            },
            days: [],

            uri: window.location.origin + '/clock-in',
            budgetURI: window.location.origin + '/api/scheduler',
            seriesURI: window.location.origin + '/api/scheduler/series/1',
            eventURI: window.location.origin + '/api/scheduler/events/1',
            dayURI: window.location.origin + '/api/scheduler/days/1',
        }
    },
    methods: {
        getBudgets(){
            axios.get(this.budgetURI).then(response=>{
                this.budgets = response.data.budgets;
                console.log(response.data.budgets);
            });
        },
        getSeries(){
            axios.get(this.seriesURI).then(response=>{
                this.seriesArray = response.data.series;
                console.log(response.data.series);
            });
        },
        getEvents(){
            axios.get(this.eventURI).then(response=>{
                this.events = response.data.events;
                console.log(response.data.events);
            });
        },
        getDays(){
            axios.get(this.dayURI).then(response=>{
                this.days = response.data.days;
                console.log(response.data.days);
            });
        },
    changeDayState(dayCode,key,index){
        for (var i = 0; i < dayCode.length; i++){
            if (dayCode[i].key === key){
            console.log(dayCode[i].key + " -- " + dayCode[i].value);
            this.state = dayCode[i + 1].key;
            this.bgColor.backgroundColor = dayCode[i + 1].value;
            return null;
            }else{
                this.state = "else";
            }
       }
    }

    },
    mounted(){
        this.getBudgets();
        this.getSeries();
        this.getEvents();
        this.getDays();
    }
}

</script>
<style>
.square-header {
    float: left;
    position: relative;
    width: 6%;
    height: 1.2em;
    margin: .15%;
    overflow: hidden;
    border-radius: 10px;
}
.square-header-content {
    position: absolute;
    height: 90%;
    width: 90%;
    padding: 5% 5%;
    text-align: center;
    bottom: 0;
    font-size: .8rem;
}

.square {
    float: left;
    position: relative;
    width: 6%;
    padding-bottom: 6%;
    margin: .15%;
    overflow: hidden;
    border-radius: 10px;
}
.square-content {
    position: absolute;
    height: 70%;
    width: 90%;
    padding: 15% 5%;
    text-align: right;
    bottom: 1px;
    font-size: .8rem;
    vertical-align: middle;
}
</style>

Особое внимание уделяется циклу, в котором комментарии кода говорят о начале строк. Я дал стиль, чтобы помочь с визуализацией сетки. Функция, в которой я пытаюсь это осуществить - это changeDayState (). Я должен быть в состоянии отслеживать каждый день и переключаться между 4 состояниями и фоновыми цветами для каждого деления.

1 Ответ

0 голосов
/ 25 июня 2019

Это было решено путем передачи текущего элемента с использованием $ event в метод, а затем манипулирования им в методе. Смотри ниже ...

            <div v-for="parent_index in 7" :key="parent_index" class="flex justify-center">
                <div class="square">
                    <div class="square-content" style="vertical-align:middle;">User {{ parent_index }}</div>
                </div>
                <div v-for="index in 14" :key="index" class="square bg-success"
                    @click="changeDayState(dayCode,$event)">
                </div>
            </div>
        changeDayState: function (dayCode,$event){
            for (var i = 0; i < dayCode.length; i++){
                if($event.currentTarget.classList.contains(dayCode[i].value)){
                    console.log('tracking ' + dayCode[i].value + ' and now next is ' + dayCode[i+1].value);
                    $event.target.classList.toggle(dayCode[i].value);
                    $event.target.classList.toggle(dayCode[i+1].value);
                    i++; // this throws the loop off after setting the correct value
                }else if($event.currentTarget.classList.contains(dayCode[dayCode.length-1].value)){
                    console.log('we reached the end and are looking at ' + dayCode[i].value);
                    $event.target.classList.toggle(dayCode[i].value);
                    $event.target.classList.toggle(dayCode[dayCode.length-1].value);
                }
            }
        }
...