效果实现:
(二)"排序"及下拉列表
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="";
//重新进行排序:排序规则原作者并未涉及
...
}
...
(三)"筛选"及下拉列表
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的数据格式:
Activity的数据格式:
support_ids的数据格式:
选中几项后,support_ids变化的格式:
原项目链接:vue2-elm项目
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。