Поиск конкретных данных в vue b-таблице из axios API

#javascript #vue.js #axios #nuxt.js #bootstrap-vue

Вопрос:

Я создал b-таблицу, в которой хранятся все данные из API, которые были получены из пользовательского интерфейса Swagger, так как там много данных, которые я хотел, чтобы кнопка поиска в верхней части страницы работала правильно, введя код магазина или веткуПо умолчанию Как реализовать фильтр для таблицы, чтобы кнопка поиска работала так, как должна быть? Заранее спасибо, вот пик моего кода (я уже пытался создать фильтр для кода магазина, но, похоже, это не работает?

 <script>
// eslint-disable-next-line no-unused-vars
import { getAllProvinces } from '~/api/delivery'
export default {
  data() {
    return {
      perPage: 0,
      currentPage: 1,
      rows: 0,

      items: [],

      fields: [
        {
          key: 'id',
          sortable: true,
          label: 'ID',
          class: 'truncate',
        },
        {
          key: 'uploadReference',
          sortable: true,
          label: 'Upload Reference',
          class: 'truncate',
        },
        {
          key: 'requestId',
          sortable: true,
          label: 'Request ID',
          class: 'truncate',
        },
        {
          key: 'storeCode',
          sortable: true,
          label: 'Store Code',
          class: 'truncate',
        },
        {
          key: 'branchCode',
          sortable: true,
          label: 'Branch Code',
          class: 'truncate',
        },
        {
          key: 'b2bId',
          sortable: true,
          label: 'B2B ID',
          class: 'truncate',
        },
        {
          key: 'request',
          sortable: true,
          label: 'Request',
          class: 'truncate',
        },
        {
          key: 'response',
          sortable: true,
          label: 'Response',
          class: 'truncate',
        },
        {
          key: 'createDate',
          sortable: true,
          label: 'Create Date',
          class: 'truncate',
        },
        {
          key: 'errorClassification',
          sortable: true,
          label: 'Error Classification',
          class: 'truncate',
        },
      ],
    }
  },
  computed: {},

  watch: {
    currentPage: {
      handler(value) {
        this.getAllStock()
      },
      search() {
        const data = this.items
        if (this.search.length > 0) {
          if (data.filter((item) => item.storeCode === this.search)) {
            this.items = data.filter((item) => item.storeCode === this.search)
          } else {
            this.search = ''
            this.getAllStock()
          }
        } else {
          this.getAllStock()
        }
      },
    },
  },
  // components: {
  // },
  created() {
    this.getAllStock()
  },

  mounted() {
    this.getAllStock()
  },
  methods: {
    getAllStock() {
      this.$axios
        .get(
          'http://swaggerlinkhere?requestPage='  
            this.currentPage  
            'amp;status=1'
        )

        .then((res) => {
          // eslint-disable-next-line no-console
          console.log(res.data)
          this.items = res.data.stocks
          this.allStock = res.data
          this.rows = res.data.totalDocuments
          // eslint-disable-next-line no-console
          // console.log('cek res stock:', JSON.stringify(res.data))
        })
    },
  },
}
</script> 
 <style>
.truncate {
  max-width: 190px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style> 
 <template>
      <div>
        <b-form inline>
          <label for="status">Status⠀⠀⠀⠀ :</label>
          <div class="col-sm-2">
            <b-form-input text></b-form-input>
          </div>
          <div class="branch">
            <div class="col-lg-10 text-right">
              <b-form inline label-align-sm="right" style="margin-left: 70px">
                <div class="col-sm-2" label for="branch">Branch⠀:</div>
                <div class="col-sm-8">
                  <b-form-input text style="margin-left: 33px"></b-form-input>
                </div>
                <br />
              </b-form>
            </div>
          </div>
        </b-form>
      </div>
      <div>
        <b-form inline>
          <label for="storecode">Store Code⠀:</label>
          <div class="col-sm-2">
            <b-form-input text></b-form-input>
          </div>
          <div class="branch">
            <div class="col-lg-12 text-right">
              <b-form inline label-align-sm="right">
                <div class="input-group col-sm-10">
                  <b-button
                    v-model="search"
                    variant="dark"
                    style="margin-left: 205px; margin-top: 5px"
                    >Search</b-button
                  >
                </div>
              </b-form>
            </div>
          </div>
        </b-form>
      </div>
      <br />
      <br />
      <b-card body>
        <b-card-header class="border-0">
          <h3 class="mb-0">Stock List</h3>
        </b-card-header>
        <template>
          <p class="mt-3">Current Page: {{ currentPage }}</p>
          <div class="text-center">
            <b-table
              id="my-table"
              responsive
              dark
              striped
              hover:true
              :items="items"
              :fields="fields"
              :per-page="0"
              :current-page="currentPage"
            >
              <template v-slot:cell()="data">
                <span v-b-tooltip.hover :title="data.value">{{
                  data.value
                }}</span>
              </template>
            </b-table>
          </div>
        </template>
        <div class="overflow-auto">
          <b-card-footer class="py-4 d-flex justify-content-end">
            <b-pagination
              v-model="currentPage"
              :total-rows="rows"
              :per-page="perPage"
              aria-controls="my-table"
            ></b-pagination>
          </b-card-footer>
        </div>
      </b-card>
    </template> 

Ответ №1:

Вы можете использовать фильтр таблицы начальной загрузки как для кода состояния, так и для кода филиала.

 var app = new Vue({
  el: '#app',
  data() {
        return {
            filter: null,
            filterOn: [],
            perPage: 0,
            currentPage: 1,
            rows: 0,
            items: [],
            fields: [{
                    key: 'id',
                    sortable: true,
                    label: 'ID',
                    class: 'truncate',
                },
                {
                    key: 'uploadReference',
                    sortable: true,
                    label: 'Upload Reference',
                    class: 'truncate',
                },
                {
                    key: 'requestId',
                    sortable: true,
                    label: 'Request ID',
                    class: 'truncate',
                },
                {
                    key: 'storeCode',
                    sortable: true,
                    label: 'Store Code',
                    class: 'truncate',
                },
                {
                    key: 'branchCode',
                    sortable: true,
                    label: 'Branch Code',
                    class: 'truncate',
                },
                {
                    key: 'b2bId',
                    sortable: true,
                    label: 'B2B ID',
                    class: 'truncate',
                },
                {
                    key: 'request',
                    sortable: true,
                    label: 'Request',
                    class: 'truncate',
                },
                {
                    key: 'response',
                    sortable: true,
                    label: 'Response',
                    class: 'truncate',
                },
                {
                    key: 'createDate',
                    sortable: true,
                    label: 'Create Date',
                    class: 'truncate',
                },
                {
                    key: 'errorClassification',
                    sortable: true,
                    label: 'Error Classification',
                    class: 'truncate',
                },
            ],
        }
    },
    watch: {
        currentPage: {
            handler(value) {
                this.getAllStock()
            },
        },
    },
    methods: {
        getAllStock() {
            this.$axios
                .get(
                    'http://swaggerlinkhere?requestPage='  
                    this.currentPage  
                    'amp;status=1'
                )

                .then((res) => {
                    // eslint-disable-next-line no-console
                    console.log(res.data)
                    this.items = res.data.stocks
                    this.allStock = res.data
                    this.rows = res.data.totalDocuments
                    // eslint-disable-next-line no-console
                    // console.log('cek res stock:', JSON.stringify(res.data))
                })
        },
        onFiltered(filteredItems) {
            this.rows = filteredItems.length
            this.currentPage = 1
        },
    },
    created() {
        this.getAllStock()
    },
}) 
 <template>
    <div>
        <div>
            <b-form inline>
                <label for="status">Status:</label>
                <div class="col-sm-2">
                    <b-form-input text></b-form-input>
                </div>
                <b-col lg="6" class="my-1">
                    <b-form-group label="Filter" label-for="filter-input" label-cols-sm="3" label-align-sm="right" label-size="sm" class="mb-0">
                        <b-input-group size="sm">
                            <b-form-input id="filter-input" v-model="filter" type="search" placeholder="Type to Search"></b-form-input>
                            <b-input-group-append>
                                <b-button :disabled="!filter" @click="filter = ''">Clear</b-button>
                            </b-input-group-append>
                        </b-input-group>
                    </b-form-group>
                </b-col>
                <b-col lg="6" class="my-1">
                    <b-form-group label="Filter On" description="Leave all unchecked to filter on all data" label-cols-sm="3" label-align-sm="right" label-size="sm" class="mb-0">
                        <b-form-checkbox-group v-model="filterOn" class="mt-1">
                            <b-form-checkbox value="branchCode">Branch Code</b-form-checkbox>
                            <b-form-checkbox value="storeCode">store Code</b-form-checkbox>
                        </b-form-checkbox-group>
                    </b-form-group>
                </b-col>
            </b-form>
        </div>
        <br/>
        <br/>
        <b-card body>
            <b-card-header class="border-0">
                <h3 class="mb-0">Stock List</h3>
            </b-card-header>
            <template>
                        <p class="mt-3">Current Page: {{ currentPage }}</p>
                        <div class="text-center">
                            <b-table id="my-table" :per-page="perPage" :current-page="currentPage" small striped hover responsive show-empty :items="items" :fields="fields" :filter="filter" :filterIncludedFields="filterOn" @filtered="onFiltered">
                            </b-table>
                        </div>
        </template>
            <div class="overflow-auto">
                <b-card-footer class="py-4 d-flex justify-content-end">
                    <b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" aria-controls="my-table"></b-pagination>
                </b-card-footer>
            </div>
        </b-card>
    </div>
</template> 

Ответ №2:

Если я вас правильно понимаю, попробуйте сделать что-то вроде этого

 var app = new Vue({
  el: '#app',
  data: {
    rawItems:["one", "two", "three", "foo", "bar"],
    searchText:"",
    filteredItems:[]
  },
  mounted: function() {
    this.filteredItems = this.rawItems
  },
  methods: {
    onSearchClick: function () {
      this.filteredItems = this.rawItems.filter(v=>v.indexOf(this.searchText)>=0)
    }
  }
}) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <p>
    <input v-model="searchText">
    <button @click="onSearchClick">Search</button>
  </p>

<p>{{filteredItems}}</p>
</div>