美食杰-菜谱大全(二)

一,效果展示

 

 

二,效果概要 

        1.数据渲染

        2.页码数

        3.条数

        4.遮盖层

三,技术掌握

        1.熟悉element组件库

        2.掌握vue-cli脚手架

        3.掌握vue-router路由

        4.掌握vuex库

        5.vue中v-for的使用

        6.vscode编辑器

四,实现效果

1.首先是渲染数据,通过调用后台给的接口用.then方法异步操作拿到data数据,在data中设置list空数组,total设置为1,current_page设置为1(注意一定要是数字类型),然后接收值

getMenus(params).then(({data}) =>{
                    console.log(data);
                    // this.loading = true
                    if(this.loading) loading.close();
                    this.loading = false
                    this.list = data.list;
                    this.total = data.total;
                    this.page = data.current_page;
                    
                })

2.渲染到页面,":page-size='5'"是当前页面显示

<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-pagination
                            style="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>

3.页面数切换以及跟随更新

handlerSelect(){
                
                this.$router.push({
                    query:{
                        ...this.$route.query,
                        page:this.page
                    }
                })
            },

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

 this.$nextTick(() =>{
                    loading = this.$loading({
                        target:'.filter-menus-box',
                        text:'Loading...',
                        spinner:'el-icon-loading',
                        background:'rgba(0,0,0,0.7)'
                    })
                })

5.由于在点击切换的时候原数据还在,所以在loading之前还需要把list中的数据情况,即this.list=[];然后由于loading再切换的时候会一直显示,因为我们在前边把loading改为了true的原因,所以需要在数据加载成功时把loading改为false

6.懒人操作,下边是整体代码

<template>
    <div class="recipe">
        <!-- 菜谱分类 start -->
        <el-tabs  type="border-card"
                  v-model="classifyName"
                  @tab-click = "tabClick"
        >
            <el-tab-pane 
                    v-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>
                    <!-- v-model="activeName" -->
                    <!-- 筛选 start -->
                    <el-collapse  v-model="propertyActiveName">
                        <el-collapse-item
                                v-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>
                    <!-- 筛选 end -->
                </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-pagination
                            style="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-1
                        this.classifyName = classify[0]; //1
                        this.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-1
                    this.classifyName = this.classify[0].parent_type; //1
                    this.$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.page
                delete query.classify
                if(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);
                    // this.loading = true
                    if(this.loading) loading.close();
                    this.loading = false
                    this.list = data.list;
                    this.total = data.total;
                    this.page = data.current_page;
                    
                })
            },
            //点击改变当前页
            handlerSelect(){
                
                this.$router.push({
                    query:{
                        ...this.$route.query,
                        page:this.page
                    }
                })
            },
            tabClick(){
                const classifName = this.classifyName
                const item = this.classify.find(item => item.parent_type === classifName);
                //item 是被点击到的 一级路由整体(整体数据)
                if(item){
                    this.classifyName = item.parent_type; //一级路由的type
                    this.classifyType = item.list[0].type;
                    this.$router.push({
                        query:{
                            ...this.$route.query,
                            classify: this.classifyType,
                        }
                    })
                }
            }
        }
    }
</script>

<style lang="stylus">
    .recipe-link
        font-size 0;
        margin-top 5px

        a
            display inline-block
            font-size 12px
            padding 0px 8px
            height 28px
            line-height 28px

        .active
            background #ff3232
            color #fff

    .recipe
        h2
            text-align center
            line-height 150px

        .el-main
            padding 0

        .filter-box
            background #fff
            padding 10px
            width 100%
            float left
            box-sizing border-box

    .filter-tags
        display flex
        flex-wrap wrap
        justify-content space-around

        .tag-selected 
            background-color #ff3232 !important
            color #fff !important

    .menu-empty
        width 100%
        text-align center
        font-size 20px
</style>

五,注意事项

1.page值必须为Number类型,否则会一直报错,可以在这强行转为Number类型

 六,总结

  • 本文讲了美食杰菜谱大全功能的实现,整篇结束,界面的布局介绍,如果您还有更好地理解,欢迎沟通
  • 定位:分享 &知识点,有兴趣可以继续关注 vue.js  html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值