在 Vue 2.5 實作「無限滾動」功能

做法

src 資料夾的 main.js 檔建立一個滾動指令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Vue.directive('scroll', {
inserted(el, binding) {
const f = (evt) => {
if (binding.value(evt, el)) {
window.removeEventListener('scroll', f);
}
};
window.addEventListener('scroll', f);
},
});

new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');

在元件中使用 v-scroll 指令。

1
2
3
<div
v-scroll="handleScroll"
/>

定義一個 handleScroll() 方法,處理滾動事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default {
methods: {
handleScroll() {
// 獲取捲軸被往下滾動的距離
const scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
// 獲取瀏覽器窗口高度
const { innerHeight } = window;
// 獲取頁面高度
const { offsetHeight } = document.documentElement;
// 當捲軸被滾動到最底部時觸發
if (scrollTop + innerHeight + 1 > offsetHeight) {
// 切換頁碼
this.setPage(this.page + 1);
// 獲取遠端資源
this.getKeys();
}
// 遠端資源回傳空陣列時,停止監聽
return this.noData;
},
},
};

在 Vuex 定義獲取遠端資源的 getKeys() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
getKeys({ commit }) {
return new Promise((resolve, reject) => {
axios({
method: 'GET',
url: '/users/me/keys',
})
.then(({ data }) => {
// 將獲取到的資源合併到現有資源中
commit('setKeys', [...state.keys, ...data.data]);
// 判斷是否為空陣列
commit('setNoData', data.data.length === 0)
resolve(data);
})
.catch((error) => {
reject(error);
});
});
},

參考資料