以asp.net 为后端,结合Vue.js和axios、vue-

作者: 凉风有兴 | 来源:发表于2017-06-08 01:08 被阅读2248次

    滚动加载或者说是无限加载,是一种当今非常流行的列表显示方式。当一个列表内容太长,通常需要使用分页的形式去展现出来,可是老是需要用户去点击下一页又显得很不人道,于是滚动加载的技术就出来了,只要内容滚动到底部,就自动加载出下一页的内容出来,用户体验刚刚的。

    在这个例子当中,我用了asp.net mvc,首先对数据进行分页输出JSON,再利用Vue.js配合axios,通过AJAX的方法获取数据,最后使用vue-infinite-scroll实现滚动加载。

    得到分页数据,在控制器当中,新建一个Getlist,pageIndex代表当前是第几页,pageSize是一页显示多少笔数据,最后totalCount返回一个这个列表的总数据。

    public List<Product> Getlist(int pageIndex, int pageSize, ref int totalCount)
            {
                var list=(from p in listall orderby p.ID descending select p).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                totalCount = listall.Count();
                
                return list.ToList();
            }
    

    接着,我们还需要生成一个已经分页完成的JSON,并且记录好总页数,一并输出:

     [HttpPost]
            public ActionResult ShowthePro(int? page)
            {
                int pageSize = 8;
                int pageIndex = page ?? 1;
                int totalCount = 0;
                
                var listpage = Getlist(pageIndex, pageSize, ref totalCount);
                int totalpage = (totalCount / pageSize) + 1;
                return Json(new {
                    count=totalpage,
                    data=listpage
                }, JsonRequestBehavior.AllowGet);
            }
    

    这个时候,我们先使用Vue.js和axios测试一下不自动分页,看看有没有什么问题。先写js:

       Vue.prototype.$http = axios;
        new Vue({
            el: '#Pro',
            data: {
                peps: ''
            },
            mounted() {
                this.$http.post('/Json/ShowthePro?page=1').then(response=>this.peps = response.data.data);
            }
        })
    

    然后将视图的模板做好:

     <div class="row" id="Pro">
            <article class="work-item" v-for = "pep in peps">
                <a :href=pep.url class="icon fa-desktop" target="_blank"><img :src=pep.img alt="" />
                  <h3>{{pep.name}}</h3></a>
            </article>
    
        </div>
    

    运行成功,接着我们就要用到vue-infinite-scroll来实现滚动加载。

    vue-infinite-scroll Github 主页,可以去这里下载,然后本地加载,当然也可以使用CDN: https://unpkg.com/vue-infinite-scroll

    选项

    选项 说明
    infinite-scroll-disabled 如果此属性的值为true,则无限滚动将被禁用。
    infinite-scroll-distance Number(default = 0)当元素底部与窗口底部的距离达到这个数值时,执行v-infinite-scroll
    infinite-scroll-immediate-check Boolean(default = true)指示在绑定后应立即检查该伪指令。 如果内容不够高以填满可滚动容器,则很有用。
    infinite-scroll-listen-for-event 当Vue实例中发生事件时,无限滚动将再次检查。

    了解了基本应用后,我们首先加载vue-infinite-scroll到我们页面

    <script src="/Scripts/vue-infinite-scroll.js"></script>
    

    接着修改视图代码,对#Pro增加选项:

     <div class="row" id="Pro"  v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
       .......
       </div>
    

    最后修改js代码,这是很关键的一步,我们已经完成后端分页并且以JSON输出,那么在这里我们只需要让其滚动就自动加载分页好的JSON,当页数到达总数时,我们就停止滚动加载。

    从网上扒下一个实例,我们就照这个实例进行修改好了:

    <template>
        <div class="group-container" v-infinite-scroll="getActiveByAxios" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
        </div>
        <load-more tip="正在加载" v-if="showLoading"></load-more>
    </template>
    
      <script>
      import Vue from 'vue'
      import Axios from 'axios'
      import { LoadMore  } from 'vux'
      import infiniteScroll from 'vue-infinite-scroll'
    
      Vue.use(infiniteScroll);
    
     export default{
         data(){
             return {
              showLoading:true,
              busy: false,
              pageInfo:{
                count:0,
                pageIndex:1,
                pageSize:5
              },
             }
         },
         methods:{
             getActiveByAxios(){
                             if((that.pageInfo.pageIndex - 1) * that.pageInfo.pageSize >                     that.pageInfo.count){
                    that.busy = false;
                    that.showLoading = false;
                    return;
                  }
                  Axios.get('url',{
                    params:{
                      pageSize:that.pageInfo.pageSize,
                      pageNum:that.pageInfo.pageIndex
                    }
                  }).then(function (response) {
                    if (response.data.success){
                      let list = response.data.data.commentList;
                      that.comments = that.comments.concat(list);
                      that.pageInfo.count = response.data.data.page.count;
                      that.pageInfo.pageIndex += 1;
                      setTimeout(() => {
                        that.busy = false;
                      }, 10);
                    }
                  }).catch(function (error) {
            
                  })
             }
         }
     }
              
    </script>
    

    我第一次写的时候发生了一点意外,就是没有使用concat连接起来,导致页面一页一页的翻过去但没有累加起来:

    <script>
        Vue.prototype.$http = axios;
        var page = 1;
        
        new Vue({
            el: '#Pro',
            data: {
                pros: ''
            },
            busy: false,
            methods: {
                loadMore: function () {
                    this.busy = true;
                    
                    setTimeout(() => {
                        this.$http.post('/Json/ShowthePro?page=' + page).then(response=>this.pros = response.data.data);
                            this.busy = false;
    
                        }, 1000);
                        page++;
                    
                    //End fro loadMore
    
                }
            }
           
        })
    </script>
    

    可是一旦concat连接起来,JSON数据就会出现连接不上的情况,我在Chorme安装了Vue Dvetool插件后,看到连接的JSON数据发生错误,我觉得是初始化的JSON和第一页的JSON数据concat起来发生错误,那么只要让代码确认初始化的JSON不参与concat就可以了,代码相当简单:

     vm.$http.get('/Json/ShowthePro?page=' + pages).then(
                        function (response) {
                            var list1 = response.data.pros;
    if (vm.pros.length == 0) {
                                this.pros = list1;
                            }
                            else {
                              var list2 = vm.pros;
                                vm.pros = list2.concat(list1);}  
                          pages++;
                            setTimeout(() => {
                                vm.busy = false;
                            }, 1000);
                        });
    

    测试通过。

    为了防止当前页面超过所有页面还要继续读取数据,我这里使用了一个布尔变量,当超过页面总数时,整个无限加载就停止运行。

    完整代码如下:

     Vue.prototype.$http = axios;
        var pages = 1;
        var totrue = true;
        new Vue({
            el: '#Pro',
            data: {
               pros:''
            },
            busy: false,
            methods: {
                loadMore: function () {
                    this.busy = true;
                    var vm = this;
                    if (totrue){
                    vm.$http.get('/Json/ShowthePro?page=' + pages).then(
                        function (response) {
                            var list1 = response.data.pros;
                            var count = response.data.count;
                            console.log(count);
                            if (vm.pros.length == 0) {
                                vm.pros = list1;
                            }
                            else {
                                if (pages <= parseInt(count)){
                                var list2 = vm.pros;
                                vm.pros = list2.concat(list1);
                              
                                }
                                else {
                                    totrue = false;
                                }
                            }
                            pages++;
                            setTimeout(() => {
                                vm.busy = false;
                            }, 1000);
                        });
                    } else {
    
                    }
                    //End fro loadMore
    
                }
            }
           
        })
    

    每次开始一个新的框架或者新的语言,就像初恋中的男女一样,在没有确定关系之前各种试探各种伤害,等到完全上手以后,各种温柔各种甜蜜~~

    相关文章

      网友评论

        本文标题:以asp.net 为后端,结合Vue.js和axios、vue-

        本文链接:https://www.haomeiwen.com/subject/gjkzfxtx.html