Vue在input时searchAjax响应数组
我试图过滤一个列表,当input到我从Ajax调用中获得的文本框。 问题似乎是在Ajax准备好之前应用filter。
HTML:
<input type="text" class="form-control" v-model="searchTerm"> <table> <tr v-for="food in filteredItems"> <td>{{ food.name }}</td> <td>{{ food.energy }}</td> </tr> </table>
助手/ index.js:
export default { getFoods() { return Vue.http.get('http://localhost:3000/foods/allfoods') .then((response) => { return response.data; }); } }
Vue组件:
import helpers from '../helpers' export default { name: 'Search', mounted() { helpers.getFoods().then((response) => { this.foodData = response; }); }, data() { return { searchTerm: '', foodData: [], } }, computed: { filteredItems() { return this.foodData.filter(function(food){return food.name.toLowerCase().indexOf(this.searchTerm.toLowerCase())>=0;}); } }
当我加载页面或开始input我得到
'TypeError:undefined不是一个对象(评估'this.searchTerm')'。
如果我对foodData数组进行硬编码,一切都可以正常工作。
我误解了一些事情和/或我做错了什么?
在计算filter函数的callback中, this
不是指向Vue。
computed: { filteredItems() { return this.foodData.filter(function(food){ // in this next line, this.searchTerm is likely undefined // because "this" is not the Vue return food.name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) >= 0; }); } }
这是因为你使用function(food){...}
作为你的callbackfunction(food){...}
, this
将是包含范围。 相反,使用箭头函数,闭包或bind
。
computed: { filteredItems() { return this.foodData.filter(food => { // in this next line, this.searchTerm is likely undefined // because "this" is not the Vue return food.name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) >= 0; }); } }
console.clear() const foods = [{ name: "orange", energy: 10 }, { name: "apple", energy: 8 }, { name: "banana", energy: 12 }, { energy: 1000 } ] const Search = { name: 'Search', template: ` <div> <input type="text" class="form-control" v-model="searchTerm"> <table> <tr v-for="food in filteredItems"> <td>{{ food.name }}</td> <td>{{ food.energy }}</td> </tr> </table> </div> `, mounted() { setTimeout(() => this.foodData = foods, 500) }, data() { return { searchTerm: '', foodData: [], } }, computed: { filteredItems() { const searchTerm = this.searchTerm.toLowerCase() return this.foodData .filter(food => food.name && food.name.toLowerCase().includes(searchTerm)) } } } new Vue({ el:"#app", components: {Search} })
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script> <div id="app"> <search></search> </div>