在我的Laravel应用程序中,我已经使用Vue创建带有分页的可搜索表。这是源代码:
@extends ('layouts.app')
@section('title', 'Library')
@section ('content')
{{-- Breadcrumbs --}}
@component('components.breadcrumb-bar',
[
'breadcrumbs' => array(
[
'name' => "Home",
'url' => route('welcome-page')
],
[
'name' => "Library",
'url' => route('library.index')
]
)
])
@endcomponent
{{-- Page Header --}}
@component('components.page-header')
Library
@slot('introduction')
Welcome to the Library. Here you can view, download and share all templates and forms from across
the organisation. If you have any queries or ideas on how we can improve this section, contact us.
@endslot
@endcomponent
<div id="library-container">
<div class="container">
<div class="row">
<div class="col-12 col-md-6">
<form method="get" action="{{ route('library.search') }}" class="mb-5">
<div class="input-group">
<input type="text" name="q" class="form-control" id="" autocomplete="off" placeholder="Search the library" v-model="query"/>
<span class="input-group-append">
<button class="btn btn-outline-secondary" type="button" v-on:click="search()">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
</div>
<div class="col-12 col-md-6">
<form>
<select v-model="category" v-on:change="fetch_files_by_category()" class="form-control">
<option value="">Select a category</option>
<option v-for="category in categories" v-bind:value="category">@{{ category }}</option>
</select>
</form>
</div>
<div class="col-12">
<div class="alert alert-info" role="alert" v-if="loading">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
Loading files
</div>
<div class="alert alert-danger" role="alert" v-if="error">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
@{{ error }}
</div>
<table class="table table-library" v-if="shouldDisplayTable">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Category</th>
<th scope="col">Type</th>
<th colspan="2" scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="element in results" v-bind:key="element.id">
<td><span v-html="element.icon"></span><a v-bind:href="'/download/' + element.name">@{{ element.name }}</a></td>
<td>@{{ element.category }}</td>
<td>@{{ element.extension }}</td>
<td>
<a v-bind:href="'/download/' + element.name" class="btn btn-bright-blue">Download</a>
</td>
<td>
<a href="#" v-if="element.is_liked" v-on:click.prevent="like(element)">
<i class="fas fa-heart"></i>
</a>
<a href="#" v-else v-on:click.prevent="like(element)">
<i class="far fa-heart"></i>
</a>
</td>
</tr>
</tbody>
</table>
<ul class="pagination justify-content-end">
<li class="page-item">
<button v-on:click="fetch_results(pagination.prev_page_url)" :disabled="!pagination.prev_page_url" class="page-link">Previous</button>
</li>
<li class="page-item">
<button v-on:click="fetch_results(pagination.next_page_url)" :disabled="!pagination.next_page_url" class="page-link">Next</button>
</li>
</ul>
<p class="justify-content-end">Showing @{{ pagination.from }} of @{{ pagination.to }} of @{{ pagination.total }}</p>
</div>
</div>
</div>
</div>
@endsection
@section('inline-script')
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
new Vue({
el: '#library-container',
data: {
query: '',
categories: '',
category: '',
results: [],
pagination: {},
loading: false,
error: '',
},
computed: {
shouldDisplayTable(){
if(this.loading == true || this.error !== ''){
return false;
}
return true;
}
},
created(){
this.fetch_categories();
this.fetch_results();
},
watch: {
query(after, before) {
this.search();
}
},
methods: {
search: _.debounce(function(){
if(this.query !== ""){
let vm = this;
this.results = [];
this.loading = true;
this.error = '';
axios.get("/library/api/search",{params: {q: this.query}})
.then(response => ([
vm.makePagination(response.data),
this.results = response.data.data,
this.error = response.data.error ? response.data.error : '',
this.loading = false
]))
.catch(this.error = '');
} else{
this.fetch_results();
}
}, 500),
fetch_categories:function(){
axios.get('/library/api/categories')
.then(response => ([
this.categories = response.data
]))
.catch()
},
fetch_results: function(page_url){
let vm = this;
page_url = page_url || '/library/api/all'
this.results = [];
this.loading = true;
this.error = '';
axios.get(page_url)
.then(response => ([
vm.makePagination(response.data),
this.results = response.data.data,
this.loading = false
]))
.catch(this.error = '');
},
fetch_files_by_category: function(){
let vm = this;
this.results = [];
this.loading = true;
this.error = '';
axios.get('/library/api/' + this.category)
.then(response => ([
vm.makePagination(response.data),
this.results = response.data.data,
this.loading = false
]))
.catch(this.error = '');
},
makePagination: function(data){
var pagination = {
from: data.from,
to: data.to,
total: data.total,
current_page: data.current_page,
last_page: data.last_page,
next_page_url: data.next_page_url,
prev_page_url: data.prev_page_url
}
this.pagination = pagination
},
like: function(element){
axios.post('/like/file/' + element.id)
.then(response => ([
element.is_liked == true ? element.is_liked = false : element.is_liked = true
]))
.catch(response => console.log(response.data));
}
}
});
</script>
@endsection
我觉得这不是应该使用Vue的方式。
我的问题是:您将哪些部分分成多个组件,或者您将更进一步,将整个组件做成模板?
这正是我想要的方式,但是以这种方式将Blade and Vue混合在一起感觉不对。