1

效果实现:

(二)"排序"及下拉列表

image.png
template部分:

...
<!--排序 s-->
<div class="sort_item" :class="{choose_type:sortBy=='sort'}">
    <!--触发部分 s-->
    <div class="sort_item_container" @click="chooseType('sort')">
        <div class="sort_item_border">
            <!--名字-->
            <span :class="{category_title:sortBy=='sort'}">排序</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>
    <!--触发部分 e-->
    <!--触发后展示的下拉列表 s-->
    <transition name="showlist">
        <!--sortBy值为sort时,列表展示,sortBy重新置空之后,再点击该部分隐藏-->
        <section v-show="sortBy=='sortBy'" class="sort_detail_type">
            <!--作用在于,点击时,找到某个li的p。根据data值的不同,以不同的排序方式重新进行排序-->
            <ul class="sort_list_container" @click="sortList($event)">
                <!--智能排序 s-->
                <li class="sort_list_li">
                    <!--绘制该分类的图标 s-->
                    <svg>
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#default" />
                    </svg>
                    <!--绘制该分类的图标 e-->
                    <p data="0" :class="{sort_select:sortByType==0}">
                        <span>智能排序</span>
                        <!--点击"智能排序"li绘制的图标-->
                        <svg v-if="sortByType==0">
                            <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                        </svg>
                    </p>
                </li>
                <!--智能排序 e-->
                <!--距离最近 s-->
                <li class="sort_list_li">
                    <!-- 绘制该分类的图标 s-->
                    <svg>
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#distance" />
                    </svg>
                    <!-- 绘制该分类的图标 e-->
                    <p data="5" :class="{sort_select:sortByType==5}">
                      <span>距离最近</span>
                      <!-- 点击了"距离最近"排序后,绘制的图标 -->
                      <svg v-if="sortByType==5">
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                      </svg>
                    </p>
                </li>
                <!--距离最近 e-->
                <!--销量最高 s-->
                <li class="sort_list_li">
                    <!-- 绘制销量最高的图标 s -->
                    <svg>
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#hot" />
                    </svg>
                    <!-- 绘制销量最高的图标 e -->
                    <p data="0" :class="{sort_select:sortByType==6}">
                      <span>销量最高</span>
                      <!-- 点击了"销量最高"排序绘制的图标 -->
                      <svg v-if="sortByType==6">
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                      </svg>
                    </p>
                </li>
                <!--销量最高 e-->
                <!--起送价最低 s-->
                 <li class="sort_list_li">
                    <!-- 绘制该分类的图标 s -->
                    <svg>
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#price" />
                    </svg>
                    <!-- 绘制该分类的图标 e -->
                    <p data="1" :class="{sort_select:sortByType==1}">
                      <span>起送价最低</span>
                      <!-- 点击了起送价最低之后绘制的图标 -->
                      <svg v-if="sortByType == 1">
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                      </svg>
                    </p>
                </li>
                <!--起送价最低 e-->
                <!--配送速度最快 s-->
                <li class="sort_list_li">
                    <!-- 绘制该分类的图标 s -->
                    <svg>
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#speed" />
                    </svg>
                    <!-- 绘制该分类的图标 e -->
                    <p data="2" :class="{sort_select:sortByType==2}">
                      <span>配送速度最快</span>
                      <!-- 点击"配送速度最快"之后绘制的图标 -->
                      <svg v-if="sortByType == 2">
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                      </svg>
                    </p>
                </li>
                <!--配送速度最快 e-->
                <!--评分最高 s-->
                <li class="sort_list_li">
                    <!-- 绘制该分类的图标 s-->
                    <svg>
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#rating" />
                    </svg>
                    <!-- 绘制该分类的图标 e -->
                    <p data="3" :class="{sort_select:sortByType==3}">
                      <span>评分最高</span>
                      <!-- 点击了评分最高之后绘制的图标 -->
                      <svg v-if="sortByType==3">
                        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                      </svg>
                    </p>
                </li>
                <!--评分最高 e-->
            </ul>
        </section>
    </transition>
    <!--触发后展示的下拉列表 e-->
</div>
<!--排序 e-->
...

JS部分:

...
//点击某个排序方式,获取事件对象的data值,并根据获取的值重新获取数据渲染
sortList(event){
    let node;
    //如果点击的是span中的文字,则需要获取到span的父标签p
    if(event.target.nodeName.toUpperCase()!=="p"){
        node=event.target.parentNode;
    }
    else{
        node=event.target;
    }
    //以上代码的作用在于确认找到的元素是p标签
    //获取p的data属性,该属性标记了不同的排序方式
    this.sortByType=node.getAttrtbute("data");
    //置空sortBy,收起下拉列表
    this.sortBy="";
    //重新进行排序:排序规则原作者并未涉及
    ...
}
...
(三)"筛选"及下拉列表

image.png

template部分:

...
<div class="sort_item" :class="{choose_type:sortBy=='activity'}">
    <!--触发部分 s chooseType方法通过改变sortBy值,控制列表的隐藏和显示-->
    <div class="sort_item_container" @click="chooseType('activity')">
        <span :class="{category_title:sortBy=='activity'}">筛选</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>
    <!--触发部分 e-->
    <!--触发后展示部分 s-->
    <transition name="showlist">
        <section v-show=='activity' class="sort_detail_type filter_container">
            <!--配送方式 s-->
            <section style="width:100%;">
                <header class="filter_header_style">配送方式</header>
                <ul class="filter_ul">
                    <!--点击时执行selectDeliveryMode,进行选择和取消选择-->
                    <li class="filter_li" v-for="(item,index) in Delivery" :key="index"
                     @click="selectDeliveryMode(item.id)">
                        <!--绘制该配送方式的图标,未选中时delivery_mode为0,不透明度为1-->
                        <!--delivery_mode == item.id时,当前为选中状态,图标为选中图标-->
                        <svg :style="{opacity:(item.id==0)&&(delivery_mode!==0)?0:1}">
                            <use
                              xmlns:xlink="http://www.w3.org/1999/xlink"
                              :xlink:href="delivery_mode == item.id? '#selected':'#fengniao'"
                            />
                        </svg>
                        <!--若为选中状态,改变文本的颜色-->
                         <span :class="{selected_filter:delivery_mode==item.id}">{{item.text}}</span>
                    </li>
                </ul>
            </section>
            <!--配送方式 e-->
            <!--商家属性 s-->
            <section style="width:100%;">
                <header class="filter_header_style">
                    商家属性(可以多选)
                </header>
                <ul class="filter_ul" style="paddingBottom:.5rem;">
                    <!--selectSupportIds点击时传入当前项的下标和id,实现多选-->
                    <li class="filter_li" v-for="(item,index) in Activity" :key="index"
                     @click="selectSupportIds(index,item.id)">
                        <!--support_ids的status为true时表示选中状态,绘制选中状态时的图标-->
                        <svg v-show="support_ids[index].status" class="activity_svg">
                             <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#selected" />
                        </svg>
                        <!--status值为false,不绘制选中状态的图标,而是绘制该activity的name的简写-->
                        <span class="filter_icon" :style="{color:'#'+item.icon_color,borderColor:'#'+item.icon_color}" v-show="!support_ids[index].status">
                            {{item.icon_name}}
                        </span>
                        <!--selected_filter标记选中状态的文字颜色-->
                        <span :class="{selected_filter:support_ids[index].status}">
                            {{item.name}}
                        </span>
                    </li>
                </ul>
            </section>
            <!--商家属性 e-->
            <!--清除和确认 s-->
            <div class="confirm_filter">
                <div class="clear_all filter_button_style" @click="clearSelect">清空</div>
                <div class="confirm_select filter_button_style" @click="confirmSelectFun">
                    确定
                    <!--展示已选定的个数-->
                    <span v-show="filterNum">{{filterNum}}</span>
                </div>
            </div>
            <!--清除和确认 e-->
        </section>
    </transition>
    <!--触发后展示部分 e-->
</div>
...
<!--点击后与下拉列表一同出现的遮罩层-->
<transition name="showcover">
    <div class="back_cover" v-show="sortBy"></div>
</transition>

JS部分:

//引入获取配送方式数据的方法foodDelivery;引入获取商家支持活动的数据的方法foodActivity
import {foodDelivery,foodActivity} from "../../service/getData";
export default{
    data(){
        return{
        ...
        //配送方式数据
        Delivery:null,
        //选中的配送方式
        delivery_mode:null,
         //所选中的所有样式的集合
        filterNum: 0,
        //商家支持活动数据
        Activity:null,
        //选中商铺的活动列表
        support_ids:[],
        //确认选择
        confirmStatus:false

        }
    },
    created(){
        this.initData();
    },
    methods:{
        //初始化数据
        async initData(){
            //获取筛选列表的配送方式
            this.Delivery=await foodDelivery(this.latitude,this.longitude);
            //获取筛选列表的商铺活动
            this.Activity=await foodActivity(this.latitude,this.lomgitude);
            /*supports_ids中存放status,来标记选中状态
              id:和获取到的活动数据的id相等
              supports_ids的长度和Activity的长度相等,下标也与之对应
            */
            this.Activity.forEach((item,index)=>{
                this.support_ids[index]={
                    status:false,
                    id:item.id
                }
            
            });
        },
        //“筛选选项”中配送方式选择
        selectDeliveryMode(id){
            //传入的参数为当前点击项的id
            //初始状态this.delivery_mode为空。点击选中当前项filterNum加1
            if(this.delivery_mode==null){
               //this.filterNum++是所选中项的集合
               this.filterNum++;
               //用delivery_mode标记当前选中项
               this.delivery_mode=id;
            }
            else if(this.delivery_mode==id){
                //若当前已是选中状态,清空已选中的状态,filterNum减一
                this.filterNum--;
                this.delivery_mode=null;
            }
            else{
                //未选中状态下再次点击选中
                this.delivery_mode=id;
            }
        
        },
        //点击商家活动,状态取反
        selectSupportIds(index,id){
            //传入参数:下标值,该点击项的id值
            /*
                splice()方法从数组中添加/删除项目,然后返回被删除的项目
                点击某一项,support_ids中,与index下标对应的项的status变为true,标记为选中
            */
            this.support_ids.splice(index,1,{
                status:!this.support_ids[index].status,
                /*第二次点击取消选中时,status由true--->false,选中的少了一个
                  下面循环计算filterNum值的时候也会少一个,选择的数量会展示在确认按钮那里*/
                id
            });
            //初始状态this.delivery_mode为null,this.filterNum值为0
            //filterNum为1的情况,“配送方式”是选中的状态
            this.filterNum=this.delivery_mode==null?0:1;
            this.support_ids.forEach(item=>{
                if(item.status){
                    this.filterNum++;
                    //status的状态为true,选中的filterNum值加1
                }
            })
        },
        //只有点击清空按钮才清空数据,否则一直保持原有状态
        clearSelect(){
            this.support_ids.map(item=>{
                item.status=false;
            });
            this.filterNum=0;
            this.delivery_mode=null;
        },
        //点击确认时,将需要筛选的id值传递给子组件,并且收回列表
        confirmSelectFun(){
        //状态改变时,因为子组件进行了监听,会重新获取数据进行筛选
            this.confirmStatus=!this.confirmStatus;
            this.sortBy="";
        }
    
    }
    

}
//"筛选选项"中配送方式选择
说明

Delivery的数据格式:
image.png
Activity的数据格式:
image.png
image.png
support_ids的数据格式:
image.png
选中几项后,support_ids变化的格式:
image.png
image.png

原项目链接:vue2-elm项目


zs_staria
36 声望12 粉丝

月光啊,闪爆他们~ ~