繁体   English   中英

如何干燥使用具有多个道具和插槽的 Vue.js 组件

[英]How to DRY use a Vue.js component with multiple props and slots

在 vuejs 应用程序中有 3 个组件 - TopClicks .vue、 TopImpressions .vue、 TopCtr .vue。 其中每一个都使用vue-good-table (组件本身并不重要,它可以是任何一个)来呈现几乎相同的表格,但排序不同:

../components/TopClicked.vue (almost 200 lines)

<template>
  <div class="top-clicked">
    <vue-good-table
      mode="remote"
      @on-page-change="onPageChange"
      @on-sort-change="onSortChange"
      :sort-options="{
        enabled: true,
        initialSortBy: {field: 'clicks', type: 'desc'}
      }"
      ... 
    >
      <template slot="table-row" slot-scope="props">
        <template v-if="props.column.field === 'keyword'">
          ...
        </template>
        <template v-else-if="props.column.field === 'clicks'">
          ...
        </template>
        <template v-else-if="props.column.field === 'impressions'">
          ...
        </template>
         ...
      </template>
      <template slot="loadingContent">
        <span class="vgt-loading__content">
          ...
        </span>
      </template>
      <template slot="emptystate">
          ...
      </template>
    </vue-good-table>
  </div>
</template>

<script>

import { VueGoodTable } from 'vue-good-table';

export default {
  name: 'TopClicked',
  components: { VueGoodTable},
  data() {
    return {
      columns: [
        {
          label: this.$t('keyword'),
          field: 'keyword',
        },
        {
          label: this.$t('clicks'),
          field: 'clicks',
        },
        ... more columns
      ],
    };
  },
};
</script>

其他两个组件 - TopImpressions .vue 和TopCtr .vue 几乎相同,但具有不同:sort-options参数。

我的问题是:如何组织我的代码以避免在传递给vue-good-table的组件道具或插槽模板中多次进行相同的更改? 一个组件应该是什么样子,它将默认的 props 和 slot 传递给另一个组件,但是这些可以在需要时被覆盖?

如果不是从上面复制 200 行代码,而是可以像这样创建和使用子组件(具有基本优点和插槽模板) ,那就太好了

<vue-good-table-child
  // this should overwrite default :sort-options in vue-good-table-child
  :sort-options="{
    enabled: true,
    initialSortBy: {field: 'impressions', type: 'desc'}
  }"
>
  // this should overwrite default named slot "loadingContent" in vue-good-table-child
  <template slot="loadingContent">
    ...
  </template>
</vue-good-table-child>

这样,所有通用代码都将位于基础组件中,并且只有不同的道具(或插槽模板)应传递给子组件。

我会尝试将 3 个几乎相同的组件合并为 1 个组件,该组件接收它需要的自定义sortOptions作为prop

// This is the merged component, TopThings.vue, it replaces the instances 
// of TopClicks.vue, TopImpressions.vue, and TopCtr.vue in the parent component

<template>
<div class="top-clicked">
    <vue-good-table
        ...
        :sort-options="sortOptions"
        ...
    />
    ...
</template>

<script>
    ...
    props: {
        sortOptions: {
            type: Object,
            required: true,
        },
    },
    ...
</script>

在您的父组件中,导入 TopThings 组件并调用它来代替您之前的 3 个组件中的每一个,其中每个实现都传递了其各自的sortOptions

// This is the parent component where the 3 tables are implemented as 
// separate instances of <TopThings />

<template>
    ...
    <TopThings // this is the TopClicks implementation
        :sort-options="sortOptions.topClicks"
    />
    ...
    <TopThings // this is the TopImpressions implementation
        :sort-options="sortOptions.topImpressions"
    />
    ...
    <TopThings // this is the TopCTR implementation
        :sort-options="sortOptions.topCTR"
    />
    ...
</template>

<script>

components: {
    TopThings.vue,
},
data() {
    return {
        sortOptions: {
            topClicks: {
                enabled: true,
                initialSortBy: {field: 'clicks', type: 'desc'}
            },
            topImpressions: {
                ...
            },
            topCTR: {
                ...
            },
        },
    };
},

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM