- _nosay
Laravel + vue 实现无刷新翻页
2017-08-21 10:25:45
由于本站的文章主要是分两个模块的,一个是本站文章,一个是外站文章。所以做起列表页来很麻烦。
一开始我是试过将两个进行合并,成而形成一张表,这样后续的一系列操作将会简单许多。
但是,合并在一起的效果, 我不喜欢。
如果不合并的话,分页搞起来将会相当的麻烦。目前看来好像只有两种方案了,一种是在列表页在套一个标签页面,类似于这样
但是我还是不喜欢...没办法,就是那么任性,目前看来只有一种方案了,就是做ajax静态无刷新翻页,这样的话,就可以实现一个页面有多个翻页此类的骚操作了。
于是我决定使用vue把这个模块话,目标是只要给vue模块传入url地址,然后配合jquery就可以完成翻页,这样的话比较友好,方便以后重用,说干就干。
首先需要在resource/assets/admin/js/components中建立Page.vue文件,文件内容为:
< template> <nav> <ul class="pagination"> <li v-if="pagination.current_page > 1"> <a href="#" aria-label="Previous" @click.prevent="changePage(pagination.current_page - 1)"> <span aria-hidden="true">«</span> </a> </li> <li v-for="page in pagesNumber" v-bind:class="[ page == isActived ? 'active' : '']"> <a href="#" @click.prevent="changePage(page)">{{ page }}</a> </li> <li v-if="pagination.current_page < pagination.last_page"> <a href="#" aria-label="Next" @click.prevent="changePage(pagination.current_page + 1)"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </template> <script> export default { props:['url','category_id'], mounted() { this.fetchItems(this.pagination.current_page); }, data() { return { pagination: { total: 0, per_page: 7, from: 1, to: 0, current_page: 1 }, offset: 4, items: [] } }, computed: { isActived: function () { return this.pagination.current_page; }, pagesNumber: function () { if (!this.pagination.to) { return []; } var from = this.pagination.current_page - this.offset; if (from < 1) { from = 1; } var to = from + (this.offset * 2); if (to >= this.pagination.last_page) { to = this.pagination.last_page; } var pagesArray = []; while (from <= to) { pagesArray.push(from); from++; } return pagesArray; } }, methods: { fetchItems: function (page) { var data = {page: page}; axios.get(this.url + '/' + this.category_id, { params: data }) .then(response =>{ this.pagination = response.data.pagination; $('.articles_content').html(response.data.data); }).catch(function(err){ }); }, changePage: function (page) { console.log(page); this.pagination.current_page = page; this.fetchItems(page); } } } </script>
这里我们需要传入两个参数,一个是分类的id,另一个就是请求的url,接着我们注册这个vue文件,以供全局使用,在上一级文件夹的app.js文件中,加入
Vue.component('vue-page', require('./components/Page.vue'));
然后在控制台执行
sudo npm run dev
这样我们就完成了vue模块,我们只需要在应该使用的地方,使用注册的标签vue-page调用即可,如
<vue-page url="/api/vue/getArticles" category_id="{{ $id }}"></vue-page>
我们在路由中注册此url,并指定相应控制器,如下
$router->get('getArticles/{id}','CommonController@getArticles')->where('id', '[0-9]+'); $router->get('getAutoArticles/{id}','CommonController@getAutoArticles')->where('id', '[0-9]+');
相应控制器代码为
public function getArticles($id) { $category = (new CategoryRepository())->getCategoryById($id); $results = (new ArticleRepository())->getArticleByCategory($id,$category,'2'); $response = [ 'pagination' => [ 'total' => $results->total(), 'per_page' => $results->perPage(), 'current_page' => $results->currentPage(), 'last_page' => $results->lastPage(), 'from' => $results->firstItem(), 'to' => $results->lastItem() ], 'data' => view('frontpage.category.articles',compact('results'))->render() ]; return $response; }
然后我们只需建立frontpage/category/articles文件,内容为
@inject('categoryPresenter','App\Presenter\CategoryPresenter') @foreach($results as $key => $value) <article> <a href="{{ route('frontpage.article.show',$value->id) }}" class="image"><img src="{{ env('IMG_URL').$value->category->thumb_img->true_path }}" alt="" /></a> <a href="{{ route('frontpage.article.show',$value->id) }}"><strong style="font-size:14px;">{{ $value->title }}</strong></a> <p class="top10"><em>{{ $value->created_at }}</em></p> <p> {!! str_limit(clean(strip_tags($value->content)),200,'...') !!}</p> <p>分类:<a rel="nofollow" target="_blank" href="#">{{ $categoryPresenter->getParentCategory($value->category_id)->name }}</a> / <a rel="nofollow" target="_blank" href="#">{{ $value->category->name }}</a></p> <p>标签: @foreach($value->tags as $tag) <span class="label"><a href="#{{ $tag->id }}">{{$tag->name}}</a></span> @endforeach </p> </article> @endforeach
这样就完成了我们需要的使有功能,测试通过,特记录。