在 VueJS 中从 Prop 和 Prop 值创建类

Posted

技术标签:

【中文标题】在 VueJS 中从 Prop 和 Prop 值创建类【英文标题】:Creating Classes From Props & Prop Values in VueJS 【发布时间】:2019-08-05 14:44:06 【问题描述】:

我希望在 VueJS 中创建一个列组件,看起来像这样:

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

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

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

换句话说,我想将道具名称及其值连接在一起,然后将连接的字符串添加到类属性中——我很难弄清楚该怎么做。

有什么想法吗?

【问题讨论】:

【参考方案1】:

如果要使用组件的所有属性,您可以使用Object.entriesthis.$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;
<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>

【讨论】:

以上是关于在 VueJS 中从 Prop 和 Prop 值创建类的主要内容,如果未能解决你的问题,请参考以下文章

VueJS - 函数的结果作为 Prop 的默认值

vueJs-非prop的特性

VueJs 组件的 Prop 相关计算属性对对象数组 Prop 更改没有反应

VueJS 使用 prop 作为数据属性值

VueJS 使用 prop 作为数据属性值

将 VueJS Prop 传递给 TypeScript 类组件