我有一个 Vue 组件,我想扩展它以便将颜色绑定到特定消息。我尝试过像这样的绑定
:style="styles"
但后来我得到了错误
属性或方法"样式"不是在实例上定义的,而是在呈现过程中引用的。通过初始化属性,确保此属性在 data 选项中或对于基于类的组件是反应性的
或者通过在 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>
试试这个,
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
},
}
},
...
您发布的截图没有引用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}`
}
`;
}
}
我认为这有点黑客,但这是我用来在运行时更改我的 css 类的方法
在您的情况下,您无法在数据初始化期间访问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]
};
},
我是否理解你的问题,但你可以尝试计算方法:
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>
如果你想像以前一样保留道具并且道具"消息"会改变,你应该使用 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;
})
},