programing

vue 루프에서 요소의 색상을 동적으로 변경

prostudy 2022. 8. 29. 21:25
반응형

vue 루프에서 요소의 색상을 동적으로 변경

그래서 저는 다음과 같은 디자인을 목표로 하고 있습니다.

특히 위에 있는 화려한 배지들.이제 이 항목들은 그룹화되어 임의의 숫자일 수 있습니다.사진에서는 2개로 그룹화되어 있습니다만, 4개 또는 5개가 됩니다.

각 그룹의 배지의 배경과 텍스트 색상을 프로그래밍 방식으로 변경할 수 있는 방법을 원했습니다.

지금까지 나에게 맞지 않는 것을 많이 시도해 보았지만, 지금은 첫 번째 색상밖에 바꿀 수 없습니다.

다음 페이지입니다.

<template>
  <div class="w-full flex flex-col px-6">
    <div class="flex flex-row">
      <button class="flex flex-wrap justify-center content-center w-20 h-20 bg-blob-1 bg-no-repeat bg-contain bg-center -ml-3">
        <img class="flex w-5 h-5" src="~/assets/images/icon-back.svg" alt="">
      </button>
    </div>

    <div class="flex flex-col mt-1">
      <span class="font-raleway font-black text-2xl text-white">{{ route.origin }} - {{ route.destination }}</span>
      <div class="inline-block w-44 bg-black bg-opacity-50 rounded p-2">
         <div class="font-raleway text-md text-white">{{ departureDate.formattedDate }}</div>
      </div>
    </div>

    <div class="flex flex-col mt-10">
      <type :name="name" :bg-color="colours[index].bg" :text-color="colours[index].text" v-for="(values, name, index) in schedules" :key="name" class="mb-10">
        <schedule :schedule="schedule" v-for="schedule in values" :key="schedule.id" class="mb-1" />
      </type>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex';
import type from '~/components/bus/type.vue';
import schedule from '~/components/bus/schedule.vue';

export default {
  name: 'schedules',
  layout: 'bus-default',
  components: {type, schedule},
  async fetch({ store }) {
    const trip = store.state.trip;
    const schedule = store.state.schedule;

    await store.dispatch('schedule/getSchedules', {
      company: trip.company.alias,
      origin: trip.route.origin,
      destination: trip.route.destination, 
      date: trip.departureDate.fullDate,
      schedules: schedule.schedules
    });
  },
  computed: {
    ...mapState({
        company: state => state.trip.company.name,
        route: state => state.trip.route,
        departureDate: state => state.trip.departureDate,
        schedules: state => state.schedule.schedules,
        colours: state => state.schedule.colours
    }),
  }
}
</script>

배지가 포함된 구성 요소는 다음과 같습니다.

<template>
  <div>
      <div :class="{bgColor: true, textColor}" :key="bgColor" class="w-auto inline-block rounded-full px-3 py-1 ml-3 absolute z-20 shadow-md -mt-4 font-raleway text-sm capitalize">{{ name }}</div>
      <slot></slot>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  name: 'type',
  props: ['name', 'bg-color', 'text-color'],
  computed: {
    ...mapState({
        colours: state => state.schedule.colours
    }),
  }
}
</script>

다음은 내 스토어 파일입니다.

export const state = () => ({
    schedules: [],
    schedule: {},
    colours: [{'bg': 'bg-red-400', 'text': 'text-white'}, {'bg': 'bg-blue-400', 'text': 'text-white'}, {'bg': 'bg-yellow-600', 'text': 'text-gray-800'}],
    colour: {}
});

export const mutations = {
    setColours(state, colours) {
        state.colours = colours;
    },
    setColour(state, colour) {
        state.colour = colour;
    },
    setSchedules(state, schedules) {
        state.schedules = schedules;
    },
}

export const actions = {
    async getSchedules({ commit }, params) {
        const res = await this.$api.get('/bus/schedules', { params: params });
        commit('setSchedules', res.data);    
    },
    initialiseColours({ commit }) {
        const colours = [{'bg': 'bg-red-400', 'text': 'text-white'}, {'bg': 'bg-blue-400', 'text': 'text-white'}, {'bg': 'bg-yellow-600', 'text': 'text-gray-800'}];
        commit('setColours', colours);  
    },
    getRandomColour({ commit, state }) {
        var colours = [...state.colours];
         console.log('colours:', colours);
        var index = Math.floor(Math.random() * colours.length);
        const colour = colours.splice(index, 1)[0];
        commit('setColours', colours); 
        commit('setColour', colour);    
    },
}

여기서 달성하고자 하는 것은 각 그룹의 "배지"에 랜덤한 배경색을 프로그래밍 방식으로 할당하는 것입니다.제가 말하는 배지는 사진에 있는 이그제큐티브와 스탠다드입니다.

또한 텍스트는 배경에 따라 표시되어야 하며 필요할 때는 흰색, 필요할 때는 검은색이어야 합니다.

어떤 이유에서인지 제 솔루션은 첫 번째 항목만 변경하고 두 번째 항목은 투명하지만 HTML을 검사하면 클래스가 표시되지만 브라우저에는 색상이 표시되지 않습니다.

편집: 마지막으로 덧붙이는 것을 잊은 것은 색상을 대체하지 않고 사용해야 한다는 것입니다. 즉, 색상을 사용할 수 있었을 때 다시 반복해서는 안 된다는 뜻입니다.

코드가 거의 작동하지만 클래스 바인딩에 문제가 있습니다.

<div :class="{bgColor: true, textColor}"> ❌

이 바인딩에 의해 2개의 클래스가 설정됩니다.div이름 지어진"bgColor"그리고."textColor"그러나 실제로 이러한 소품의 값을 클래스 이름으로 하고 싶다면 이러한 소품들의 배열을 묶어야 합니다.

<div :class="[bgColor, textColor]">

이러한 클래스 이름이 기존 스타일과 일치한다고 가정하면 배경과 텍스트 색상이 그에 따라 업데이트됩니다.

배지 색상을 랜덤화하려면 , 의 카피합니다.state.schedule.colours계산 속성의 배열:

// https://stackoverflow.com/a/2450976/6277151
function shuffleArray(array) {
  if (!array || array.length <= 1) return array;
  array = array.slice();
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    const temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

export default {
  computed: {
    ...mapState({
      colours: state => shuffleArray(state.schedule.colours)
    }),
  }
}

데모

이것은 Vuex를 사용하지 않는 간단하고 간단한 솔루션입니다.만약 당신이 정말로 글로벌한 것이 필요하다고 생각한다면, 그것도 아마 효과가 있을 것입니다.

<template>
  <div>
    <div
      v-for="(button, index) in numberOfIterations"
      :key="button"
      :class="[arrayOfColours[findRandomInRange()]]"
    >
      div #{{ index }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arrayOfColours: ['red', 'blue', 'orange'],
      numberOfIterations: 6,
    }
  },
  methods: {
    findRandomInRange() {
      return Math.floor(Math.random() * this.numberOfIterations) % this.arrayOfColours.length
    },
  },
}
</script>

<style>
.red {
  background-color: red;
}
.blue {
  background-color: blue;
}
.orange {
  background-color: orange;
}
</style>

설명:

  • numberOfIterations기본 루프를 가지기 위해 사용됩니다.
  • % this.arrayOfColours.length우리의 색깔 안에 경계가 있다는 것을 알 수 있습니다.이 예에서는 6회 반복을 설정했지만 색상이 3개밖에 없습니다.예를 들어 5번째 색상을 선택하려고 하면 번거롭습니다.배열에는 3개밖에 없기 때문입니다.
  • findRandomInRange()됩니다. 수 있기 때문입니다. 을 사용법
  • :key 더 이 될 수
  • 내 예에서는 물론 각각의 div에 색이 섞이고, 당신이 그것들을 다시 렌더링할 때마다

나는 나머지가 스스로 설명되었으면 좋겠다.

그리고 이렇게 보입니다.


독특한 색을 원하지만 랜덤한 색을 가지고 싶다는 걸 보고 편집하세요.암호는 더 짧습니다.

<template>
  <div>
    <div v-for="(button, index) in arrayOfColours" :key="button" :class="[arrayOfColours[index]]">
      div #{{ index }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arrayOfColours: ['red', 'blue', 'orange'],
    }
  },
  created() {
    this.shuffle() // shuffle the order of the array before you mount it to the DOM
  },
  methods: {
    shuffle() {
      this.arrayOfColours.sort(() => Math.random() - 0.5)
    },
  },
}
</script>

언급URL : https://stackoverflow.com/questions/67512208/dynamically-change-colours-of-element-in-vue-loop

반응형