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-data-table 之前,使用带有内部但动态传递模板槽的组件以及允许项目修改的最佳方法是什么(根据上面的第 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" 
/>

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

4

0 回答 0