根据TheMealDB API的List all meal categories可看到有很多餐点分类,不过这次用到那么多分类,所以等下会在data中定义会用到的餐点分类。
父组件MenusDetails.vue
<script>export default{ data(){ return{ mealCategory:[], categories:[ {type:'starter'}, {type:'chicken'}, {type:'beef'}, {type:'pork'}, {type:'seafood'}, {type:'pasta'}, {type:'lamb'}, {type:'goat'}, {type:'dessert'} ] } }, created(){ this.getMealData(this.categories[8]); }, methods:{ //get category data async getMealData(category){ const dataUrl = `https://www.themealdb.com/api/json/v1/1/filter.php?c=${category.type}`; try{ const response = await fetch(dataUrl); const data = await response.json(); this.mealCategory = data.meals; }catch(e){ console.log(e); } }, menuName(category){ this.getMealData(category); } }}</script>
1.fetch API:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://devhints.io/js-fetch
2.Async/Await:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://javascript.info/async-await
https://dmitripavlutin.com/javascript-fetch-async-await/
然后使用v-for在HTML中渲染出画面
<!-- menus details --><div class="menusdetails__content"> <div class="row"> <div class="col-1-of-3" v-for="meal in mealCategory" :key="meal.index"> <div class="card"> <div class="card__side"> <div class="card__img-box"> <img :src=meal.strMealThumb alt=""> </div> <h4 class="card__heading"> <span class="card__heading-span"> {{meal.strMeal}} </span> </h4> <div class="card__cta"> <a href="javascript:void(0);" :data-id=meal.idMeal class="btn btn--2" @click="getMealDetails($event)">get details</a> </div> </div> </div> </div> </div></div>
将get details按钮利用HTML5的自定义属性绑定每道餐点的id,让用户点进去后可看到餐点的详细材料,这边使用getMealDetails($event)方法根据每道餐点的id串接餐点材料的API
<script>export default{ data(){ return{ mealDetails:[], } }, methods:{ async getMealDetails(e){ let id = e.target.getAttribute('data-id'); const dataUrl = `https://www.themealdb.com/api/json/v1/1/lookup.php?i=${id}`; try{ const response = await fetch(dataUrl); const data = await response.json(); this.mealDetails = data.meals; }catch(e){ console.log(e); } } }}</script>
再将mealDetails的资料传到子组件Popup.vue即可
<template> ... <Popup :details="mealDetails"></Popup></template>
子组件Popup.vue
先在props设定接收父组件的details数据为Array,然后使用computed处理一下mealDetails资料里的strIngredient数据
<script>export default { props:{ details:Array }, computed:{ getIngredients(){ //console.log(this.details['strIngredient1']) return this.details.map(el => { //console.log(el.strIngredient1) let result = []; for(let i=1;i<=30;i++){ if(el[`strIngredient${i}`] == ''){ break; } result.push(el[`strIngredient${i}`]); } return result; }) } }}</script>
然后一样使用v-for在HTML上渲染出页面
<div class="popup__dialog" v-for="detail in details" :key="detail.id"> <a href="#" class="popup__close" @click="closePopup">×</a> <div class="popup__box"> <div class="popup__logobox"> <img class="popup__logo" :src=detail.strMealThumb :alt=detail.strMeal> </div> <div class="popup__text"> <h1 class="popup__heading"> {{detail.strMeal}} </h1> <h1 class="popup__heading"> Area:{{detail.strArea}} </h1> <h1 class="popup__heading"> Ingredient: </h1> <h1 class="popup__heading"> <p class="popup__heading" v-for="ingredient in getIngredients" :key="ingredient.index"> {{ingredient.toString()}} </p> </h1> </div> </div></div>
1.HTML5中的资料属性:https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
https://pjchender.blogspot.com/2017/01/html-5-data-attribute.html
2.Array.prototype.map():https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
参考资料:
1.TheMealDB API:https://www.themealdb.com/api.php
2.meal-search-api-vanilla-js:https://github.com/prabinmagar/meal-search-api-vanilla-js
3.Recipe-Catalogue:https://github.com/ampaire/Recipe-Catalogue