接上篇,vue项目美食杰菜谱大全实现

 效果图

分析:

 整体分为三大部分

1.先实现菜谱分类头部实现

    (1)先实现家常菜谱中华菜系和各地小吃的实现,通过后端获取到数据,渲染页面(2)再实现第一部中的每一项,获取数据渲染页面,实现局部功能

2.实现左边筛选中的功能

    (1)先实现工艺,口味,难度,人数,通过后端获取到数据,渲染页面(2)实现第一步中包含的每一项,获取数据渲染页面,实现局部功能

3.实现右边菜谱内容

 (1)通过后端拿到数据渲染页面(2)通过前两部分功能进行筛选,实现功能,筛选出结果有就渲染,没有就显示
暂时没有过滤到菜谱信息,请选择其他筛选条件(3)实现分页器中的功能,数据多的话就分页,点击前进后退,点击分页器数字也可以跳转

4.就这些功能(一步一步实现)

按照步骤来实现

首先先实现tab切换,通过后端api提供的getClassify()的方法然后通过.then()方法来异步获取数据
解析数据

getClassify().then(({data})=>{console.log(data)//打印一下data,看看里面的数据`在这里插入代码片`});


获取到这些数据,先用一个空数组储存获取到的数据

data() {return {classify:[],//存储tab切换的所有数据}},mounted() {getClassify().then(({data})=>{console.log(data)this.classify = data;});
}

数据赋值给空数组然后逐步渲染

<el-tab-panev-for="item in classify":key="item.parent_type":label="item.parent_name":name="item.parent_type"
>
</el-tab-pane>

v-for遍历一下calssify渲染数据用到v-for一定要绑定key值(这里的key值是唯一的)label就是title值,渲染到页面上

渲染页面后,这个tab切换是Element ui插件中封装的方法

接下来实现家常菜谱,中华菜系,各地小吃 中的每一项中的数据

渲染

 <div class="recipe-link"><router-link:to="{query:{...$router.query,classify:option.type,page:1}}"v-for="option in item.list":key="option.type":class="{active:classifyType === option.type}">{{option.name}}</router-link></div>

储存classifyType:“1-1”,动态绑定to是为了拼接二级路由

data() {return {classify:[],//存储tab切换的所有数据classifyType:"1-1",//tab切换的选中项(二级路由)classifyName:"1",//定义刷新tab时的值(一级路由)}
},
watch: {$route: {handler(){const {classify} = this.$route.query;if(classify){this.classifyType = classify;//1-1this.classifyName = classify[0]; //1}},immediate:true}
},
mounted() {getClassify().then(({data})=>{console.log(data)this.classify = data;if(!this.$route.query.classify){this.classifyType = this.classify[0].list[0].type;//1-1this.classifyName = this.classify[0].parent_type; //1this.$router.push({query:{classify: this.classifyType,page:1}})}});
}


判断点击的时候路由添加
监听一级路由和二级路由切换哪个路由就渲染哪点数据

接着第二部分实现

跟上边实现一样通过后端api提供的getProperty()的方法然后通过.then()方法来异步获取数据

getProperty().then(({data})=>{console.log(data);this.properties = data;
});

赋值properties 储存数据

data() {return {classify:[],//存储tab切换的所有数据classifyType:"1-1",//tab切换的选中项(二级路由)classifyName:"1",//定义刷新tab时的值(一级路由)//属性properties:[],//存储属性中的所有数据}
},

渲染

<el-collapse  v-model="propertyActiveName"><el-collapse-itemv-for="item in properties":key="item.parent_type":title="item.parent_name":name="item.parent_type"></el-collapse-item>
</el-collapse>

v-for遍历一下properties渲染数据用到v-for一定要绑定key值(这里的key值是唯一的):title就是title值,渲染到页面上

接下来实现 工艺,口味,难度,人数中每一项中的数据

跟上边一样,直接拿数据渲染

<div class="filter-tags"><el-tag type="info"v-for="option in item.list":key="option.type"@click="selectedTag(option)":class="{'tag-selected': propertyType[item.title] === option.type}">{{option.name}}</el-tag>
</div>

其中添加点击有颜色,字体颜色也改变了

mounted() {getProperty().then(({data})=>{// console.log(data);this.properties = data;const {query} = this.$route;this.propertyType = this.properties.reduce((o,item)=>{//  item.title :  工艺,难度,口味,人数o[item.title] = query[item.title] ? query[item.title]: "";if(o[item.title]){this.propertyActiveName.push(o[item.title][0]);}return o;},{});});
},
methods: {selectedTag(option){let query = {...this.$route.query};//判断是否点击,如果点击过,取消,否则,选中if(this.propertyType[option.title] === option.type){this.propertyType[option.title] = "";delete query[option.title];}else{this.propertyType[option.title] = option.type;query[option.title] = option.type;}this.$router.push({query})},}

判断是否点击点击过就取消删除地址栏中的路由,没点击过就选中

$router.push( ) 一下路由,反出路由

接着

判断下拉里边是否有数据,有就刷新不掉,没有就自动闭合

接着写右侧列表

右边列表整体代码

<el-main class="filter-menus-box"><div class="menu-empty" v-show="!list.length && !loading">暂时没有过滤到菜谱信息,请选择其他筛选条件</div><!-- 作品展示 --><menu-card style="min-height: 75%;" :info="list"></menu-card><!-- 分页展示 --><div style="text-align: right;" v-show="!loading"><el-paginationstyle="display: inline-block;":page-size="5"layout="total, prev, pager, next":total="total":current-page.sync="page"@current-change="handlerSelect":hide-on-single-page="true"></el-pagination></div>
</el-main>

先写作品展示
是通过组件写的
首先
先把数据放到页面上
后端获取数据自定义一个方法然后定义空数组,渲染页面total设置为1,current_page设置为1(注意一定要是数字类型),然后接收值

ThisgetMenus(){const query = {...this.$route.query}const params = {page:query.page || 1,classify:query.classify}delete query.pagedelete query.classifyif(Object.keys(query).length){params.property={...query}}//请求右侧的数据getMenus(params).then(({data}) =>{// console.log(data);if(this.loading) loading.close();this.loading = false;this.list = data.list;this.total = data.total;this.page = data.current_page;})
},

渲染到页面,":page-size=‘5’"是当前页面显示,每一页都有5个数据,多了,在写一页显示

然后watch监听一下页面数切换以及跟随更新

watch: {$route: {handler(){const {classify,page} = this.$route.query;if(classify){this.classifyType = classify;//1-1this.classifyName = classify[0]; //1this.page = Number(page);}this.ThisgetMenus();},immediate:true}
},

遮盖层设置,在data中设置loading值为false,false是隐藏,当为true的时候显示,所以在调用他之前需要把loading改为true

ThisgetMenus(){this.loading = true;let loading = null;// 遮罩层this.$nextTick(()=>{loading = this.$loading({target:'.filter-menus-box',text:"Loading...",spinner:"el-icon-loading",background:'rgba(0,0,0,0.7)'})});
},

加载的时候让原来的数据也隐藏清一下原来的数据this.list = [];

ThisgetMenus(){this.list = [];
},

效果

基本效果就是这样了
按照步骤一步一步操作,就可以实现了
整体代码:

<template><div class="recipe"><!-- 菜谱分类 start --><el-tabstype="border-card"v-model="classifyName"@tab-click="tabClick"><el-tab-panev-for="item in classify":key="item.parent_type":label="item.parent_name":name="item.parent_type"><div class="recipe-link"><router-link:to="{query:{...$router.query,classify:option.type,page:1}}"v-for="option in item.list":key="option.type":class="{active:classifyType === option.type}">{{option.name}}</router-link></div></el-tab-pane></el-tabs><!-- 菜谱分类 end --><h2>家常好味道,给你家一般的温暖</h2><el-container><!-- 左侧列表 --><el-aside width="220px" class="recipe-aside"><div class="filter-box"><h4>筛选</h4><el-collapse  v-model="propertyActiveName"><el-collapse-itemv-for="item in properties":key="item.parent_type":title="item.parent_name":name="item.parent_type"><div class="filter-tags"><el-tag type="info"v-for="option in item.list":key="option.type"@click="selectedTag(option)":class="{'tag-selected': propertyType[item.title] === option.type}">{{option.name}}</el-tag></div></el-collapse-item></el-collapse></div></el-aside><!-- 右侧列表 --><el-main class="filter-menus-box"><div class="menu-empty" v-show="!list.length && !loading">暂时没有过滤到菜谱信息,请选择其他筛选条件</div><!-- 作品展示 --><menu-card style="min-height: 75%;" :info="list"></menu-card><!-- 分页展示 --><div style="text-align: right;" v-show="!loading"><el-paginationstyle="display: inline-block;":page-size="5"layout="total, prev, pager, next":total="total":current-page.sync="page"@current-change="handlerSelect":hide-on-single-page="true"></el-pagination></div></el-main></el-container></div>
</template>
<script>import MenuCard from '@/components/menu-card.vue'import {getClassify, getProperty, getMenus} from '@/service/api';export default {components: {MenuCard},data() {return {classify:[],//存储tab切换的所有数据classifyType:"1-1",//tab切换的选中项(二级路由)classifyName:"1",//定义刷新tab时的值(一级路由)//属性properties:[],//存储属性中的所有数据propertyType:{},//存储属性的分类propertyActiveName:[],//记录所有的属性分类list:[],//存储右侧主题total:0,//总页数loading:false,//是否显示遮罩层page:1}},watch: {$route: {handler(){const {classify,page} = this.$route.query;if(classify){this.classifyType = classify;//1-1this.classifyName = classify[0]; //1this.page = Number(page);}this.ThisgetMenus();},immediate:true}},mounted() {getClassify().then(({data})=>{console.log(data)this.classify = data;if(!this.$route.query.classify){this.classifyType = this.classify[0].list[0].type;//1-1this.classifyName = this.classify[0].parent_type; //1this.$router.push({query:{classify: this.classifyType,page:1}})}});getProperty().then(({data})=>{// console.log(data);this.properties = data;const {query} = this.$route;this.propertyType = this.properties.reduce((o,item)=>{//  item.title :  工艺,难度,口味,人数o[item.title] = query[item.title] ? query[item.title]: "";if(o[item.title]){this.propertyActiveName.push(o[item.title][0]);}return o;},{});});},methods: {selectedTag(option){let query = {...this.$route.query};//判断是否点击,如果点击过,取消,否则,选中if(this.propertyType[option.title] === option.type){this.propertyType[option.title] = "";delete query[option.title];}else{this.propertyType[option.title] = option.type;query[option.title] = option.type;}this.$router.push({query})},ThisgetMenus(){const query = {...this.$route.query}const params = {page:query.page || 1,classify:query.classify}delete query.pagedelete query.classifyif(Object.keys(query).length){params.property={...query}}this.loading = true;let loading = null;// 遮罩层this.$nextTick(()=>{loading = this.$loading({target:'.filter-menus-box',text:"Loading...",spinner:"el-icon-loading",background:'rgba(0,0,0,0.7)'})});this.list = [];//请求右侧的数据getMenus(params).then(({data}) =>{// console.log(data);if(this.loading) loading.close();this.loading = false;this.list = data.list;this.total = data.total;this.page = data.current_page;})},//点击改变当前页handlerSelect(){// console.log(this.page)this.$router.push({query:{...this.$route.query,page:this.page}})},tabClick(){const classifyName = this.classifyNameconst item = this.classify.find(item => item.parent_type === classifyName);// console.log(item)//item 是当前被点击到的一级路由(整体路由)if(item){this.classifyName = item.parent_type//一级路由的typethis.classifyType = item.list[0].type;this.$router.push({query:{...this.$route.query,classify:this.classifyType}})}}}}
</script>
<style lang="stylus">.recipe-linkfont-size 0;margin-top 5pxadisplay inline-blockfont-size 12pxpadding 0px 8pxheight 28pxline-height 28px.activebackground #ff3232color #fff.recipeh2text-align centerline-height 150px.el-mainpadding 0.filter-boxbackground #fffpadding 10pxwidth 100%float leftbox-sizing border-box.filter-tagsdisplay flexflex-wrap wrapjustify-content space-around.tag-selectedbackground-color #ff3232 !importantcolor #fff !important.menu-emptywidth 100%text-align centerfont-size 20px
</style>

以上就是这页的整体代码了
总结:
写的时候一定要注意page值必须为Number类型,否则会一直报错,可以在这强行转为Number类型,要懂得分析,其实上边和下边的实现效果是一样的,都是通过后端提供的数据,拿到之后获取数据渲染到页面上,然后再一步一步实现效果,
每天及时更新项目,喜欢的话,点赞,关注,收藏。

vue项目美食杰菜谱大全实现(二)相关推荐

  1. vue项目美食杰菜谱大全实现(三)

    接上篇,vue项目美食杰菜谱大全已经实现,今天来说一下菜单详情的实现 分析: 这个菜单详情页面,考验的知识很少,基本都是拿数据渲染 分为4大部分,四个组件: 1.detail: detail组价: 根 ...

  2. vue项目美食杰--菜谱大全

    项目已经接近尾声了,难度也随之增加,不过,世上无难事,只要肯登攀,遇到困难,打倒它,然后在遇到更大的困难..当然了,在这个过程中我们的技术和心理素质也会逐步的提高..今天分享一个小小难度的部分,菜谱大 ...

  3. vue项目美食杰菜谱大全实现

    效果图 分析 1.先实现菜谱分类头部实现 (1)先实现家常菜谱中华菜系和各地小吃的实现 (2)再实现第一部中的每一项 2.实现左边筛选中的功能 (1)先实现工艺,口味,难度,人数 (2)实现第一步中包 ...

  4. 美食杰----菜谱大全(二)

    这篇文章接着续写上一篇菜谱大全,这篇文章主要写的是右边的侧栏部分. 一.思路:1.首先布局,要用到Element Ui组件来布局. 2.然后从后端获取数据. 3.将调用到的数据进行解构,再创建个空数组 ...

  5. 美食杰-菜谱大全(一)

    一,效果展示 二,效果概要 tab切换 获取api中的数据 点击换css样式 渲染页面 三,技术要求 熟悉element组件库 掌握vue-cli脚手架 掌握vue-router路由 掌握vuex库 ...

  6. vue项目美食杰 -- 发布菜谱

    不知不觉间,vue美食杰项目已经实现了很多了,我都有点始料未及呢,今天进行的部分呢,是项目中的发布菜谱功能,在这个页面中,我们会学习到前后端的交互,Element-ui的使用等等... 先看下效果图: ...

  7. 美食杰----菜谱大全

    今天我们来写美食杰的菜谱大全页面,首先要讲的是实现这个页面的流程: 拿到数据----渲染数据----监听路由传参----判断----写点击事件 1.在api里面拿到数据getClassify, get ...

  8. 美食杰-菜谱大全右侧主体

    根据用户的选择,展示不同的数据 分页 在data中定义需要的数组 data() {return {classify: [],property: [],propertype: {}, //存储分类的属性 ...

  9. 美食杰--------菜谱大全

    话不多说,直接看效果图: HTML: <template><div class="recipe"><!-- v-model="activeN ...

最新文章

  1. 对python源码进行编译,加密python脚本
  2. 手机淘宝以秒杀抢滩校园市场
  3. java 继承练习题_Java继承 练习题
  4. 获取计算机的信息(IP地址、MAC地址、CUP序列号、硬盘序列号、主板信息等等)...
  5. java List实体排序
  6. 2018 ICPC Asia Jakarta Regional Contest J. Future Generation 状压dp
  7. idea 分支管理插件_Git的分支管理常用命令
  8. 学习生物信息的系列书籍
  9. 生鲜电商/社区团购/团长中心、地址管理、自提点、订单列表、限时折扣、预售、会员储值、钱包、同城配送、门店自提、团长自提、采购、履约、仓储、运输、财务、移动端电商原型、rp源文件、axure电商原型
  10. VsCode配置Python开发环境后运行代码会报错“无法加载文件 D:\Code\xxx\poetry-demo\.venv\Scripts\Activate.ps1”
  11. 制作种子怎么上传服务器,怎么制作BT种子 使用BitComet制作BT种子文件教程
  12. PS-elevenday-铅笔工具(颜色替换)
  13. Hive函数collect_set、concat_ws、concat、if
  14. 三极管NPN和PNP导通条件
  15. 学信认证使用Jetbrains教育授权方式
  16. java小球挡板游戏_多线程的一个小球游戏,就是以前的那个Pong游戏
  17. 项目总是延期令人头疼?Tracup帮你做好项目进度管理
  18. cba篮球暂停次数和时间_篮球比赛一节有几次暂停?
  19. 图片过大怎么办?如何把图片压缩到最小
  20. IT运维服务外包管理的两种模式

热门文章

  1. vc2010更改项目名称
  2. 我的世界观-2-适者生存的物质原理
  3. 数据结构笔记(2)——二叉树基本算法大全
  4. 链表的基本操作(C)
  5. C语言(数据结构) - 链表的基本操作
  6. arm9260 linux编译,at91sam9260 开发环境的建立
  7. macbook系统占用硬盘大_mac系统占用磁盘80g相关阅读-mac系统占用磁盘80g文章阅读-123文学网...
  8. 编程之路第12天:帮你是情分,不帮你是本分,说得真太对了
  9. Vben Admin 二(登录页)
  10. 婚姻的幸福感在哪?还有吗?