---
tags: PHP, Laravel, Backend, Vue
---
# 在Laravel中使用Vue實現滾動載入
在工作中有做到通知功能,想說可以讓通知呈現像FB這樣的效果
## 安裝vue-infinite-loading
[vue-infinite-loading](https://github.com/PeachScript/vue-infinite-loading)
### npm
`npm install vue-infinite-loading -S`
### CDN
`<script src="https://unpkg.com/vue-infinite-loading@^2/dist/vue-infinite-loading.js"></script>`
## Component
在組件中使用
```javascript=
<template>
<infinite-loading></infinite-loading>
</template>
<script>
import InfiniteLoading from 'vue-infinite-loading';
export default {
components: {
InfiniteLoading,
},
};
</script>
```
## 範例
### Vue
將`InfiniteLoading`組件放在列表的底部,監聽`infinite`事件觸發`infiniteHandler`方法,當滾動資料載入完畢,則顯示無通知,可以利用[slot特殊屬性](https://vuejs.org/v2/api/index.html#slot)來配置不同情況。
並通過`$state.loaded`方法告訴這個插件我們還有數據,如果 API 返回一個空數組,我們將通過`$state.complete`方法告訴這個插件所有數據都已加載。
```javascript=
<template>
<div v-for="(item, index) in notifications" :key="item.id">
<!-- 通知迴圈 -->
</div>
<infinite-loading @infinite="infiniteHandler">
<div slot="spinner">載入中...</div>
<div slot="no-more">無更多通知</div>
<div slot="no-results">
暫無通知
</div></infinite-loading
>
</template>
<script>
import InfiniteLoading from 'vue-infinite-loading';
export default {
components: {
InfiniteLoading,
},
data: () => ({
notifications: [],
page: 0
}),
methods: {
/**
* 滾動載入通知.
*/
infiniteHandler($state) {
axios
.get("/notifications", {
params: { page: (this.page = this.page += 1) },
})
.then(({ data: { total, notifications } }) => {
this.total = total;
notifications.data.map(({ id, data, created }) => {
this.notifications.push({
id: id,
title: data.title,
body: data.body,
created: created,
action_url: data.action_url,
img_url: data.img_url,
});
});
if (notifications.current_page == notifications.last_page) {
$state.complete();
} else {
$state.loaded();
}
});
},
}
};
</script>
```
### Controller
在`controller`取得資料庫未讀通知的分頁資料,可改變`page`參數取得不同頁數資料,通過此網址範例`https://example.com.tw/notifications?page=1`訪問,
```php=
public function __construct()
{
$this->middleware('auth');
}
public function index(Request $request)
{
$user = $request->user(); // 當前user
$query = $user->unreadNotifications(); // 取得未讀訊息
$notifications = $query->paginate(5); // 通知五個為一頁
$notifications->getCollection()->transform(function ($value) {
// 日期時間轉換為 ISO 8601
$value->created = $value->created_at->toIso8601String();
return $value;
});
$total = $user->unreadNotifications->count(); // 未讀訊息數
return compact('notifications', 'total');
}
```
更詳細介紹請看[Documentation](https://peachscript.github.io/vue-infinite-loading/)