如果数据为真,如何绑定样式属性?

时间:2018-12-13 18:12:53

标签: javascript vue.js vuejs2

希望您能提供帮助。

我试图弄清楚如何仅在数据为true时才包括样式css属性,否则,如果数据中的css没有值,那就没关系了。.目前,我看到以下错误在控制台中:

由于alignText没有值,因此控制台中会显示此错误(我不介意; alignText是可选的)

渲染错误:“ TypeError:无法读取未定义的属性'alignText'”

HTML

<h1 v-if="content.header1" :style="{'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="{'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="{'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>

数据

"headerStyling1": {
            "type": "object",
            "title": "Header 1 Styling",
            "description": "",
            "allOf": [
                {
                    "$ref": "textstyling.json"
                }
            ]
        },

文字样式

"fontType": {
        "type": "string",
        "enum": [
            "Opens Sans",
            "Times New Roman"
        ],
        "title": "Text Font Type",
        "description": "Font style type. Leave blank for default styling."
    },
    "fontSize": {
        "type": "string",
        "minLength": 0,
        "maxLength": 5,
        "title": "Font Size",
        "description": "Font size in pixels. e.g 10px. Leave blank for default styling."
    },
    "textColor": {
        "type": "string",
        "minLength": 0,
        "maxLength": 7,
        "title": "Text Colour",
        "description": "Hexcode e.g #000000. Leave blank for default styling."
    },
    "alignText": {
        "type": "string",
        "enum": [
            "left",
            "right",
            "center",
            "justify"
        ],
        "title": "Text Align",
        "description": ""
    },

如何检查CSS是否具有值,然后进行设置;如果没有,那就没关系,然后继续。

谢谢

1 个答案:

答案 0 :(得分:0)

该错误表明包含名为“ 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>

额外清理...

您可以选择进一步清理模板,并最大程度地减少重复代码:

  1. 创建一个方法(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
        };
      }
    },
    
  2. 为从上方调用computeStyles的每种标题样式创建computed property

    computed: {
      headerStyling1() {
        return this.computeStyles(this.content.headerStyling1);
      },
      headerStyling2() {
        return this.computeStyles(this.content.headerStyling2);
      },
      headerStyling3() {
        return this.computeStyles(this.content.headerStyling3);
      }
    },
    
  3. 在模板中绑定那些计算属性样式:

    <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>