v-data-table 中的动态项目模板槽,带有自定义组件和助手

问题描述 投票:0回答:1

假设我有一个使用 Vuetify 的

v-data-table
的自定义组件。

在此组件中,还有多个其他自定义组件,例如加载器和特定的基于列的组件,用于以某种方式显示数据。

我发现自己在整个项目中使用相同的代码来过滤、检索数据、加载器等 - 所以不是很干燥。

不同的地方是:

  1. 用于检索数据的 API 请求 url(我可以将其传递给此通用组件)

  2. v-data-table
    的标头(我将其传递给此通用组件)

  3. 特定物品槽模板! (使用相同代码的一个文件需要像下面这样的列修改,有时也需要不同的组件):

      <template v-slot:[`item.FullName`]="{ item }">
        <router-link class="black--text text-decoration-none" :to="'/users/' + item.Id">
         <Avatar :string="item.FullName" />
        </router-link>
      </template>
    

    另一个例子:

      <template v-slot:[`item.serial`]="{ item }">
        <copy-label :text="item.serial" />
      </template>
    

    我显然使用了许多更独特的“列模板”,这只是一个示例。

  4. 修改计算属性中传递给

    v-data-table
    的项目(添加“操作”或运行清理和/或在显示内容之前修改内容 - 与实际 HTML 输出无关,而是值本身)

      computed: {
        items () {
          if (!this.data || !this.data.Values) {
            return []
          }
    
         return this.data.Values.map((item) => {
           return {
             device: this.$getItemName(item),
             serial: item.SerialNumber,
             hwVersion: this.$getItemHwVersion(item),
             swVersion: this.$getItemSwVersion(item),
             actions: [
              { to: '/devices/' + item.Id, text: this.$t('common.open') },
              { to: '/devices/' + item.Id + '/replace', text: this.$t('common.replace') }
       ],
             ...item
          }
       })
    }
    
  5. 我可以在某些模板槽项修改上使用一些独特的方法,例如下面的 dateMoreThan24HoursAgo() :

      <template v-slot:[`item.LastLogin`]="{ item }">
         <span v-if="dateMoreThan24HoursAgo(item.LastLogin)">{{ item.LastLogin | formatDate }}</span>
         <span v-else>
           {{ item.LastLogin | formatDateAgo }}
         </span>
       </template>
    

    我总是可以将其设为全局或将它们作为道具提供,所以这一点不应该是一个大问题。

所以我的问题是:

  1. 使用带有
    v-data-table
    的组件但动态传递模板槽并允许在将数组传递到 v 数据表之前进行项目修改(根据上面的第 3 点和第 4 点)的最佳方法是什么
  2. 有没有更好的方法来解决这个问题,因为这看起来太复杂了(我应该保留单独的特定文件)吗?它感觉不太干燥,这就是为什么我不太喜欢当前的解决方案。

基本上我很乐意拥有类似的东西:

data: () => {
    return {
      apiPath: 'devices',
      headers: [
        { text: 'Device', align: 'start', value: 'device', sortable: false, class: 'text-none' },
        { text: 'Serial Number', sortable: false, value: 'serial', class: 'text-none' },
        { text: 'Status', value: 'Status', class: 'text-none' },
        { text: 'Calibration', value: 'NextCalibrationDate', class: 'text-none' },
        { text: '', sortable: false, align: 'right', value: 'actions' }
      ],
      itemsModify: (items) => {
         return items.map((item) => {
           return {
             device: this.$getItemName(item),
             serial: item.SerialNumber,
             actions: [
              { to: '/devices/' + item.Id, text: this.$t('common.open') },
              { to: '/devices/' + item.Id + '/replace', text: this.$t('common.replace') }
              ],
             ...item
          }
        })
      },
      columnTemplatesPath: '/path/to/vue/file/with/templates' 
    }
  }

然后我就这样调用我的动态组件:

<GenericTable 
  :api-path="apiPath" 
  :headers="headers" 
  :items-modify="itemsModify" 
  :column-templates-path="columnTemplatesPath" 
/>

与我的问题相关但不完全是解决方案:

vue.js vuejs2 datatable vuetify.js v-data-table
1个回答
0
投票

我们面临同样的情况,你解决了吗?你找到解决办法了吗?

© www.soinside.com 2019 - 2024. All rights reserved.