Vue嵌套自定义组件范围

时间:2017-04-17 17:39:08

标签: vue.js

我想创建一组可重用的实用程序/非ui组件,通过允许它来实现任何HTML表:

  • 附加到http数据源
  • 排序
  • 分页
  • 过滤等

我希望在使用它时所拥有的代码如下:

<my-app>
  <data-table :url="url">
    <table>
      <thead>
        <tr>
          <dt-th sort-key="name">Name</dt-th>
          <dt-th sort-key="surname">Surname</dt-th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in data">
          <td>{{ row.name }}</td>
          <td>{{ row.surname }}</td>
        </tr>
      </tbody>
    </table>
  </data-table>
</my-app>

上面代码的最大问题是Vue在MyApp组件中查找以解析dt-th元素,data表达式等。有没有办法让这个工作?

您可以在此处找到我的伪应用:https://plnkr.co/edit/30Z7L3zrfrGmED17QrIh?p=preview

1 个答案:

答案 0 :(得分:1)

您的数据问题可以使用scoped slot解决。

const DataTable = {
  components: {
    'dt-th': DataTableHeaderCell
  },
  props: ['src'],
  data () {
    return {
      data: [
        { name: 'Gale', surname: 'Marlon' },
        { name: 'Corwin', surname: 'Hayden' }
      ]
    }
  },
  created () {
    EventBus.$on('sort', this.sort)
  },
  methods: {
    sort (sortKey) {
      console.log(`Sorting by ${sortKey}`)
    }
  },
  template: `
    <div><slot :rows="data"></slot></div>
  `
}

您的模板变为

<data-table :src="src">
  <template scope="{rows}">
    <table>
      <thead>
        <tr>
          <dt-th sort-key="name">Name</dt-th>
          <dt-th sort-key="surname">Surname</dt-th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in rows">
          <td>{{ row.name }}</td>
          <td>{{ row.surname }}</td>
        </tr>
      </tbody>
    </table>
  </template>
</data-table>

要解决dt-dh问题,您可以将其公开给Vue。

const DataTableHeaderCell = {
  props: ['sort-key'],
  methods: {
    emit () {
      EventBus.$emit('sort', this.sortKey)
    }
  },
  template: `
    <th @click="emit"><slot></slot></th>
  `
}

Vue.component("dt-th", DataTableHeaderCell)

这是您的plunkr updated

另一种选择是通过范围传递DataTableHeaderCell的定义。

const DataTable = {
  props: ['src'],
  data () {
    return {
      data: [
        { name: 'Gale', surname: 'Marlon' },
        { name: 'Corwin', surname: 'Hayden' }
      ], 
      DataTableHeaderCell
    }
  },
  created () {
    EventBus.$on('sort', this.sort)
  },
  methods: {
    sort (sortKey) {
      console.log(`Sorting by ${sortKey}`)
    }
  },
  template: `
    <div><slot :rows="data" :header="DataTableHeaderCell"></slot></div>
  `
}

在你的模板中

<data-table :src="src">
  <template scope="{rows, header}">
    <table>
      <thead>
        <tr>
          <th :is="header" sort-key="name">Name</th>
          <th :is="header" sort-key="surname">Surname</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in rows">
          <td>{{ row.name }}</td>
          <td>{{ row.surname }}</td>
        </tr>
      </tbody>
    </table>
  </template>
</data-table>

以下是example