Vue 组件动态样式传值

前端问题

最近在做数字化合规项目,做前端页面时遇到一个需求:展示各个状态的任务数量统计,大概是左侧图标、右侧数字的样式。由于很多地方都要展示同样的内容,就将这小块写了一个组件出来。

在页面上引入这个组件之后,数据展示没有问题,但是从父组件传过来图标的颜色会在后端数据返回后消失,展示成默认的黑色。

<!-- 父组件 -->
<template>
    <div>
        <my-component :title="title" :dataList="dataList"></my-component>
    </div>
</template>
<script>
export default {
    data() {
        return {
            title: 'XX 任务总览',
            dataList: [
                {
                    name: '待办',
                    value: 'todo',
                    icon: 'el-file-outline',
                    // 字体图标的颜色
                    color: 'rgb(10, 10, 10)'
                }
            ]
        }
    }
}
</script>
<!-- 自组件 -->
<template>
    <div>
        <h1>{{ title }}</h1>
        <div v-for="(index, item) in dataList">
            <div :style="{'color': 'item.color'}">
                <span><i :class="[iconList[index]]"></i></span>    
            </div>
        </div>
    </div>
</template>
<script>
export default {
    props: ['title', 'dataList'],
    data() {
        return {
            iconList: []
        }
    }
    created: {
        this.iconList = this.dataList.map(e => e.icon)
    }
}
</script>

用上面这种写法,图标可以展示,父组件请求后端接口报错时图标颜色展示正常,但是正常返回数据之后,颜色会一闪而过。

问题排查

将 v-for 循环里的颜色值打印出来,发现是 undefined,但是其他属性是有值的,开始怀疑是 dom 加载和数据请求的顺序问题或者是自组件监听父组件值变化的问题,看到这个结果之后不确定问题是什么了。

解决方案

在网上搜了一些类似的问题,但是好像都只是传单个样式进去,不涉及到 v-for 循环里取动态样式的。

博客园上有一个解决方案:vue动态设置组件样式,通过 css var(–myStyle) 来解决,但是仅限于样式数量确定的情况,排除。

最后意识到既然 icon 可以正常取到,换成和 color 一样的写法不就可以了吗?于是改了一下自组件的写法:

...
<div :style="{'color': '[colorList[index]]'}">
    <span><i :class="[iconList[index]]"></i></span>    
</div>
...
<script>
export default {
    props: ['title', 'dataList'],
    data() {
        return {
            iconList: [],
            colorList: []
        }
    }
    created: {
        this.iconList = this.dataList.map(e => e.icon)
        this.colorList = this.dataList.map(e => e.color)
    }
}
</script>

刷新一下缓存重新加载页面,颜色可以正常展示了。