我可以将自定义视图组件注入Vue.js网格组件吗?

时间:2016-04-07 12:28:54

标签: components decorator vue.js

我在Vue.js中有一个数据网格组件,看起来有点像官方样本中的那个:http://vuejs.org/examples/grid-component.html

基于输入数据而不是纯字符串有时我想将“装饰”条目显示为复选框或v-link组件(不仅仅是,我可能还需要渲染其他组件,如未转义的HTML或张图片)。

显然我不想为所有用例准备Grid组件,所以我想做的事情:

要显示的示例数据模型:

model = [
  {
    field1: 'some string',
    field2: 'another string',
    field3: { // this should be a checkbox
      state: true
    },
    field4: { // this should be an <a v-link>
      url: 'http://whatever',
      label: 'go somewhere'
    }
  }
]

Grid组件的相关摘录:

<template>
  ...
    <tr v-for="entry in model">
      <td>
        <div v-if="typeof entry === 'object' && entry.hasOwnPropery('url')">
          <a v-link="entry.url">{{ entry.label }}</a>
        </div>
        <div v-if="typeof entry === 'object' && entry.hasOwnProperty('state')">
          <input type="checkbox" v-model="entry.state">
        </div>
        <div v-else>
          {{ entry }}
        </div>
      </td>
    </tr>
  ...
</template>

将自定义组件注入装饰器的Vue.js理念是什么?我希望我的网格与这些装饰器组件完全无关。

1 个答案:

答案 0 :(得分:1)

这是一个可变组件的好地方。您可以定义一些不同的装饰器组件,然后使用您的数据来决定应该使用哪个组件进行渲染。

模板:

<div id="app">
<ul>
    <li
    v-for="entry in entries"
    >
    <component :is="entry.type">
        {{ entry.content }}
    </component>
    </li>
</ul>
</div>

组件:

new Vue({
  el: '#app',
  components: {
    'blank': {
      template: '<div><slot></slot></div>'
    },
    'green': {
      template: '<div style="color: #0f0;"><slot></slot></div>'
    },
    'red': {
      template: '<div style="background-color: #f00;"><slot></slot></div>'
    }
  },
  computed: {
    entries: function() {
      return this.raw_entries.map(
        function(entry) {
          if (typeof entry !== "object") {
            return { type: 'blank', content: entry }
          }

          if (!entry.hasOwnProperty('type')) {
            entry.type = 'blank'
          }

          return entry
        }
      )
    }
  },
  data: {
    raw_entries: [
      'Base Text',
      {
        type: 'green',
        content: 'Green Text'
      },
      {
        type: 'red',
        content: 'Red Background'
      }
    ]
  }
})

JsFiddle使用列表的工作示例