在 Laravel 中使用 Vue 實現滾動載入
在工作中有做到通知功能,想說可以讓通知呈現像 FB 這樣的效果
安裝 vue-infinite-loading
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
在組件中使用
<template> <infinite-loading></infinite-loading> </template>
<script> import InfiniteLoading from 'vue-infinite-loading';
export default { components: { InfiniteLoading, }, }; </script>
|
範例
Vue
將InfiniteLoading
組件放在列表的底部,監聽infinite
事件觸發infiniteHandler
方法,當滾動資料載入完畢,則顯示無通知,可以利用slot 特殊屬性來配置不同情況。
並通過$state.loaded
方法告訴這個插件我們還有數據,如果 API 返回一個空數組,我們將通過$state.complete
方法告訴這個插件所有數據都已加載。
<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
訪問,
public function __construct() { $this->middleware('auth'); } public function index(Request $request) { $user = $request->user(); $query = $user->unreadNotifications(); $notifications = $query->paginate(5); $notifications->getCollection()->transform(function ($value) { $value->created = $value->created_at->toIso8601String(); return $value; }); $total = $user->unreadNotifications->count();
return compact('notifications', 'total'); }
|