【问题标题】:Dynamically change colours of element in vue loop在Vue循环中动态改变元素的颜色
【发布时间】:2021-05-12 23:31:59
【问题描述】:

所以我正在尝试实现以下设计:

特别是顶部的彩色徽章。现在这些项目被分组并且可以是任意数字。 在图片中,它们被分为 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 时,我看到了那里的类,但它没有在浏览器中显示颜色。

编辑:所以我忘记添加的最后一件事是颜色应该在没有替换的情况下使用,这意味着当一个可以使用时它不应该再次重复。

【问题讨论】:

  • 这里真的需要用vuex吗?看起来工作比其他任何事情都多。否则,这是我对您的用例的看法:stackoverflow.com/a/67382023/8816585 如果您想要完全随机的东西,请使用一个简单的 colours 数组,其中包含 ['bg-red-400', 'bg-blue-400', 'bg-yellow-400' etc...],而不是带有无用 bg 键的对象数组。跨度>

标签: vue.js nuxt.js vuex


【解决方案1】:

您的代码即将运行,但类绑定存在问题:

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

该绑定在div 上设置了两个名为"bgColor""textColor" 的类,但是如果您确实希望这些道具的值是类名,则应该绑定这些道具的数组:

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

假设这些类名对应于现有样式,则背景和文本颜色会相应更新。

要随机化徽章颜色,shuffle 计算属性中 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)
    }),
  }
}

demo

【讨论】:

    【解决方案2】:

    这是一个没有 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>
    

    【讨论】:

      猜你喜欢
      • 2012-03-30
      • 2021-12-31
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      • 2015-10-27
      • 1970-01-01
      • 2021-12-22
      相关资源
      最近更新 更多