一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

實現(xiàn)一個簡單的vue無限加載指令方法

 夢想成為的樣子 2017-08-28

vue 中的自定義指令是對底層 dom 進行操作,下面以實現(xiàn)滾動到底部加載數(shù)據(jù),實現(xiàn)無限加載來介紹如何自定義一個簡單的指令。

無限加載的原理是通過對滾動事件的監(jiān)聽,每一次滾動都要獲取到已滾動的距離,如果滾動的距離加上瀏覽器窗口高度,會大于等于內(nèi)容高度,就觸發(fā)函數(shù)加載數(shù)據(jù)。

先介紹不使用 vue 的情況如何實現(xiàn)無限加載。

不使用框架

首先是html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html><html lang="en">
<head><meta charset="UTF-8">
<title>實現(xiàn)滾動加載</title>
<style>
 * {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  }
 li, ul {
  list-style: none;
 }
 .container {
  width: 980px;
  margin: 0 auto;
 }
 .news__item {
  height: 80px;
  margin-bottom: 20px;
  border: 1px solid #eee;
 }</style>
</head>
<body>
<div class="container">
 <ul class="news" id="news">
  <li class="news__item">1、hello world</li>
  <li class="news__item">2、hello world</li>
  <li class="news__item">3、hello world</li>
  <li class="news__item">4、hello world</li>
  <li class="news__item">5、hello world</li>
  <li class="news__item">6、hello world</li>
  <li class="news__item">7、hello world</li>
  <li class="news__item">8、hello world</li>
  <li class="news__item">9、hello world</li>
  <li class="news__item">10、hello world</li>
 </ul>
</div>
</body>
</html>

打開瀏覽器,調(diào)整下瀏覽器窗口高度,讓頁面可以滾動。

先了解三個變量

  • document.body.scrollTop 滾動條滾動的距離
  • window.innerHeight 瀏覽器窗口高度
  • document.body.clientHeight 內(nèi)容高度

對應(yīng)上面的原理就是

1
2
3
4
5
6
7
8
9
10
window.addEventListener('scroll', function() {
 var scrollTop = document.body.scrollTop;
 if(scrollTop + window.innerHeight >= document.body.clientHeight) {
  // 觸發(fā)加載數(shù)據(jù)   
  loadMore();
 }
});
function loadMore() {
 console.log('加載數(shù)據(jù)')'
}

loadMore() 函數(shù)就是從接口獲取到數(shù)據(jù),組裝 html,插入到原先到節(jié)點后面。

1
2
3
4
5
6
7
8
9
10
11
12
// 表示列表的序號
var index = 10;
function loadMore() {
 var content = '';
 for(var i=0; i< 10; i++) {
  content += '<li class="news__item">'+(++index)+'、hello world</li>' 
 }
 var node = document.getElementById('news');
 // 向節(jié)點內(nèi)插入新生成的數(shù)據(jù) 
 var oldContent =   node.innerHTML;
 node.innerHTML = oldContent+content;
}

這樣就實現(xiàn)了無限加載。

在 vue 中使用指令實現(xiàn)

為什么要用指令實現(xiàn)呢?好像只有指令是可以獲取到底層 dom 的?而實現(xiàn)無限加載,是需要拿到內(nèi)容高度的。

首先初始化一個項目,添加一個組件,用來顯示列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// components/Index.vue
<template>
 <div>
  <ul class="news">
   <li class="news__item" v-for="(news, index) in newslist">
    {{index}}-{{news.title}}
   </li>
  </ul>
 </div>
</template>
<style>
 .news__item {
  height: 80px;
  border: 1px solid #ccc;
  margin-bottom: 20px;
 }
</style>
<script>
 export default{
  data(){
   return{
    newslist: [
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'}
    ]
   }
  }
 }
</script>

OK,現(xiàn)在開始編寫指令。從傳統(tǒng)實現(xiàn)中,我們了解到要注冊對滾動事件對監(jiān)聽,同時拿到內(nèi)容高度。

1
2
3
4
5
6
7
8
9
10
11
directives: {
 scroll: {
  bind: function (el, binding){
   window.addEventListener('scroll', ()=> {
    if(document.body.scrollTop + window.innerHeight >= el.clientHeight) {
     console.log('load data');
    }
   })
  }
 }
}

首先是在組件內(nèi)注冊了 scroll 指令,然后在指令第一次綁定到組件時,也就是對應(yīng)著 bind鉤子,注冊滾動監(jiān)聽。

鉤子函數(shù)就是一些生命周期改變時會調(diào)用的函數(shù)。bind 在第一次綁定到組件時調(diào)用、unbind 在指令與組件解綁時調(diào)用。

還可以注意到 bind 對應(yīng)到函數(shù)有兩個參數(shù),el 和 binding,這是鉤子函數(shù)參數(shù),比如 el 對應(yīng)綁定的節(jié)點,binding 有很多數(shù)據(jù),比如傳給指令的參數(shù)等。

下面的el.clientHeight就是表示獲取綁定指令的這個節(jié)點的內(nèi)容高度。

和之前一樣,判斷滾動的高度加上窗口高度是否大于內(nèi)容高度。

綁定指令到節(jié)點上:

1
2
3
4
5
6
7
8
9
<template>
 <div v-scroll="loadMore">
  <ul class="news">
   <li class="news__item" v-for="(news, index) in newslist">
    {{index}}-{{news.title}}
   </li>
  </ul>
 </div>
</template>

可以看到給指令傳了一個值,這個值就是加載數(shù)據(jù)的函數(shù):

1
2
3
4
5
6
7
8
9
methods: {
 loadMore() {
  let newAry = [];
  for(let i = 0; i < 10; i++) {
   newAry.push({title: 'hello world'})
  }
  this.newslist = [...this.newslist, ...newAry];
 }
}

當然,現(xiàn)在在滾動到底部時,只會打印load data,只要把這里改成調(diào)用函數(shù)就OK了:

1
2
3
4
5
6
window.addEventListener('scroll', ()=> {
 if(document.body.scrollTop + window.innerHeight >= el.clientHeight) { 
  let fnc = binding.value; 
  fnc();
 }
})

v-scroll="loadMore"的 loadMore可以在鉤子函數(shù)參數(shù)的 binding 上拿到。

至此,一個簡單的指令就完成了。

優(yōu)化

上面的例子并沒有真正從接口獲取數(shù)據(jù),所以存在一個隱藏的 bug:當接口響應(yīng)很慢的情況,滾動到底部正在加載數(shù)據(jù)時,稍微滾動一下仍會觸發(fā)獲取數(shù)據(jù)函數(shù),這會造成同時請求多次接口,一次性返回大量數(shù)據(jù)。

解決辦法是添加一個全局變量 scrollDisable,當?shù)谝淮斡|發(fā)加載數(shù)據(jù)函數(shù)時,將該值設(shè)置為 true,根據(jù)該值判斷是否要執(zhí)行加載函數(shù)。

以普通實現(xiàn)為例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var scrollDisable = false;
window.addEventListener('scroll', function() {
 var scrollTop = document.body.scrollTop;
 if(scrollTop + window.innerHeight >= document.body.clientHeight) {
  // 觸發(fā)加載數(shù)據(jù)   
  if(!scrollDisable) {
   //
   loadMore();
  }
 }
});
// 表示列表的序號
var index = 10;
function loadMore() {
  // 開始加載數(shù)據(jù),就不能再次觸發(fā)這個函數(shù)了
 scrollDisable = true;
 var content = '';
 for(var i=0; i< 10; i++) {
  content += '<li class="news__item">'+(++index)+'、hello world</li>' 
 }
 var node = document.getElementById('news');
 // 向節(jié)點內(nèi)插入新生成的數(shù)據(jù) 
 var oldContent =   node.innerHTML;
 node.innerHTML = oldContent+content;
 // 插入數(shù)據(jù)完成后 
 scrollDisable = false;
}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

原文鏈接:http://www.jianshu.com/p/47c086dab73d

如對本文有疑問,請?zhí)峤坏浇涣魃鐓^(qū),廣大熱心網(wǎng)友會為你解答??! 點擊進入社區(qū)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    亚洲男人天堂成人在线视频| 国产女同精品一区二区| 中文字幕亚洲精品人妻| 国产免费一区二区三区不卡| 欧美极品欧美精品欧美| 国产中文字幕久久黄色片| 91日韩在线观看你懂的| 中文字幕高清不卡一区| 国产在线视频好看不卡| 亚洲男人的天堂久久a| 中文字幕久热精品视频在线| 亚洲国产精品久久琪琪| 99一级特黄色性生活片| 亚洲高清中文字幕一区二三区| 黄色片国产一区二区三区| 国产精品久久精品国产| 日本黄色高清视频久久| 欧美乱妇日本乱码特黄大片| 日本人妻的诱惑在线观看| 精品欧美日韩一区二区三区 | 久久人人爽人人爽大片av| 东京不热免费观看日本| 国产一级二级三级观看| 久久99亚洲小姐精品综合| 国产一区麻豆水好多高潮| 国产传媒免费观看视频| 丰满人妻熟妇乱又乱精品古代| 色丁香一区二区黑人巨大| 人妻少妇av中文字幕乱码高清| 欧美成人免费视频午夜色| 国内九一激情白浆发布| 欧美日韩国产一级91| 国产肥妇一区二区熟女精品| 亚洲欧美中文字幕精品| 不卡免费成人日韩精品| 欧美六区视频在线观看| 欧美日韩亚洲国产av| 老熟妇乱视频一区二区| 亚洲一区二区三区三州| 亚洲精品一区三区三区| 日本一区二区三区久久娇喘|