--- 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/)