Laravel + vue 实现无刷新翻页

2017-08-21 10:25:45

    由于本站的文章主要是分两个模块的,一个是本站文章,一个是外站文章。所以做起列表页来很麻烦。

    一开始我是试过将两个进行合并,成而形成一张表,这样后续的一系列操作将会简单许多。

    但是,合并在一起的效果, 我不喜欢。

    如果不合并的话,分页搞起来将会相当的麻烦。目前看来好像只有两种方案了,一种是在列表页在套一个标签页面,类似于这样

    image.png

    但是我还是不喜欢...没办法,就是那么任性,目前看来只有一种方案了,就是做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">&laquo;</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">&raquo;</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

    这样就完成了我们需要的使有功能,测试通过,特记录。