【问题标题】:Dynamic css in vue-loader component not workingvue-loader 组件中的动态 css 不起作用
【发布时间】:2018-08-20 14:09:49
【问题描述】:

我有一个 Vue 组件,我想扩展它以便将颜色绑定到特定消息。我用类似的绑定试过了

:style="styles"

然后我得到了错误

属性或方法“样式”未在实例上定义,而是在渲染期间引用。通过初始化属性,确保此属性是反应性的,无论是在数据选项中,还是对于基于类的组件

或者通过在 css 中创建特定的颜色类。

color--1

遇到类似的错误

“无法读取未定义的属性‘2’”

如何通过从 API 接收数字来动态绑定类的颜色?

这是我的代码

<template>
    <div class="chat__message shadow" :class="{'chat__message--own': message.selfOwned, colorClass}" >

    </div>
</template>

<script>
    import moment from 'moment'
    export default {
        props: ['message'],
        data(){
            return{
                time: '',
                colorArray: ['hsl(210 , 82 , 50 )', 'hsl(130 , 50 , 51 )', 'hsl(337 , 50 , 46 )','hsl(133 , 50 , 65 )', 'hsl(28 , 50 , 70 )','hsl(180 , 50 , 59 )' , 'hsl(274 , 50 , 82 )'],
                colorClass:'',
                styles: {
                    'background-color' : this.colorArray[2]
                },
            }
        },
        created(){
            this.time = moment(this.message.created_at).format('HH:mm');
            this.setColorClass(this.message.matchPosition);
        },
        methods: {
            setColorClass(number){
                this.colorClass = "color--" + number ;
            }
        }
    }
</script>

<style lang="scss">
    .color{
            &--1{background-color: hsl(210 , 82 , 50 );}
            &--2{background-color: hsl(130 , 50 , 51 );}
            &--3{background-color: hsl(337 , 50 , 46 );}
            &--4{background-color: hsl(133 , 50 , 65 );}
            &--5{background-color: hsl(28 , 50 , 70 );}
            &--6{background-color: hsl(180 , 50 , 59 );}
            &--7{background-color: hsl(274 , 50 , 82 );}
    }
    .chat{
        &__message{

            &--own{
                background-color: hsl(201, 100%, 55%);
                color: rgba(255,255,255,1);
                text-align: right;
}}

</style>

【问题讨论】:

    标签: css laravel vue.js vue-loader


    【解决方案1】:

    试试这个,

    export default {
         props: ['message'],
         data(){
             var self = this; // Add this
             return{
                 time: '',
                 colorArray: ['hsl(210 , 82 , 50 )', 'hsl(130 , 50 , 51 )', 'hsl(337 , 50 , 46 )','hsl(133 , 50 , 65 )', 'hsl(28 , 50 , 70 )','hsl(180 , 50 , 59 )' , 'hsl(274 , 50 , 82 )'],
                 colorClass:'',
                 styles: {
                     'background-color' : self.colorArray[2] // change here
                 },
             }
         },
    ...
    

    【讨论】:

    • 没有同样的问题,同样的错误...Property or method "styles" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
    • styles 应该是一个计算属性 imo。你打算如何改变它/它的目的是什么?
    【解决方案2】:

    您发布的片段没有引用 styles 的 html,是另一个组件试图引用该组件的 styles 变量吗?

    如何动态绑定类的颜色,通过接收 来自 API 的编号?

    如果您将cssEl 添加到组件的data 对象中,您可以执行以下操作:

    watch: {
      // Keep track of the color (or colors) taken from the api
      colorTakenFromApi () {
        // Remove the old class if it exists;
        this.cssEl && this.cssEl.remove();
        // Create the element in the DOM, then tell the browser it's a stylesheet
        this.cssEl = document.createElement('style');
        this.cssEl.type = 'text/css';
        // Use a text template to insert the css rule you want
        this.cssEl.innerHTML = `
          .${this.cssClass} {
            background-color: `${this.colorTakenFromApi}`
          }
        `;
      }
    }
    

    我认为这有点 hack,但这是我用来在运行时更改我的 css 类的方法

    【讨论】:

      【解决方案3】:

      在您的情况下,您无法在数据初始化期间访问this

      解决方法是:

      将您的样式对象初始化为空。

      data(){
          return{
              time: '',
              colorArray: ['hsl(210 , 82 , 50 )', 'hsl(130 , 50 , 51 )', 'hsl(337 , 50 , 46 )','hsl(133 , 50 , 65 )', 'hsl(28 , 50 , 70 )','hsl(180 , 50 , 59 )' , 'hsl(274 , 50 , 82 )'],
              colorClass:'',
              styles: {},
          }
      },
      

      然后在created生命周期设置初始样式:

      created() {
          this.time = moment(this.message.created_at).format('HH:mm');
          this.setColorClass(this.message.matchPosition);
      
          // Using Vue.set
          Vue.set(this, 'styles', {
              'background-color' : self.colorArray[2]
          });
      
          // OR Normal setting
          this.styles = {
              'background-color' : this.colorArray[2]
          };
      },
      

      【讨论】:

        【解决方案4】:

        我不知道我是否理解您的问题,但您可以尝试计算方法:

        props: ['message', 'colorNumber'],
        computed: {
           getColorClass () {
              return 'color--' + this.colorNumber
           }
        },
        

        在你的模板中:

        <template>
            <div :class="{'chat__message shadow': true,
                          'chat__message--own': message.selfOwned,
                           getColorClass: true}" >
            </div>
        </template>
        

        如果你想像以前一样保持 props 并且 prop "message" 会改变,你应该使用 watch(deep kind) 而不是计算一个。

        否则,如果页面加载后消息道具不会改变,那么您可以将其加载到 data() 变量中并在计算方法中使用它:

        data(){
            return {
                colorNumber: '',
            }
        },
        mounted() {
           this.$nextTick(function () {
               // Code that will run only after the
               // entire view has been rendered
        
               this.colorNumber = this.message.matchPosition;
           })
        },
        

        【讨论】:

          猜你喜欢
          • 2018-10-24
          • 2018-12-01
          • 1970-01-01
          • 2022-11-08
          • 1970-01-01
          • 2019-02-12
          • 1970-01-01
          • 2021-02-01
          • 1970-01-01
          相关资源
          最近更新 更多