Как связать атрибут стиля, если данные верны? - PullRequest
0 голосов
/ 13 декабря 2018

Надеюсь, вы можете помочь.

Я пытаюсь выяснить, как включить атрибут css стиля, только если данные истинны, в противном случае, если в данных нет значения css, тогда это не так.В настоящее время я вижу следующую ошибку в консоли:

Поскольку для alignText нет значения, эта ошибка отображается в консоли (что я не возражаю; alignText является необязательным)

Ошибка при рендеринге: «Ошибка типа: невозможно прочитать свойство 'alignText' из неопределенного» * ​​1008 *

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 голосов
/ 14 декабря 2018

Ошибка указывает, что объект, содержащий свойство с именем «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: {
      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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...