Отфильтруйте таблицу в Vue

#javascript #vue.js #vuejs2

Вопрос:

Я пытаюсь создать приложение Vue, которое отображает ряд цитат и позволяет выполнять поиск по данным. Я думаю, что, возможно, я не привязываю функцию к нужному элементу. У меня есть атрибут v-модели на входном теге, так что он должен связывать любой текст, который вводит пользователь.

Вот мой шаблон:

 <template>
  <div class="container">
    <h3>Quotes</h3>
    <div class="controllers">
      <div class="search">
         <input id="search-item" type="text" placeholder="Search for a quote..." v-model="searchText"/>
         <button @click="searchResults()" class="search-btn">Search</button>
      </div>
    </div>
    <table class="table">
      <thead>
        <tr>
          <th scope="col">Source</th>
          <th scope="col">Context</th>
          <th scope="col">Quote</th>
          <th scope="col">Theme</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="quote in quotes" v-bind:key="quote.quote"> 
          <th scope="row">{{quote.context}}</th>
          <td>{{quote.source}}</td>
          <td>{{quote.quote}}</td>
          <td>{{quote.theme}}</td>
        </tr>
      </tbody>
    </table> 
  </div> 
</template>
 

Вот мой сценарий

   import axios from 'axios';
  export default {
    name: 'Quotes',
    data() {
      return {
        searchText: '',
        // search: null,
        // data: null,
        quotes: [ 
          {
            quote: null,
            context:  null,
            source: null,
            theme: null,
            currentPage: 0,
        }
        ],
      };
    },
    mounted() {
      axios
        .get('https://gist.githubusercontent.com/benchprep/dffc3bffa9704626aa8832a3b4de5b27/raw/quotes.json')
        .then(res => {
          this.quotes = res.data;
        })
      },
    methods: {
      searchResults() {
        if (this.searchText.length === 0) {
        return '';
      }
      return this.quotes.filter(quote => quote.quote.match(this.searchText));
     },
  }
}
 

Когда я пытаюсь реализовать поиск, функциональность не работает. Я не получаю никаких ошибок в компиляторе.

Комментарии:

1. searchText никогда не меняется для того, что я вижу, и v-model="filter" тоже не используется, я думаю, что ваша ошибка v-model="filter" в том, что это должно быть v-model="searchText"

2. Ах да, я вижу эту ошибку. Я только что изменил его v-model="searchText" , и я все еще не могу выполнить поиск по таблице.

Ответ №1:

Проблема связана с searchResults() функцией, потому что она только фильтрует this.quotes и возвращает это значение, но это значение не используется, поэтому объект this.quotes продолжает использовать начальные значения. Я бы посоветовал вам обновить функцию this.quotes при вызове функции searchResults() , но не забудьте сохранить первоначальные результаты.

Лучший способ для этого-использовать вычисляемую переменную, которая при необходимости возвращает this.кавычки, отфильтрованные. Смотрите в https://vuejs.org/v2/guide/computed.html#Computed-Properties

Ответ №2:

Ваш метод неверен, он должен быть:

     searchResults() {
        if (this.searchText.length == 0 || this.searchText == '') return;
        this.quotes = this.quotes.filter(quote => quote.quote.match(this.searchText));
    }
 

Вам это не нужно return this.quotes , вместо этого вы меняете массив. Но это приведет к очистке массива, поэтому вместо этого вы должны использовать другую переменную с исходным массивом.

Так будет лучше:

     import axios from 'axios';
    export default {
        data() {
            return {
                searchText: "",
                quotes: [],
                data: [],
            };
        },
        mounted() {
            this.fetchQuotes();
        },
        methods: {
            fetchQuotes() {
                let url = 'https://gist.githubusercontent.com/benchprep/dffc3bffa9704626aa8832a3b4de5b27/raw/quotes.json/';
                axios.get(url).then(res => {
                    this.quotes = res.data;
                    this.data = res.data;
                });
            },
            searchResults() {
                if (this.searchText.length == 0 || this.searchText == '') {
                    this.quotes = this.data;
                }
                this.quotes = this.data.filter(quote => quote.quote.includes(this.searchText));
            }
        }
    }
 

Комментарии:

1. Когда я пытаюсь назначить this.quotes this.data ничего не отображается на моей странице. Но он делает рендеринг без переназначения this.quotes

2. это странно, позвольте мне взглянуть на ваш код. Я провел тест на местном языке, и он работает.

3. fetchQuotes() { let url = 'https://gist.githubusercontent.com/benchprep/dffc3bffa9704626aa8832a3b4de5b27/raw/quotes.json/'; axios.get(url).then(res => { this.quotes = res.data; this.quotes = this.data; });

4. Вы можете отметить ответ, если это вам помогло 🙂

5. Пытался, но, очевидно, у меня недостаточно репутации, чтобы :/