1

效果实现

由导航进入的食物列表页:

image.png
menu分为分类、排序、筛选3部分。

1.分类效果:

image.png
点击展开,在展开状态下点击隐藏。
结构:

<div class="food_container">
    <head-top :head-title="headTitle" goBack="true"></head-top>
    <!--分类/排序/筛选-->
    <section class="sort_container">
        <!--分类 sortBy=='food'的类型,控制对应detail项的展开或隐藏
        sortBy置为空的时候点击收起,sorBy值为"food"时点击展示food对应项-->
        <div class="sort_item" :class="{choose_type:sortBy=='food'}">
            <!--标题,点击触发chooseType控制内容的隐藏和显示-->
            <div class="sort_item_container" @click="chooseType('food')">
                <div class="sort_item_border">
                    <!--标题-->
                    <span :class="{category_title:sortBy=='food'}">
                        {{foodTitle}}
                    </span>
                    <!--绘制下拉箭头-->
                     <svg
                      width="10"
                      height="10"
                      xmlns="http://www.w3.org/2000/svg"
                      version="1.1"
                      class="sort_icon"
                     >
                        <polygon points="0,3 10,3 5,8" />
                     </svg>
                </div>
            </div>
            <!--内容项 category为拿到的数据,拿到分类数据后执行-->
            <transition name="showlist" v-show="category">
                <!--sortBy有值时展示,sorBy为空时隐藏-->
                <section v-show="sortBy=='food'">
                    <!--第一项展开的内容分为两部分-->
                    <!--左侧分类条目 s-->
                    <section class="category_left">
                        <ul>
                            <!--点击左侧menu,传入当前项id和当前项在list中的位置
                            在右侧筛选详情部分展示与index对应的sub_categories-->
                            <li v-for="(item,index) in category"
                  :key="index"
                  class="category_left_li"
                  :class="{category_active:restaurant_category_id==item.id}"
                  @click="selectCategoryName(item.id,index)">
                                <!--图标名字-->
                                <section>
                                    <img :src="getImgPath(item.image_url)"  v-if="index"
                                    class="category_icon"/>
                                    <span>{{item.name}}</span>
                                </section>
                                <!--数量-->
                                <section>
                                    <span class="category_count">{{item.count}}</span>
                                    <!--绘制向右侧的小箭头-->
                                    <svg
                                      v-if="index"
                                      width="8"
                                      height="8"
                                      xmlns="http://www.w3.org/2000/svg"
                                      version="1.1"
                                      class="category_arrow"
                                    >
                                    <path d="M0 0 L6 4 L0 8" stroke="#bbb" stroke-width="1" fill="none" />
                                    </svg>
                                </section>
                            </li>
                        </ul>
                    </section>
                    <!--左侧分类条目 e-->
                    <!--右侧展示条目 s-->
                    <section class="category_right">
                        <ul>
                        <!--点击右侧具体筛选项,传入该项name值,id值。name值为替换“分类”文字
                        进行筛选
                        category_right_choosed:选中状态,初始状态index=0,restaurant_category_ids选中;点击时restaurant_category_ids == item.id
                        选中;
                        -->
                            <li v-for="(item,index) in categoryDetail"
                                v-if="index" :key="index" class="category_right_li"
                                 @click="getCategoryIds(item.id, item.name)"
                  :class="{category_right_choosed: restaurant_category_ids == item.id || (!restaurant_category_ids)&&index == 0}">
                                <span>{{item.name}}</span>
                                <span>{{item.count}}</span>
                            </li>
                        </ul>
                    </section>
                    <!--右侧展示条目 e-->
                </section>
            </transition>
        </div>
        <!--排序-->
        <div class="sort_item" :class="{choose_type:sortBy=='sort'}">
        
        </div>
        <!--筛选-->
        <div class="sort_item" :class="{choose_type:sortBy=='activity'}">
        
        </div>
    </section>
</div>

JS部分:

//引入获取分类数据的方法
import {foodCategory} from "../../service/getData";
//引入处理图片路径的方法
import {getImgPath} from "../../components/common/mixin"; 
import {mapState,mapMutations} from "vuex";
 export default{
    data(){
        return{
            //头部标题
            headTitle:"",
            //筛选条件
            sortBy:"",
            //筛选的标题
            foodTitle:"",
            //分类左侧数据
            category:null,
             //category分类右侧的详细数据
             categoryDetail: null,
             //食品类型id值
            restaurant_category_id: "",
            //筛选类型的id
            restaurant_category_ids: ""
        }
    },
    //引入头部组件
    components:{
        headTop
    },
    created(){
        this.initData();
    },
    //getImgPath方法的调用需要引入mixins
    mixins:[getImgPath],
    computed:{
        ...mapState(["latitude","longitude"])
    },
    methods:{
        //初始化获取数据
        async initData(){
            //初始化时第一个筛选条目的名字和标题相等
            this.headTitle=this.$route.query.title;
            this.foodTitle=this.headTitle;
            //初始的食品类型id来自于上个页面(msite.vue)点击某个nav时传递过来的值
            this.restaurant_category_id = this.$route.query.restaurant_category_id;
            //初始化的时候获取分类数据,调用foodCategory,需要传入坐标
            this.category=await foodCategoty(this.latitude,this.latitude);
            //初始化时定位当前category分类左侧默认选项,在右侧展示出sub_categories列表
            this.category.forEach(item=>{
                if(this.restaurant_category_id==item.id){
                    this.categoryDetail=item.sub_categories;
                }
            });
            
            
        },
        //点击筛选nav来控制内容的隐藏和显示
        async chooseType(type){
            初始状态sortBy="",type值为food或其他
            if(this.sortBy!==type){
                //第一次点击之后sorBy值为type的值为food(若点击其他筛选项就是其他筛选项的值)
                this.sortBy=type;
                //点击的是第一项,第一个筛选条目的名字变成"分类"
                if(type=="food"){
                    this.foodTitle="分类"
                }
                else{
                    //点击其他两个条目
                    this.foodTitle=this.headTitle;
                }
            }
            else{
                //sortBy有值,对应内容展示后,再次点击,sorBy置空,显示效果对应内容收起
                this.sortBy="";
                if(type=="food"){
                    //若点击的是第一个条目,筛选项的名字由分类--->原来的名字
                    this.foodTitle=this.headTitle;
                }
            
            }
        
        },
        //选中category左侧列表的某个选项时,右侧渲染相应的sub_categories列表
        selectCategoryName(id,index){
            //点击对应类型食品,传入selectCategoryName(item.id,index),该项的id值
            //以及该项在list中的下标值
            if(index===0){
                //第一个选项-全部商家,因为没有自己的列表,所以点击则默认获取所有数据
                //点击全部时,下拉的详情应进行隐藏
                //重新置空筛选类型id,和控制下拉内容隐藏显示的sortBy
                this.restaurant_category_ids = null;
                this.sortBy = "";
            }
            else{
                //不是第一个选项时,右侧展示其index对应子级sub_categories的列表
                this.restaurant_category_id = id;    
                this.categoryDetail = this.category[index].sub_categories;
            }
        
        },
        //选中categoty右侧列表的某个选项时,进行筛选,重新获取数据并渲染
        getCategoryIds(id,name){
            //点击时传入详情(来自sub_categories)的id值,和name值
            //筛选项id置位点击项的id,状态为选中状态,添加有class:category_right_choosed
            this.restaurant_category_ids = id;
            this.sortBy="";//收起下拉内容
            //将筛选条目的名称,以及当前页面的title改为当前点击项的name值
            this.foodTitle=this.headTitle=name;
            //进行筛选...应该需要调用什么方法进行重新排序,原作者没有提到
        }
    
    
    }
 }
说明:

category的数据格式如下:
image.png
image.png
image.png
this.restaurant_category_id的初始值来源、headTitle的初始值来源:
image.png
坐标值来源:
store文件夹下,的index.js中,新增两个变量:
image.png
mutations.js:好像有位置信息的记录:
image.png

2.排序效果:

image.png

3.筛选效果:

image.png

原文链接:原文

zs_staria
36 声望12 粉丝

月光啊,闪爆他们~ ~