Ошибка указывает, что объект, содержащий свойство с именем «alignText», имеет значение undefined
.Это не означает, что alignText
само по себе является undefined
.В вашем коде есть три ссылки на alignText
:
content.headerStyling1.alignText
content.headerStyling2.alignText
content.headerStyling3.alignText
Так что по крайней мере один из headerStylingN
объектов - undefined
.Если вы хотите убедиться, что объекты разыменовываются только тогда, когда не undefined
, вы можете использовать оператор &&
в привязке стиля:
<h1 v-if="content.header1" :style="content.headerStyling1 && {'text-align': content.headerStyling1.alignText, ...}">
^^^^^^^^^^^^^^^^^^^^^^^^^
<h2 v-if="content.header2" :style="content.headerStyling2 && {'text-align': content.headerStyling2.alignText, ...}">
^^^^^^^^^^^^^^^^^^^^^^^^^
<h3 v-if="content.header3" :style="content.headerStyling3 && {'text-align': content.headerStyling3.alignText, ...}">
^^^^^^^^^^^^^^^^^^^^^^^^^
Например, content.headerStyling1 && {'text-align': content.headerStyling1.alignText, ...}
оценивает объект стилятолько если content.headerStyling1
существовал / правдив, а false
в противном случае (без стиля).
new Vue({
el: '#app',
data: () => ({
content: {
header1: 'Header 1',
headerStyling1: {
alignText: 'right',
fontSize: '14px',
fontType: 'Times',
letterSpacing: '1px',
lineHeight: '1.2em',
textColor: '#777',
padding: {
pixels: '8px'
}
},
header2: 'Header 2',
header3: 'Header 3',
headerStyling3: {
fontSize: '14px',
fontType: 'Arial',
letterSpacing: '1px',
lineHeight: '1.2em',
textColor: '#888',
padding: {
pixels: '8px'
}
},
}
}),
})
<script src="https://unpkg.com/vue@2.5.17"></script>
<div id="app">
<h1 v-if="content.header1" :style="content.headerStyling1 && {'text-align': content.headerStyling1.alignText, 'font-size': content.headerStyling1.fontSize, 'font-family': content.headerStyling1.fontType, 'letter-spacing': content.headerStyling1.letterSpacing, 'line-height': content.headerStyling1.lineHeight, 'color': content.headerStyling1.textColor, 'padding': content.headerStyling1.padding.pixels}">
{{content.header1}}
</h1>
<h2 v-if="content.header2" :style="content.headerStyling2 && {'text-align': content.headerStyling2.alignText, 'font-size': content.headerStyling2.fontSize, 'font-family': content.headerStyling2.fontType, 'letter-spacing': content.headerStyling2.letterSpacing, 'line-height': content.headerStyling2.lineHeight, 'color': content.headerStyling2.textColor, 'padding': content.headerStyling2.padding.pixels}">
{{content.header2}}
</h2>
<h3 v-if="content.header3" :style="content.headerStyling3 && {'text-align': content.headerStyling3.alignText, 'font-size': content.headerStyling3.fontSize, 'font-family': content.headerStyling3.fontType, 'letter-spacing': content.headerStyling3.letterSpacing, 'line-height': content.headerStyling3.lineHeight, 'color': content.headerStyling3.textColor, 'padding': content.headerStyling3.padding.pixels}">
{{content.header3}}
</h3>
</div>
Дополнительная очистка ...
При желании вы можете дополнительно очистить шаблон и минимизировать повторяющийся код:
Создать метод (computeStyles
) для возврата нормализованного объекта стиля на основе заданного объекта стиля (другого формата):
methods: {
computeStyles(styles) {
return styles && {
'text-align': styles.alignText,
'font-size': styles.fontSize,
'font-family': styles.fontType,
'letter-spacing': styles.letterSpacing,
'line-height': styles.lineHeight,
'color': styles.textColor,
'padding': styles.padding.pixels
};
}
},
Создайте вычисляемое свойство для каждого стиля заголовка, который вызывает computeStyles
сверху:
computed: {
headerStyling1() {
return this.computeStyles(this.content.headerStyling1);
},
headerStyling2() {
return this.computeStyles(this.content.headerStyling2);
},
headerStyling3() {
return this.computeStyles(this.content.headerStyling3);
}
},
Свяжите эти стили вычисленного свойства в шаблоне:
<h1 v-if="content.header1" :style="headerStyling1">
{{content.header1}}
</h1>
<h2 v-if="content.header2" :style="headerStyling2">
{{content.header2}}
</h2>
<h3 v-if="content.header3" :style="headerStyling3">
{{content.header3}}
</h3>
new Vue({
el: '#app',
data: () => ({
content: {
header1: 'Header 1',
headerStyling1: {
alignText: 'right',
fontSize: '14px',
fontType: 'Tahoma',
letterSpacing: '1px',
lineHeight: '1.2em',
textColor: 'red',
padding: {
pixels: '8px'
}
},
// header2: 'Header 2',
// headerStyling2: {
// alignText: 'center',
// fontSize: '14px',
// fontType: 'Tahoma',
// letterSpacing: '1px',
// lineHeight: '1.2em',
// textColor: 'blue',
// padding: {
// pixels: '8px'
// }
// },
header3: 'Header 3',
headerStyling3: {
fontSize: '14px',
fontType: 'Tahoma',
letterSpacing: '1px',
lineHeight: '1.2em',
textColor: 'green',
padding: {
pixels: '8px'
}
},
}
}),
computed: {
headerStyling1() {
return this.computeStyles(this.content.headerStyling1);
},
headerStyling2() {
return this.computeStyles(this.content.headerStyling2);
},
headerStyling3() {
return this.computeStyles(this.content.headerStyling3);
}
},
methods: {
computeStyles(styles) {
return styles && {
'text-align': styles.alignText,
'font-size': styles.fontSize,
'font-family': styles.fontType,
'letter-spacing': styles.letterSpacing,
'line-height': styles.lineHeight,
'color': styles.textColor,
'padding': styles.padding.pixels
};
}
},
})
<script src="https://unpkg.com/vue@2.5.17"></script>
<div id="app">
<h1 v-if="content.header1" :style="headerStyling1">
{{content.header1}}
</h1>
<h2 v-if="content.header2" :style="headerStyling2">
{{content.header2}}
</h2>
<h3 v-if="content.header3" :style="headerStyling3">
{{content.header3}}
</h3>
</div>