vue 实现 web端滚动刷新 排序 筛选 响应式布局 (源码)

vue 实现 web端滚动刷新 排序 筛选 响应式布局

先展示效果图
在这里插入图片描述
源码:

<template>
    <div>
<!--        头部-->
        <div class="header">
            <div class="header_select">
                <el-select  v-model="item"  @change="changeOption(item)" placeholder="请选择">
                    <el-option
                            v-for="(item,index) in options"
                            :key="index"
                            :value="item.title"
                    >
                    </el-option>
                </el-select>
            </div>
            <div class="sort" @click="sort">
                <div class="up" @click="sort(1)">↑</div>
                <div class="down" @click="sort(2)">↓</div>
            </div>
        </div>

<!--        主题部分-->
    <div class="content">
<!--        左边排序-->
        <div class="content_left">
             <div v-for="(item,index) in options" :key="index" @click="changePrice(item)">
                <p :class="['content_left_title', {'content_left_title_active':changeIndex===index ? true :false}]"
                   @click="changeRed(index)"> {{item.title}}
                </p>
             </div>
        </div>
<!--        右边展示-->
        <div class="content_right">
<!--        栅格布局-->
        <el-row :gutter="10">

            <el-col :xs="24" :sm="8" :md="6" :lg="6" :xl="6" v-for="(item,index) in list" :key="index">
                <div class="container">
                        <img :src="item.productImage"  class="productImage">
                        <div class="container_text">
                            <p class="productName"> {{item.productName}}</p>
                            <p class="salePrice"> ¥:{{item.salePrice}}</p>
                            <div class="add_div" @click="addCart(item)">加入购物车</div>
                        </div>
                </div>

<!--                点击加购的弹出框-->
                <el-dialog
                        :visible.sync="dialogVisible"
                        width="30%"
                        :before-close="handleClose">
                    <span class="add_cart_ok_text"> <i class="el-icon-cherry"></i>加购成功<i class="el-icon-ice-tea"></i></span>
                    <span slot="footer" class="dialog-footer">
                    <el-button @click="dialogVisible = false">继续加购</el-button>
                    <el-button type="primary" @click="lookCart">查看购物车</el-button>
                </span>
                </el-dialog>

            </el-col>
        </el-row>
<!--            <h2 v-customShow="imgShow" >没有数据啦</h2>-->
<!--            底部加载图片   -->
            <div class="hidden_img" v-customShow="imgShow">
                 <img  width="15%" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1594203057728&di=b98734df67bbe297b4ac80154751a3a3&imgtype=0&src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F73d00f8e9b5e91aaf8ca7f8fc8c1746b33acb0d563c3d-2lSOZj_fw658">
            </div>

        </div>
    </div>

    </div>
</template>

<script>
import axios from 'axios'
    export default {
        name: "Media",
        data(){
            return{
                list:[], //商品的全部数据
                options:[],//价格排序的数据
                item:'', //
                priceList:[], //点击价格数组
                courselist:[], //原始的数组
                changeIndex:0, //点击红色左边框
                dialogVisible:false, //点击打开弹窗
                imgShow:false,  //自定义指令
                i:2,  // 下拉加载的下标

            }
        },
        methods:{
            //改变左边的价格选项
            changePrice(item){
                this.list = []; //先清空  否则会一直追加
                this.courselist.forEach(ele=>{
                    // 判断价格的区间范围  放在展示数组里面
                    if(item.low <= ele.salePrice  && ele.salePrice <= item.hight) {
                        this.list.push(ele);
                    }
                });
            },
            // 头部选项框改变
            changeOption(item){
                //遍历 价格排序的数组
                let a = this.options.findIndex(ele=>{
                    return ele.title === item
                });
                // console.log(this.options[a]);
                this.list = []; //先清空  否则会一直追加
                this.courselist.forEach(ele=>{
                    // 判断价格的区间范围  放在展示数组里面
                    if(this.options[a].low <= ele.salePrice  && ele.salePrice <= this.options[a].hight) {
                        this.list.push(ele);
                    }
                });
            },
            //点击排序
            sort(id){
                 switch (id) {
                     case 1:
                         this.list.sort((x,y)=>{
                             return x.salePrice - y.salePrice
                         });
                         break;
                     case 2:
                         this.list.sort((x,y)=>{
                             return y.salePrice - x.salePrice
                         });
                         break;
                 }
            },
            //点击排序 出现红色左边框
            changeRed(index){
                this.changeIndex = index
            },
            //点击加购
            addCart(item){
                this.dialogVisible = true;
            },
            //点击弹出层的X 弹出确认框
            handleClose(done) {
                this.$confirm('确认关闭?').then(_ => {
                        done();
                    }).catch(_ => {});
            },
            //点击查看购物车  跳转路由
            lookCart(){
                this.dialogVisible = false;
                this.$router.push('/lookCart');
            }

        },
        mounted() {
            axios.get('./media/data.json').then(res=>{
                //保存一个原始数组
                this.courselist = res.data.result.list;
                // 展示商品的数组
                this.list = res.data.result.list;
                //左边价格的选项
                this.options = res.data.result.slider;
                }).catch(err=>{
                    console.log(err)
             });
            // 实时获取 滚动的距离
            window.addEventListener('scroll',()=>{
               /* 计算滑动到底部 整个文档的高度  = 可视区域高度 + 滚动的距离*/
                //获取滚动的距离
                let scrollHeight = document.documentElement.scrollTop;
                //获取整个文档的高度
                let docHeight = document.documentElement.scrollHeight;
                //可视区域高度
                let seeHeight = document.documentElement.clientHeight;
                // 整个文档的高度 -  可视区域高度 - 滚动的距离 === 0 时候 说明 到底部了
                if(docHeight - seeHeight - scrollHeight  < 1) {
                    //loading加载出现
                    this.imgShow = true;
                    //计时器  3秒后loading隐藏 数据请求回来加入数组
                    window.setTimeout(()=>{
                        console.log('达到最底部')
                        //我们的json数据只到 3  所以在这里判断一下
                        if(this.i === 4 ) {
                            this.imgShow = false;
                            return;
                        }
                        //loading 隐藏
                        this.imgShow = false;
                        //axios请求 json
                        axios.get(`./media/data${this.i}.json`).then(res=>{
                            //扩展运算符 赋值给list
                            this.list = [...this.list,...res.data.result.list];

                        }).catch(err=>{
                            console.log(err)
                        });
                        this.i++;

                    },3000)
                }
      /*      console.log(scrollHeight + '滚动距离')
                console.log(docHeight + '文档高度')
                console.log(seeHeight + '可视') */
            })

        },
        // 自定义指令
        directives:{
            customShow:{   //自定义指令的名字
                bind(){},
                // 只有在插入时候触发 只用一次  更新不会触发  我们每次会改变ture false 所以要在更新时写一遍
                inserted(el,binding){
                    if(binding.value) {
                        el.style.visibility = 'visible';
                    }else {
                        el.style.visibility = 'hidden';
                    }
                },
                // true  false  更新的时触发
                update(el,binging){
                    // el 是获取到当前的元素   binging是当前元素的所有信息
                    if(binging.value) {
                        el.style.visibility = 'visible';
                    }else {
                        el.style.visibility = 'hidden';
                    }
                }
            }
        }
    }
</script>

<style scoped>
    .hidden_img {
        width: 100%;
        display: flex;
        justify-content: center;
    }
    .add_cart_ok_text { color:red;}
    .content_left_title_active{
        border-left: 2px solid red !important;
        color: red !important ;
        font-weight: bold;
    }
    .add_div:hover{
        background-color: rgba(216, 124, 125, 0.5);
    }
    .container:hover{
        z-index: 2;
        -webkit-box-shadow: 0 15px 30px rgba(0,0,0,.1);
        box-shadow: 0 15px 30px rgba(0,0,0,.1);
        -webkit-transform: translate3d(0,-2px,0);
        transform: translate3d(0,-2px,0);
    }
    .down ,.up {
        width: 50px;
        border: 1px solid #fff;
        text-align: center;
        height: 30px;
        line-height: 30px;
        margin-top: 10px;
    }
    .content {width: 100%;display: flex;}
    .content_left {width: 25%;background-color: #F5F5F5; border-right: 1px solid #eee}
    .content_right {width: 75%;}
    .header { display: flex; justify-content: space-around; padding: 0 50px;box-sizing: border-box; width: 100%;height: 50px;line-height: 50px; background-color: #F5F5F5; margin: 5px 0 }
.productImage { width: 150px;  height:150px;}
.productName {color: #666666; font-size: 12px}
.salePrice {color: red; font-weight: bold}
.container{ transition: all 1s; text-align: center; height: 246px; background-color: #fff; border: 1px solid #eee; margin: 10px 0;}
.add_div { width: 95%;height: 40px;line-height: 40px;border: 1px solid red;color: red;text-align: center}
.header_select {display: none}
.content_left_title { border-left: 2px solid #fff; padding: 20px;box-sizing: border-box;height: 50px;color: #333333}
.sort {display: flex;justify-content: space-around; width: 200px;}

    @media screen and (max-width: 768px){
        .container{height: 150px;
            line-height: 150px;}
        .container img {float: left;}
        .header_select {display: block}
        .content_left {display: none}
        .content_right {width: 100%;}
        .add_div {width: 50%;}
        .container_text {
            display: flex;
            justify-content: space-around;
            align-items: center;
        }
}

</style>
  • 2
    点赞
  • 1
    收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值