سلام دوستان
برای ایجاد اسکرول بی نهایت در صفحه پست ها از طریق paginate و vuejs بهترین کار چیه ؟
چطوری دیتا رو به vue پاس بدم ؟ منظورم اینه با props باشه یا مثلا از طریق متد created درخواست axios بفرستم و پست ها رو بگیرم؟
لطفا یک توضیح کامل بدید اگر نمونه کد هم داشته باشید ممنون میشم
درود
همونطور که آقای موسوی اشاره کردند پکیج های آمادهای برای این کار هست اما در کل چیز پیچیدهای نیست
در جاوااسکریپت ... در شئ window رویدادی داریم به نام onscroll که میتونید ازش استفاده کنید; سپس با استفاده از پراپرتیهای scrollTop و offsetHeight از شئ document و پراپرتی innerHeight از شئ window چک کنید که آیا کاربر به پایین صفحه رسیده یا نه.
به طور مثال اگر بخواهیم پستهای یه بلاگ رو اینطوری نمایش بدیم...مراحل کار میتونه شبیه به زیر باشه:
ابتدا تیاز دارید Route های مربوط به API رو که باید شامل حداقل یه پارامتر Current Page باشه پیادهسازی کنید. مثلا آدرس API شما به شکل زیر باشه:
https://yourAPI.com/api/posts/page/1
و اگر هم page رو بهش پاس ندید، صفحه اول رو برگردونه
ابتدا ۲ گزینه رو مقداردهی میکنیم. اولی posts هست که برابر یه آرایه خالی قرار میدیم و دومی currentPage یا صفحه فعلی هست که برابر ۱ قرار میدیم.
قبل از هر کاری وقتی کاربر صفحه رو باز میکنه ما باید صفحه اول رو بهش نشون بدیم.. پس از متد getInitialPosts استفاده میکنیم; این متد با یه درخواست axios پستهای مربوطه رو میگیره و داخل آرایه posts قرار میده. حال کافیه این متد رو قبل از اینکه کامپوننت Mount بشه اجرا کنیم »» پس getInitialPosts رو درون ()beforeMount قرار میدیم.
پس کامپوننت Mount میشه و در این حین اطلاعات اولیه (صفحه اول پستها) رو هم از API دریافت کرده.... حال در بخش Template هم با یه v-for بسادگی آرایه رو پیمایش میکنیم و پست هارو نشون میدیم.
تا اینجا همه کارها، کارهای معمولی بوده که با Vue انجام میشه. برای پیادهسازی اسکرول بی نهایت باید یه متد دیگه هم بسازیم.. پس متدی به نام infiniteScroll اضافه میکنیم و داخلش با استفاده از رویداد window.onscroll چک میکنیم که آیا به انتهای صفحه رسیدیم یا نه.
اگر به انتهای صفحه رسیده باشیم »»» مقدار currentPage رو یکی افزایش میدیم و با یه درخواست axios دیگه اطلاعات صفحه بعد رو دریافت میکنیم و به انتهای آرایه posts اضافه میکنیم...
و چون VueJs از Two-way data binding پشتیبانی میکنه به محض اضافه شدن پست های جدید (به آرایه posts) ، کامپوننت دوباره رندر میشه و اطلاعات جدید رو هم نشون میده.
تنها کاری که باقی میمونه اینه که بعد از اینکه کامپوننت Mount شد (که پس از هر رندر اتفاق میفته)، متد ()infiniteScroll رو فراخوانی کنیم.. پس این متد رو داخل ()mounted قرار میدیم.
کلیت کار به همین روال انجام میشه و بقیه کارها مربوط به UI میشه که مثلا تا وقتی اطلاعات داره برمیگرده یه Loader هم نمایش داده بشه.
قسمت Template کامپوننت:
<template>
<div id="app">
<h1>Posts</h1>
<div v-for="post in posts">
<div class="postCard">
<img :src="post.picture.large" />
</div>
<div>
<p>{{ post.title }} {{ post.created_at }}</p>
<p>{{ post.body }}</p>
</div>
</div>
</div>
</template>
قسمت Script کامپوننت:
<script>
export default {
data() {
return {
posts: [],
currentPage: 1
};
},
methods: {
getInitialPosts() {
axios.get(`https://yourAPI.com/api/posts`).then(response => {
this.posts = response.data;
});
},
infiniteScroll(post) {
window.onscroll = () => {
let bottomOfWindow =
document.documentElement.scrollTop + window.innerHeight ===
document.documentElement.offsetHeight;
if (bottomOfWindow) {
this.currentPage++;
axios
.get(`https://yourAPI.com/api/posts/page/${this.currentPage}`)
.then(response => {
this.posts.push(response.data);
});
}
};
}
},
mounted() {
this.infiniteScroll(this.post);
},
beforeMount() {
this.getInitialPosts();
}
};
</script>
موفق باشید
سلام برای صفحه بندی که اطلاعات رو با props پاس نمیدن
باید درخواست ajax ایجاد کنید.
البته پکیجهای آمادهای برای vue-pagination هم هست که میتونید از اونها هم بهرمند بشید.
درود
همونطور که آقای موسوی اشاره کردند پکیج های آمادهای برای این کار هست اما در کل چیز پیچیدهای نیست
در جاوااسکریپت ... در شئ window رویدادی داریم به نام onscroll که میتونید ازش استفاده کنید; سپس با استفاده از پراپرتیهای scrollTop و offsetHeight از شئ document و پراپرتی innerHeight از شئ window چک کنید که آیا کاربر به پایین صفحه رسیده یا نه.
به طور مثال اگر بخواهیم پستهای یه بلاگ رو اینطوری نمایش بدیم...مراحل کار میتونه شبیه به زیر باشه:
ابتدا تیاز دارید Route های مربوط به API رو که باید شامل حداقل یه پارامتر Current Page باشه پیادهسازی کنید. مثلا آدرس API شما به شکل زیر باشه:
https://yourAPI.com/api/posts/page/1
و اگر هم page رو بهش پاس ندید، صفحه اول رو برگردونه
ابتدا ۲ گزینه رو مقداردهی میکنیم. اولی posts هست که برابر یه آرایه خالی قرار میدیم و دومی currentPage یا صفحه فعلی هست که برابر ۱ قرار میدیم.
قبل از هر کاری وقتی کاربر صفحه رو باز میکنه ما باید صفحه اول رو بهش نشون بدیم.. پس از متد getInitialPosts استفاده میکنیم; این متد با یه درخواست axios پستهای مربوطه رو میگیره و داخل آرایه posts قرار میده. حال کافیه این متد رو قبل از اینکه کامپوننت Mount بشه اجرا کنیم »» پس getInitialPosts رو درون ()beforeMount قرار میدیم.
پس کامپوننت Mount میشه و در این حین اطلاعات اولیه (صفحه اول پستها) رو هم از API دریافت کرده.... حال در بخش Template هم با یه v-for بسادگی آرایه رو پیمایش میکنیم و پست هارو نشون میدیم.
تا اینجا همه کارها، کارهای معمولی بوده که با Vue انجام میشه. برای پیادهسازی اسکرول بی نهایت باید یه متد دیگه هم بسازیم.. پس متدی به نام infiniteScroll اضافه میکنیم و داخلش با استفاده از رویداد window.onscroll چک میکنیم که آیا به انتهای صفحه رسیدیم یا نه.
اگر به انتهای صفحه رسیده باشیم »»» مقدار currentPage رو یکی افزایش میدیم و با یه درخواست axios دیگه اطلاعات صفحه بعد رو دریافت میکنیم و به انتهای آرایه posts اضافه میکنیم...
و چون VueJs از Two-way data binding پشتیبانی میکنه به محض اضافه شدن پست های جدید (به آرایه posts) ، کامپوننت دوباره رندر میشه و اطلاعات جدید رو هم نشون میده.
تنها کاری که باقی میمونه اینه که بعد از اینکه کامپوننت Mount شد (که پس از هر رندر اتفاق میفته)، متد ()infiniteScroll رو فراخوانی کنیم.. پس این متد رو داخل ()mounted قرار میدیم.
کلیت کار به همین روال انجام میشه و بقیه کارها مربوط به UI میشه که مثلا تا وقتی اطلاعات داره برمیگرده یه Loader هم نمایش داده بشه.
قسمت Template کامپوننت:
<template>
<div id="app">
<h1>Posts</h1>
<div v-for="post in posts">
<div class="postCard">
<img :src="post.picture.large" />
</div>
<div>
<p>{{ post.title }} {{ post.created_at }}</p>
<p>{{ post.body }}</p>
</div>
</div>
</div>
</template>
قسمت Script کامپوننت:
<script>
export default {
data() {
return {
posts: [],
currentPage: 1
};
},
methods: {
getInitialPosts() {
axios.get(`https://yourAPI.com/api/posts`).then(response => {
this.posts = response.data;
});
},
infiniteScroll(post) {
window.onscroll = () => {
let bottomOfWindow =
document.documentElement.scrollTop + window.innerHeight ===
document.documentElement.offsetHeight;
if (bottomOfWindow) {
this.currentPage++;
axios
.get(`https://yourAPI.com/api/posts/page/${this.currentPage}`)
.then(response => {
this.posts.push(response.data);
});
}
};
}
},
mounted() {
this.infiniteScroll(this.post);
},
beforeMount() {
this.getInitialPosts();
}
};
</script>
موفق باشید
عالی بود مهندس جان @ali.bayat
منم خیلی درگیر پیاده کردن این مسئله بودم متاسفانه نت نبود. دمت گرم
@ali.bayat
شرمنده میشه قسمت route هم توضیح بدید چطور انجام بدیم که اگه page رو بهش پاس دادیم یا ندادیم کار درست رو انجام بده
ممنون
برای Route های آپشنال باید از علامت سوال استفاده کرد, مثلا:
Route::get('api/posts/{page?}', function ($page = 1) {
});
@miladfathi021
من توی push کردن مشکل دارم دیتا من به شکل زیر ذخیره برگشت داده میشه و وقتی میخوام push کنم میگه همه رو توی یک آرایه push میکنه :
7) […]
0: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
1: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
2: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
3: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
4: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
5: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
6: Object { id: Getter & Setter, user_id: Getter & Setter, address: Getter & Setter, … }
نگاه توی ویو جچوری ذخیره میشن صفحات
orders:Array[9]
0:Object
1:Object
2:Object
3:Object
4:Object
5:Object
6:Object
7:Array[7]
8:Array[5]
هفت یک آرایه ذخیره میگه چطور این مشکل حل کنم
@ghomi2018
شما از webpack استفاده کن اگر خطایی syntax نداری ، build کن و استفاده کن.
چون webpack کدهای اسکریپتت رو به ES5 (مابه قبل تاریخ) کدهات رو کمپایل میکنه که تویی همه مرورگرها کار میکنه :)
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟