vue.js格式使用vant-页面引入2

一、上拉刷新和加载

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <title>Page Title</title>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <!-- 引入样式文件 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.4/lib/index.css">

  <!-- 引入 Vue 和 Vant 的 JS 文件 -->

  <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
  <script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vant@2.4/lib/vant.min.js"></script>

</head>

<body>

</body>

<template>
  <div id="video_wrap">
    <div class="video_tab">
      <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
        <van-list v-model="loading" :finished="finished" @load="onLoad">
          
        </van-list>
        <div class="no_more" v-show="finished">---到底了哦---.</div>
      </van-pull-refresh>
    </div>
  </div>
</template>

<script>
  let vm = new Vue({
    el: "#app",
    data() {
      return {
        videoList: [],//用于存放加载的数据
        loading: false,//控制上拉加载的加载动画
        finished: false,//控制在页面往下移动到底部时是否调用接口获取数据
        isLoading: false,//控制下拉刷新的加载动画
        pageNum: 1, // 页数
        offset: 0,  // 下次加载起始页
        totalPage: 0 // 总页数
      }
    },
    template: "#video_wrap"//通过该属性可以将自定义的template属性中的内容全部替换app的内容,并且会覆盖里面原有的内容,并且在查看dom结构时没有template标签
    , methods: {
      async init() {
        let that = this;
        let params = {
          offset: (that.pageNum - 1) * 8
        };
        let res = await axios.get(this.$HOST + '/open/health/message/center/app/videoList', params);
        that.videoList = res.result.videosAll.data; // 第一页内容
        that.pageNum = res.result.videosAll.page; // 当前显示页
        that.totalPage = Math.ceil(res.result.videosAll.total / res.result.videosAll.limit); // 总页数
        if (res.result.videosAll.total < 10) {
          that.finished = true; // 加载结束
          that.isLoading = false;
          that.loading = false;
          return false;
        }
      },

      async concatData() {
        let that = this;
        that.pageNum += 1;
        // 数据全部加载完成
        let params = {
          offset: (that.pageNum - 1) * 8
        };
        let res = await this.$http.get(this.$HOST + '/open/health/message/center/app/videoList', params);
        if (res.result.videosAll.total < 10) {
          that.finished = true; // 加载结束
          that.isLoading = false;
          that.loading = false;
          return false;
        }
        that.videoList = that.videoList.concat(res.result.videosAll.data);
        this.loading = false;
        if (this.pageNum >= this.totalPage) {
          that.finished = true; // 加载结束
          that.isLoading = false;
          that.loading = false;
        }
      },
      onRefresh() {
        setTimeout(() => {
          this.$toast({
            message: '刷新成功',
            position: 'bottom'
          });
          this.isLoading = false;
          this.pageNum = 1;
          this.loading = false;
          this.finished = false;
          this.isLoading = false;
          this.init();
        }, 500);
      },

      onLoad() {
        // 异步更新数据
        setTimeout(() => {
          this.concatData();
        }, 500);
      }
    },
    async created() {
      this.init();
    }

  });
</script>

</html>

 参考请求方法。如果不想让按钮在一开始的时候存在,而是在滚动了一定的距离的时候再出现,那设置 一个滚动条的监听就搞定啦,  

mounted() {
    window.addEventListener('scroll', this.handleScroll, true)
  },

//methods中定义事件
handleScroll(env){
      let scrollTop = document.getElementsByClassName('equi_container')[0].scrollTop
      if(scrollTop > 100){
        this.flag_scroll = true
      }else {
        this.flag_scroll = false
      }
    },

 案例例子

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>

    <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
    <!-- 引入样式文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.4/lib/index.css">

    <!-- 引入 Vue 和 Vant 的 JS 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vant@2.4/lib/vant.min.js"></script>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            overflow: hidden;
        }
        /*禁用接管浏览器滚动条*/

        .list{
            margin-top:46px;
            overflow:auto;
        }
        .list-item{
            text-align:center;
        }
    </style>
</head>

<body>
    <div id="app">

    </div>
    <!--此处template标签必须在vue绑定的元素外面定义,并且在页面中不显示下面的template标签中的内容-->
    <template id="first">
        <div>
            <van-nav-bar fixed title="数据列表" right-text="退出登录"></van-nav-bar>


            <div class="list" id="list">
                <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
                    <van-list v-model="loading" :finished="finished" @load="onLoad" :offset="10">
                        <div class="list-item">
                            <van-cell v-for="(item,key) in list" :key="key" :title="item + '' " />
                        </div>
                    </van-list>
                </van-pull-refresh>
            </div>


        </div>
    </template>

    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                list: [],
                loading: false,   //是否处于加载状态
                finished: false,  //是否已加载完所有数据
                isLoading: false,   //是否处于下拉刷新状态
            },
            template: "#first"//通过该属性可以将自定义的template属性中的内容全部替换app的内容,并且会覆盖里面原有的内容,并且在查看dom结构时没有template标签
            , methods: {
                onLoad() {      //上拉加载
                    setTimeout(() => {
                        for (let i = 0; i < 15; i++) {
                            this.list.push(this.list.length + 1);
                        }
                        this.loading = false;
                        if (this.list.length >= 60) {
                            this.finished = true;
                        }
                    }, 500);
                },
                onRefresh() {       //下拉刷新
                    setTimeout(() => {
                        this.finished = false;
                        this.isLoading = false;
                        this.list = []
                        this.onLoad()
                    }, 500);
                }
            },
            mounted() {

                let winHeight = document.documentElement.clientHeight;                          //浏览器视口大小
                document.getElementById("list").style.height = (winHeight - 50) + "px"  //调整框高度

            }
        });
    </script>

</body>

</html>

 二、配合tabs模板

如图所示:

代码如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">

    <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
    <!-- 引入样式文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.4/lib/index.css">

    <!-- 引入 Vue 和 Vant 的 JS 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vant@2.4/lib/vant.min.js"></script>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            overflow: hidden;
            /*1、禁用body滚动条*/
        }

        .list {
            margin-top: 46px;
            overflow: auto;
            -webkit-overflow-scrolling: touch;
            -webkit-overflow-scrolling: auto;
            /*2、设置局部容器的内容超出可以滚动并显示滚动条  注意:容器内部item 必须设置宽和高*/
        }

        /*内部元素设置可以滚动*/
        .list-item {
            text-align: center;
        }
    </style>
</head>

<body>
    <div id="app">

    </div>
    <!--此处template标签必须在vue绑定的元素外面定义,并且在页面中不显示下面的template标签中的内容-->
    <template id="first">
        <div>

            <van-nav-bar fixed title="数据列表" right-text="退出登录"></van-nav-bar>

            <van-button type="default"
                style="position: fixed !important ;right:2rem !important;bottom: 4rem !important;z-index: 99 !important; background-color:rgba(0,0,0,0.1) !important"
                class="backTop" sticky @click="backTop" v-show="flag_scroll">
                <van-icon name="arrow-up" size="20" />
            </van-button>

            <div class="list" id="list">
                <van-tabs v-model="active" sticky @click="changeAct">
                    <van-tab v-for="(item,ind) in navtitle" :title="item" :key="ind">
                        <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
                            <van-list v-model="loading" :finished="finished" finished-text="没有更多了"
                                :immediate-check="false" @load="onLoad(page,keyword,orderColumn)" :offset='0'>
                                <!--<IndexTemp v-for="(item,i) in goodList" :good="item" :key="i"></IndexTemp>-->
                                <!--必须指定高度,否则会影响监听底部,会导致出现不显示滚动条-->
                                <!--<van-cell style="height: 200px;" v-for="(item,key) in list" :key="key" :title="item + '' " />-->

                                <template v-for="(item,key) in list">
                                    <!--这种宽度必须指定,否则触发这两次-->
                                    <img height="200px" width="100%"
                                        src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1208538952,1443328523&fm=26&gp=0.jpg" />
                                </template>

                            </van-list>
                        </van-pull-refresh>
                    </van-tab>
                </van-tabs>

            </div>



        </div>
    </template>

    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                active: 0,
                navtitle: ["默认", "价格", "上新"],
                orderTypeCut: "desc",//

                page: 0,          //当前页
                keyword: "",      //关键字查询
                orderColumn: "",  //

                list: [],         //数据
                loading: false,   //是否处于加载状态
                finished: false,  //是否已加载完所有数据
                isLoading: false,   //是否处于下拉刷新状态

                flag_scroll: false,//是否显示返回顶部按钮

            },
            template: "#first"//通过该属性可以将自定义的template属性中的内容全部替换app的内容,并且会覆盖里面原有的内容,并且在查看dom结构时没有template标签

            , methods: {
                //切换tab
                changeAct(index, title) {
                    this.active = index;
                    this.orderColumn = title == '价格' ? 'price' : title == '上新' ? 'time' : 'default';
                    if (this.orderColumn == 'price') {
                        this.orderTypeCut = !this.orderTypeCut;
                    }
                    this.orderType = this.orderTypeCut ? 'desc' : 'asc';
                    this.page = 1;    //初始化1
                    this.list = [];   //初始化数据
                    this.loading = true;  //设置加载中状态
                    this.finished = false; //设置为未加载所有数据状态
                    if (this.loading) {
                        this.onLoad(this.page, this.keyword, this.orderColumn);
                    }
                },
                onLoad(page, keyword, orderColumn) {      //上拉加载
                    setTimeout(() => {
                        for (let i = 0; i < 15; i++) {
                            this.list.push(this.list.length + 1);
                        }
                        this.loading = false;
                        if (this.list.length >= 60) {
                            this.finished = true;
                        }
                    }, 500);
                },
                onRefresh() {       //下拉刷新
                    setTimeout(() => {
                        this.finished = false;
                        this.isLoading = false;
                        this.list = []
                        this.onLoad()
                    }, 500);
                }, backTop() //返回顶部
                {
                    //document.getElementsByClassName('list')[0].scrollTop=0;
                    $('.list').animate({ scrollTop: 0 }, 500);
                },
                handleScroll(env) {
                    let scrollTop = document.getElementsByClassName('list')[0].scrollTop;
                    console.log("滚动位置:" + scrollTop);
                    if (scrollTop > 100) {
                        this.flag_scroll = true
                    } else {
                        this.flag_scroll = false
                    }
                },
            }, created() {

            },
            mounted() {
                this.onLoad()  //创建的时候触发
                let winHeight = document.documentElement.clientHeight;                          //浏览器视口大小
                document.getElementById("list").style.height = (winHeight - 44) + "px"  //调整框高度

                //滚动条的监听显示回返顶部按钮 获取并存储当前 scrollTop
                window.addEventListener('scroll', this.handleScroll, true)

            }, destroyed() {
                window.removeEventListener('scroll', this.handleScroll, true)
            },
        });
    </script>

</body>

</html>

发现的问题:超出了2px

 

 然后查找原因

 问题是: 会出现两个滚动条,这个是超出屏幕的滚动条,一个是你写的超出.list的滚动条

 

发现受阻比较小,但是切换后,还是一个新的下拉,每次触发下拉请求,这是很重要的(只不过下拉加载触感太低) ,切换都是新的加载,没法保留,这个限制

我当时为了解决多个上拉,而且为了固定,发现完全不用 用粘性布局,外层放置一个div即可

当时的例子,不推荐自己更改css,应该当时布局好 header 中间 和底部

<template>
  <div class="page">
    <van-row id="header">
      <van-col span="24">
        <!--NavBar 导航栏fixed 以及z-index-->
        <van-nav-bar
          z-index="3"
          fixed
          title="标题"
          left-text="返回"
          right-text="按钮"
          left-arrow
          @click-left="onClickLeft"
          @click-right="onClickRight"
        ></van-nav-bar>
      </van-col>
    </van-row>

    <van-row class="content" id="content">
      <van-col span="24">
        <!--Tab 标签页-->
        <van-tabs z-index="2" v-model="active" swipeable>
          <van-tab title="标签 1">
            <!--PullRefresh 下拉刷新-->
            <van-pull-refresh v-model="isLoading1" @refresh="onRefresh1">
              <!--<p>刷新次数: {{ count }}</p> -->
              <!--List 列表 滚动加载-->
              <van-list v-model="loading1" :finished="finished1" @load="onLoad1" :offset="10">
                <div class="list-item">
                  <template v-for="(item,index) in list1">
                    <van-cell :key="index">A item{{item}}</van-cell>
                  </template>
                </div>
              </van-list>
            </van-pull-refresh>
          </van-tab>
          <van-tab title="标签 2">
            <!--PullRefresh 下拉刷新-->
            <van-pull-refresh v-model="isLoading2" @refresh="onRefresh2">
              <!--<p>刷新次数: {{ count }}</p> -->
              <!--List 列表 滚动加载-->
              <van-list v-model="loading2" :finished="finished2" @load="onLoad2" :offset="10">
                <div class="list-item">
                  <template v-for="(item,index) in list2">
                    <van-cell :key="index">B item{{item}}</van-cell>
                  </template>
                </div>
              </van-list>
            </van-pull-refresh>
          </van-tab>
          <van-tab title="标签 3">内容 3</van-tab>
          <van-tab title="标签 4">内容 4</van-tab>
        </van-tabs>
      </van-col>
    </van-row>

    <van-row class="footer">
      <van-col span="24">
        <!--Tabbar 标签栏-->
        <tabbar></tabbar>
      </van-col>
    </van-row>
  </div>
</template>
<script>
import tabbar from "../../components/tabbar.vue"; //引用组件的地址
export default {
  components: {
    tabbar: tabbar
  },
  data() {
    return {
      active: 0,
      count1: 0,
      list1: [],
      loading1: false, //是否处于加载状态
      finished1: false, //是否已加载完所有数据
      isLoading1: false, //是否处于下拉刷新状态
      count2: 0,
      list2: [],
      loading2: false, //是否处于加载状态
      finished2: false, //是否已加载完所有数据
      isLoading2: false //是否处于下拉刷新状态
    };
  },
  methods: {
    onClickLeft() {
      this.$toast("返回");
    },
    onClickRight() {
      this.$toast("按钮");
    }, //上拉加载
    onLoad1() {
      setTimeout(() => {
        for (let i = 0; i < 15; i++) {
          this.list1.push(this.list1.length + 1);
        }
        this.loading1 = false;
        if (this.list1.length >= 60) {
          this.finished1 = true;
        }
      }, 500);
    }, //下拉刷新
    onRefresh1() {
      setTimeout(() => {
        this.$toast("刷新成功");
        this.isLoading1 = false;
        this.count++;
      }, 1000);
    },
    onLoad2() {
      setTimeout(() => {
        for (let i = 0; i < 15; i++) {
          this.list2.push(this.list2.length + 1);
        }
        this.loading2 = false;
        if (this.list2.length >= 60) {
          this.finished2 = true;
        }
      }, 500);
    }, //下拉刷新
    onRefresh2() {
      setTimeout(() => {
        this.$toast("刷新成功");
        this.isLoading2 = false;
        this.count++;
      }, 1000);
    }
  },
  mounted() {

      let winHeight = document.documentElement.clientHeight                          //视口大小
      document.getElementById('content').style.height = (winHeight - 100) +'px'  //调整上拉加载框高度


  }
};
</script>

<style scoped>
.list-item {
  text-align: center;
}

.content {
  margin-top: 46px; 
}

.content .van-col >>> .van-tabs .van-tabs__wrap {
  position: fixed;
  width: 100%;
  top: 44px;
  box-sizing: border-box;
  z-index: 2;
}
.content .van-col >>> .van-tabs .van-tab__pane {
  margin-top: 44px;
}
/*
滚动条的问题
*/

.content{

  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

.page
{
  height: auto;
}


/*.van-tabs {
  overflow: auto;
  height: 100%;
  box-sizing: border-box;
  -webkit-overflow-scrolling: touch;
}*/
</style>

发现多次一举这样的自定义css ,不过这里面放入多个可以解决多个tab数据保留的问题,只不过上拉加载阻力太低,感觉高度是一开始充满的,不是上拉到底部后触发的

注意:

整理

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">

    <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
    <!-- 引入样式文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.4/lib/index.css">
    <link rel="stylesheet" href="./app.min.css">

    <!-- 引入 Vue 和 Vant 的 JS 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vant@2.4/lib/vant.min.js"></script>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            overflow: auto;
            background-color: #f7f8fa;
        }

        /*禁用接管浏览器滚动条*/

        .list {
            /*如果overflow: hidden;设置的则下拉内应该 配合 margin: 0 1rem;否则list宽度100%滚动条会和body重合,会导致出现消失 */
            margin-top: 46px;
            overflow: auto;
            width: 100%;
            box-sizing: border-box;
        }

        /*内部元素设置可以滚动*/
        .list-item {
            text-align: center;
        }



        /*多层*/
        .product_list_medium,
        .product_list_small {
            overflow: hidden;
        }

        /* .product_list_small  small_product列表布局*/
        /*
        flex-wrap 属性
        flex-wrap: nowrap|wrap|wrap-reverse|initial|inherit; 
        nowrap - 默认, 弹性容器为单行。该情况下弹性子项可能会溢出容器。
        wrap - 弹性容器为多行。该情况下弹性子项溢出的部分会被放置到新行,子项内部会发生断行
        wrap-reverse -反转 wrap 排列。
        */
        .product_list_small .product_div {
            display: -webkit-flex;
            display: flex;
            -webkit-flex-wrap: wrap;
            flex-wrap: wrap;
            /*指定宽高  h 必须指定,不然内部其他元素会冲开*/
            width: auto;
            /*auto是随内容的高度而撑开的。100%是根据父级元素的高度来决定的*/
            height: 8rem;
            /*布局*/
            margin: 1rem;
            padding: 1rem;
            /*指定背景*/
            background-color: #ffffff;
            box-shadow: 0 8px 12px #ebedf0;
            border-radius: 1rem;
            /*超出隐藏,以防隐藏到外部的布局*/
            overflow: hidden;
        }

        /*指定图片框固定大小*/
        .product_list_small .product_div .pictrue_div {
            width: 8rem;
            height: 100%;
        }

        /*设置100%,填充图片框*/
        .product_list_small .product_div .pictrue_div img {
            width: 100%;
            height: 100%;
            border-radius: 1rem;
        }

        .product_list_small .product_div .dis-box {
            flex: 1;
            padding: 1rem;
            /*这里知道高可以指定title=3rem 内容可以设置3rem即可,而我设置title3 底部 auto 自动计算内容也会是3,用了 弹性盒子*/
            display: -webkit-flex;
            display: flex;
            -webkit-flex-direction: column;
            flex-direction: column;
        }

        .product_list_small .product_div .dis-box .product_text {
            height: 3rem;
        }

        .product_list_small .product_div .dis-box .product_remark {
            flex: 1;
        }

        .product_list_medium {
            display: -webkit-flex;
            display: flex;
            -webkit-flex-wrap: wrap;
            flex-wrap: wrap;
        }

        /* .product_list_medium medium-list*/
        .product_list_medium .product_div {
            display: -webkit-flex;
            display: flex;
            -webkit-flex-direction: column;
            flex-direction: column;
            /*指定宽高  h 必须指定,不然内部其他元素会冲开*/
            width: 46%;
            /*auto是随内容的高度而撑开的。100%是根据父级元素的高度来决定的*/
            height: auto;
            /*布局*/
            margin: 4% 2% 0 2%;
            padding: 0.4rem;
            /*指定背景*/
            background-color: #ffffff;
            box-shadow: 0 8px 12px #ebedf0;
            border-radius: 1rem;
            /*超出隐藏,以防隐藏到外部的布局*/
            overflow: hidden;
            box-sizing: border-box;
        }

        .product_list_medium .product_div .dis-box {
            box-sizing: border-box;
            flex: 1;
            padding: 0.2rem;
        }

        .product_list_medium .product_div .pictrue_div {
            box-sizing: border-box;
            flex: 1;
        }

        /*指定图片框固定大小*/
        .product_list_medium .product_div .pictrue_div {
            width: 100%;
            height: 14rem;
        }

        /*设置100%,填充图片框*/
        .product_list_medium .product_div .pictrue_div img {
            width: 100%;
            height: 100%;
            border-radius: 1rem;
        }

        /**/
        .product_list_big {
            display: -webkit-flex;
            display: flex;
            -webkit-flex-wrap: wrap;
            flex-wrap: wrap;
        }

        /* .product_list_big medium-list*/
        .product_list_big .product_div {
            display: -webkit-flex;
            display: flex;
            -webkit-flex-direction: column;
            flex-direction: column;
            /*指定宽高  h 必须指定,不然内部其他元素会冲开*/
            width: 100%;
            /*auto是随内容的高度而撑开的。100%是根据父级元素的高度来决定的*/
            height: auto;
            /*布局*/
            margin: 4% 2% 0 2%;
            padding: 0.4rem;
            /*指定背景*/
            background-color: #ffffff;
            box-shadow: 0 8px 12px #ebedf0;
            border-radius: 1rem;
            /*超出隐藏,以防隐藏到外部的布局*/
            overflow: hidden;
            box-sizing: border-box;
        }

        .product_list_big .product_div .dis-box {
            box-sizing: border-box;
            flex: 1;
            padding: 0.2rem;
        }

        .product_list_big .product_div .pictrue_div {
            box-sizing: border-box;
            width: 100%;
            flex: 1;
        }

        /*指定图片框固定大小*/
        .product_list_big .product_div .pictrue_div {
            width: 100%;
            height: 26rem;
        }

        /*设置100%,填充图片框*/
        .product_list_big .product_div .pictrue_div img {
            width: 100%;
            height: 100%;
            border-radius: 1rem;
        }
    </style>
</head>

<body>
    <div id="app">

    </div>
    <!--此处template标签必须在vue绑定的元素外面定义,并且在页面中不显示下面的template标签中的内容-->
    <template id="first">
        <div>

            <van-nav-bar fixed title="数据列表" right-text="退出登录"></van-nav-bar>

            <van-button type="default"
                style="position: fixed !important ;right:2rem !important;bottom: 4rem !important;z-index: 99 !important; background-color:rgba(0,0,0,0.1) !important"
                class="backTop" sticky @click="backTop" v-show="flag_scroll">
                <van-icon name="arrow-up" size="20" />
            </van-button>

            <div class="list" id="list">
                <van-tabs v-model="active" swipeable sticky @click="changeAct">
                    <van-tab v-for="(item,ind) in navtitle" :title="item" :key="ind">
                        <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
                            <!-- :immediate-check="false"    是否在初始化时立即执行滚动位置检查-->
                            <!-- :offset='0'    滚动条(滚动条)与底部距离小于 offset 时触发load事件-->
                            <van-list v-model="loading" :finished="finished" finished-text="没有更多了"
                                @load="onLoad(page,keyword,orderColumn)" :error.sync="error" error-text="请求失败,点击重新加载"
                                :offset='0'>
                                <!--<IndexTemp v-for="(item,i) in goodList" :good="item" :key="i"></IndexTemp>-->
                                <!--<van-cell v-for="(item,key) in list" :key="key" :title="item + '' "></van-cell>-->

                                <!--
                                <div class="product_list_small">
                                    <template v-for="(item,key) in list">
                                        <div class="product_div">
                                            <div class="pictrue_div">
                                                <img
                                                    src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1208538952,1443328523&fm=26&gp=0.jpg" />
                                            </div>
                                            <div class="dis-box">
                                                <p class="product_text">
                                                    标题
                                                </p>
                                                <p class="product_remark">
                                                    商品描述 简介  一些列信息
                                                </p>
                                            </div>
                                        </div>
                                    </template>
                                </div> 
                            -->
                                <!--
                                <div class="product_list_medium">
                                    <template v-for="(item,key) in list">
                                        <div class="product_div">
                                            <div class="pictrue_div">
                                                <img
                                                    src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1208538952,1443328523&fm=26&gp=0.jpg" />
                                            </div>
                                            <div class="dis-box">
                                                <p class="product_text">
                                                    标题
                                                </p>
                                                <p class="product_remark">
                                                    商品描述 简介  一些列信息
                                                </p>
                                            </div>
                                        </div>
                                    </template>
                                </div>
                            -->

                                <div class="product_list_big">
                                    <template v-for="(item,key) in list">
                                        <div class="product_div">
                                            <div class="pictrue_div">
                                                <img
                                                    src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1208538952,1443328523&fm=26&gp=0.jpg" />
                                            </div>
                                            <div class="dis-box">
                                                <p class="product_text">
                                                    标题
                                                </p>
                                                <p class="product_remark">
                                                    商品描述 简介 一些列信息
                                                </p>
                                            </div>
                                        </div>
                                    </template>
                                </div>




                            </van-list>
                        </van-pull-refresh>
                    </van-tab>

                    <van-tab>
                        <template #title>

                            <i class="iconfont icon-pailie" data="0"></i>
                            <!--<i class="iconfont icon-viewlist" data="2"></i>-->
                            <!--<i class="iconfont icon-icon-square" data="2"></i>-->

                        </template>

                    </van-tab>

                </van-tabs>

            </div>



        </div>
    </template>

    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                active: 0,
                navtitle: ["默认", "价格", "上新"],
                orderTypeCut: "desc",//

                page: 0,          //当前页
                keyword: "",      //关键字查询
                orderColumn: "",  //

                list: [],         //数据
                loading: false,   //是否处于加载状态
                finished: false,  //是否已加载完所有数据
                refreshing: false,   //是否处于下拉刷新状态
                error: false,

                flag_scroll: false,//是否显示返回顶部按钮

            },
            template: "#first", //通过该属性可以将自定义的template属性中的内容全部替换app的内容,并且会覆盖里面原有的内容,并且在查看dom结构时没有template标签
            methods: {
                //切换tab
                changeAct(index, title) {

                    this.active = index;
                    this.orderColumn = title == '价格' ? 'price' : title == '上新' ? 'time' : 'default';
                    if (this.orderColumn == 'price') {
                        this.orderTypeCut = !this.orderTypeCut;
                    }
                    this.orderType = this.orderTypeCut ? 'desc' : 'asc';
                    this.page = 1;    //初始化1
                    this.list = [];   //初始化数据
                    this.loading = true;  //设置加载中状态
                    this.finished = false; //设置为未加载所有数据状态
                    if (this.loading) {
                        this.onLoad(this.page, this.keyword, this.orderColumn);
                    }

                },
                onLoad(page, keyword, orderColumn) {      //上拉加载

                    console.log("触发onload事件");

                    setTimeout(() => {
                        for (let i = 0; i < 15; i++) {
                            this.list.push(this.list.length + 1);
                        }
                        //加载状态结束
                        this.loading = false;
                        //数据全部加载完成
                        if (this.list.length >= 60) {
                            this.finished = true;
                        }
                    }, 500);

                    console.log(this.list);

                },
                onRefresh() {       //下拉刷新
                    setTimeout(() => {
                        this.finished = false;
                        this.refreshing = false;
                        this.list = [];
                        this.onLoad();
                    }, 500);
                }, backTop() //返回顶部
                {
                    //document.getElementsByClassName('list')[0].scrollTop=0;
                    $('#list').animate({ scrollTop: 0 }, 500);
                },
                handleScroll(env) {
                    let scrollTop = document.getElementById("list").scrollTop;
                    console.log("滚动位置:" + scrollTop);
                    if (scrollTop > 100) {
                        this.flag_scroll = true
                    } else {
                        this.flag_scroll = false
                    }
                },
            },
            mounted() {
                let winHeight = document.documentElement.clientHeight;                          //浏览器视口大小
                document.getElementById("list").style.height = (winHeight - 44) + "px"  //调整框高度

                //滚动条的监听显示回返顶部按钮 获取并存储当前 scrollTop
                window.addEventListener('scroll', this.handleScroll, true)

            }, destroyed() {
                window.removeEventListener('scroll', this.handleScroll, true)
            },
        });
    </script>

</body>

</html>

刷新触发load,单次和频繁的问题都有,而且拉动只能触动内容的部分才可以拉动

<style scoped>
.flex {
  display: -webkit-flex;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between; /*左右布局*/
}
.item {
  background-color: #fff;
  padding: 1rem;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 0.4rem;
}
.item_header {
  margin-bottom: 0.6rem;
  height: 1.6rem;
  font-size: 1rem;
}

.item_header_right {
  display: inline-block;
  font-size: 0.9rem;
}

.item_header_left img {
  height: 100%;
  display: inline-block;
  vertical-align: middle;
}
.item_header_left span {
  margin-left: 0.4rem;
  display: inline-block;
  vertical-align: middle;
}
.item_header_right span {
  display: inline-flex;
  vertical-align: middle;
}

.item_center {
  background-color: #f8f8f8;
  font-size: 0.9rem;
  margin-bottom: 0.6rem;
  min-height: 3rem;
  padding: 0.4rem;
  vertical-align: middle;
  border-radius: 10px;
}
.item_footer {
  font-size: 0.8rem;
}
</style>
    
    <template>
  <div class="page">
    <van-row>
      <van-col span="24">
        <!--NavBar 导航栏fixed 以及z-index-->
        <van-nav-bar z-index="3" title="进件列表"></van-nav-bar>
        <!--可添加fixed属性-->
      </van-col>
    </van-row>

    <van-row class="center" id="center">
      <van-col span="24">
        <!--Tab 标签页-->
        <!--Tab 标签页-->
        <van-tabs
          v-model="active"
          sticky
          @click="changeAct"
          swipeable
          title-active-color="#05A1E7"
          color="#05A1E7"
        >
          <van-tab v-for="(item,ind) in navtitle" :title="item" :key="ind">
            <van-pull-refresh
              v-model="refreshing"
              loading-text="加载中..."
              success-text="刷新成功"
              @refresh="onRefresh"
            >
              <van-list
                style="min-height: calc(100vh - 147px);"
                v-model="loading"
                :finished="finished"
                finished-text="没有更多了"
                :immediate-check="true"
                @load="onLoad"
                :offset="10"
              >
                <template v-if="list.length>0">
                  <!--<IndexTemp v-for="(item,i) in goodList" :good="item" :key="i"></IndexTemp>-->
                  <!--必须指定高度,否则会影响监听底部,会导致出现不显示滚动条-->
                  <template v-for="(item,index) in list">
                    <!--这种宽度必须指定,否则触发这两次-->
                    <div class="item" :key="index">
                      <div class="item_header flex">
                        <div class="item_header_left">
                          <img src="../../static/image/order-list-icon.png" />
                          <span>{{item.personname}}</span>
                        </div>
                        <div class="item_header_right">
                          <span>{{item.status}}</span>
                          <span class="icon">
                            <van-icon style="vertical-align: middle;" name="arrow"></van-icon>
                          </span>
                        </div>
                      </div>
                      <div class="item_center">
                        <span>
                          <template v-if="!!item.statusinfo">{{item.statusinfo}}</template>
                        </span>
                      </div>
                      <div class="item_footer">订单编号:2131322222222</div>
                    </div>
                  </template>
                </template>

                <template v-else>
                  <div class="default_footer">
                    <img src="../../static/icon/icon_loan_default.png" alt="暂无" />
                    <p>暂时没有该栏目信息</p>
                  </div>
                </template>
              </van-list>
            </van-pull-refresh>
          </van-tab>
        </van-tabs>
      </van-col>
    </van-row>
    <van-row class="footer_">
      <van-col span="24">
        <!--Tabbar 标签栏-->
      </van-col>
    </van-row>
  </div>
</template>
  <script>
import Vue from "vue";
export default {
  data() {
    return {
      active: 0,
      orderColumn: "",
      navtitle: ["全部", "下户", "审批", "签约", "拒绝"],

      list: [], //数据集
      pageNum: 0, //当前页
      pageSize: 1, //加载数据大小

      loading: false, //加载状态
      finished: false, //数据已经加载完
      refreshing: false //下拉刷新状态
    };
  },
  watch: {
    active: function() {
      var self = this;
      this.orderColumn = this.navtitle[this.active];
      if (Vue.cancel != null) {
        Vue.cancel("路由切换时取消axios成功!");
      }
      //
      self.list=[];
      this.pageNum = 1;
      setTimeout(() => {
        this.LogicListData(res => {
          if (res.length < self.pageSize) self.finished = true;
          self.list = res;
        });
        this.refreshing = false; //刷新状态 结束
      }, 1000);
    }
  },
  methods: {
    //切换tab
    changeAct(index) {
      // console.log("切换执行");
      this.active = index;
    },
    GetListData(reqInit) {
      return this.$axios({
        url: reqInit,
        method: "get" // 请求方式
      })
        .then(res => {
          // 请求成功
          if (res.data && res.data.length > 0) {
            //console.log(res.data);
          }
          return res;
        })
        .catch(error => {
          console.log(error);
        });
    },
    async LogicListData(successCallback) {
      var self = this;
      var status = self.orderColumn;
      var statusSql = "";
      switch (status) {
        case "下户":
          statusSql = "and (Status='待下户' or Status='已下户')";
          break;
        case "审批":
          statusSql = "and (Status='待审批' or Status='已审批')";
          break;
        case "签约":
          statusSql = "and (Status='已签约' or Status='已抵押')";
          break;
        case "拒绝":
          statusSql = "and Status='已拒绝'";
          break;
        default:
          break;
      }
      self.loginInfo = JSON.parse(sessionStorage.getItem("loginInfo"));
      var adminName = self.loginInfo.AdminName;
      var cityid = self.loginInfo.CityId;
      var where = "CreateUser='" + adminName + "' and cityid=" + cityid;
      //if (status == "全部") {
      //    statusSql = " and Status <> '已放款'";
      //}

      //如果是渠道代理商
      if (self.loginInfo.LimitName == "渠道代理商") {
        where = "AgentUser='" + adminName + "' and cityid=" + cityid;
      }
      var orderByStr = "";
      //如果是下户专员
      if (
        self.loginInfo.LimitName == "下户专员" ||
        self.loginInfo.LimitName == "下户调度专员"
      ) {
        statusSql = "";
        orderByStr = ",HouseTimeOrder asc";
        where =
          "HouseUser='" +
          adminName +
          "' and Status='待下户' and cityid=" +
          cityid;
        if (status == "全部") {
          where = "HouseUser='" + adminName + "' and cityid=" + cityid;
        }
      }
      //初始化信息
      var sqlInit =
        "select ID,PersonName,CreateUser,StatusInfo,LoanNo,Status,HouseTimeOrder,(select Count(1) as Num from Tbl_LoanAssess where LoanID=Tbl_Loan.Id and DealFlag=0) as IsAssess FROM Tbl_Loan where " +
        where +
        statusSql +
        " and IsValid=1  and DealFlag=0  ORDER BY  DealTime desc" +
        orderByStr;
      // console.log(sqlInit)
      //统计数量
      var sqlTotal =
        "select count(1) from  Tbl_Loan where " +
        where +
        statusSql +
        "  and IsValid=1   and DealFlag=0";

      var token = 123;
      //console.log("数据加载:" + sqlInit);
      var reqInit =
        "/api.ashx?token=" +
        token +
        "&action=data_read&sql=" +
        sqlInit +
        "&pagesize=" +
        self.pageSize +
        "&pageindex=" +
        self.pageNum +
        "&callback=?";

      var reqTotal =
        "/api.ashx?token=" +
        token +
        "&action=data_sql&sql=" +
        sqlTotal +
        "&pagesize=1&pageindex=1&callback=?";

      let res = await this.GetListData(reqInit);
      if (res.data && res.data.length > 0) {
        let res2 = await this.GetListData(reqTotal);
        self.count = JSON.parse(res2.data.result);
      }
      successCallback && successCallback(res.data);
    },
    onLoad() {  //1、页面加载触发直到沾满整个屏幕此时是频繁的请求  2、触发底部就会频繁触发 
      console.log("触发onLoad方法");
      var self = this;
      setTimeout(() => {
        self.pageNum=1;
        //加载状态结束
        self.loading = false; //取消加载
        //加载的情况
        this.LogicListData(res => {
          //异步才可以用await,故onload没加async 只能回调处理
          if (res.length < self.pageSize) self.finished = true;
          res.forEach(element => {
            self.list.push(element);
          });
        });
      }, 1000);
    }, //下拉刷新
    onRefresh() {
      var self = this;
      this.pageNum = 1;
      //this.loading = true; //我之前是反过来了 ? 你都没有弄这个 你只管了正常加载的,没有管刷新时候的 主要是控制这个 你再自己研究一下 ,我要搞事了  嗯嗯 我在啊看看
      //this.list = [];
      setTimeout(() => {
        self.list=[];
        //self.onLoad();
        /*this.LogicListData(res => {  //用onLoad 而不自己写是为了当请求sieze 少的时候,会监听加载满整个屏幕
          //异步才可以用await,故onload没加async 只能回调处理
          if (res.length < self.pageSize) self.finished = true;
          self.list = res;
        });*/
        this.refreshing = false; //刷新状态 结束
        //this.$toast("刷新成功");
        this.loading = true;
        self.onLoad();
        
      }, 1000);
    }, //1、解决主动加载数据
    loadData() {
      if (!this.loading) {
        this.loading = true;
        this.onLoad();
      }
    }
  },
  mounted() {
    this.loadData();
    //let winHeight = document.documentElement.clientHeight; //视口大小
    //document.getElementById("center").style.height = winHeight - 200 + "px"; //调整上拉加载框高度
  }
};
</script> 
    <style scoped>
</style>

具体解决

1、处理了刷新的加载触发load部分

2、影响处理拉动部分的

原文地址:https://www.cnblogs.com/fger/p/12657654.html