在 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');
 }
 
 |