Estoy tratando de crear una aplicación Vue que genere una serie de cotizaciones y le permita buscar a través de los datos. Creo que tal vez no estoy vinculando la función al elemento correcto. Tengo un atributo de modelo v en la etiqueta de entrada, por lo que debería vincular cualquier texto que ingrese un usuario.
Aquí está mi plantilla:
<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>Aquí está mi guión
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)); }, } }Cuando intento implementar una búsqueda, la funcionalidad no funciona. No recibo ningún error en el compilador.
Su método es incorrecto, debería ser:
searchResults() { if (this.searchText.length == 0 || this.searchText == '') return; this.quotes = this.quotes.filter(quote => quote.quote.match(this.searchText)); } No necesita return this.quotes , cambia la matriz en su lugar. Pero esto hará que se vacíe la matriz, por lo que en su lugar debe usar otra variable con la matriz original.
Esta es mejor:
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)); } } }El problema está en la función searchResults() porque solo está filtrando this.quotes y devuelve este valor, pero este valor no se usa, por lo que el objeto this.quotes continúa con los valores iniciales. Le sugiero que actualice this.quotes cuando llame a la función searchResults() pero recuerde guardar los resultados iniciales.
La mejor manera de hacerlo es usar una variable calculada que devuelva this.quotes filtrada cuando sea necesario. Ver en https://vuejs.org/v2/guide/computed.html#Computed-Properties