在VueJS中根据属性和属性值创建类

时间:2019-03-14 15:59:22

标签: vue.js vuejs2 vue-component

我正在寻找在VueJS中创建一个列组件,其外观将如下所示:

<column-i xs="3" md="6" lg="12">
  Some Content
</column-i>

渲染后,我希望html标记看起来像这样:

<div class="column xs3 md6 lg12>Some Content</div>

换句话说,我想将prop名称和它的值连接在一起,然后将连接的字符串添加到class属性中-我很难确定该怎么做。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果将使用组件的所有属性,则可以使用Object.entriesIf (GetFlag = True) Then MsgBox ("Data already entered for today, use Edit button") End If If (GetFlag = False) Then... 来获取所有this.$props对的数组。然后,在计算属性中迭代数组以构造将绑定到组件元素的类。

[key, value]
const ColumnI = {
  name: 'column-i',

  template: `<div :class="columnClass"><slot /></div>`,

  // Define the props that will be converted into classes
  props: {
    xs: {
      Type: Number,
      default: null,
    },

    md: {
      Type: Number,
      default: null,
    },

    lg: {
      Type: Number,
      default: null,
    },
  },

  computed: {
    columnClass() {
      let result = ['column']
      // Look for all the component props and get an array of all its
      // enumerable [key, value] pairs
      for (let [propKey, propValue] of Object.entries(this.$props)) {
        // If the prop has a value
        if (propValue) {
          // Add the prop to the class as '<key><value>'
          // ie. xs prop with a value of 3 results in 'xs3'
          result.push(`${propKey}${propValue}`)
        }
      }
      return result
    },
  },
}

new Vue({
  el: '#app',

  components: {
    ColumnI,
  }
})
/*
 Random styles just for illustration purposes
*/

.column {
  padding: 10px;
}

.xs3 {
  color: dodgerblue;
}

.md6 {
  background-color: whitesmoke;
}

.lg12 {
  border: 2px solid tomato;
}


上述解决方案无法处理将不会作为类绑定到该组件的道具。

要解决这个问题,我们可以创建一个要转换为类的断点数组。

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <column-i xs="3" md="6" lg="12">
    Some Content
  </column-i>
</div>
const ColumnI = {
  name: 'column-i',

  template: `<component :is="tag" :class="columnClass"><slot /></component>`,

  props: {
    // This prop will not be converted into a class
    tag: {
      Type: String,
      default: 'div',
    },

    xs: {
      Type: Number,
      default: null,
    },

    md: {
      Type: Number,
      default: null,
    },

    lg: {
      Type: Number,
      default: null,
    },
  },

  data() {
    return {
      breakpoints: ['xs', 'md', 'lg'],
    }
  },

  computed: {
    columnClass() {
      let result = ['column']
      // Look for all the component props and get an array of all its
      // enumerable [key, value] pairs
      for (let [propKey, propValue] of Object.entries(this.$props)) {
        // If the prop is a breakpoint and it has a value
        if (this.breakpoints.includes(propKey) && propValue) {
          // Add the prop to the class as '<key><value>'
          // ie. xs prop with a value of 3 results in 'xs3'
          result.push(`${propKey}${propValue}`)
        }
      }
      return result
    },
  },
}

new Vue({
  el: '#app',

  components: {
    ColumnI,
  }
})
/*
 Random styles just for illustration purposes
*/

.tagdiv {
  /* This will not be applied */
  text-decoration: underline;
}

.column {
  padding: 10px;
}

.xs3 {
  color: dodgerblue;
}

.md6 {
  background-color: whitesmoke;
}

.lg12 {
  border: 2px solid tomato;
}