Reputation: 495
Hello everyone I'm new to vue.js and I'm confused whether it is possible to reload a data table (server side rendering) without refreshing the page using a component embedded in a blade.php?
Here is a my code. All of these components are attached in a blade.php file.
Department.vue Component (for adding)
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Add Department / Section</div>
<div class="card-body">
<form @submit.prevent="addData()">
<div class="form-group">
<label class="form-control-label" for="name">Department</label>
<input type="text" class="form-control" v-model="department">
<div v-if="errors.department" :class="['invalid-feedback']">{{ errors.department[0] }}</div>
</div>
<div class="form-group">
<label class="form-control-label" for="name">Section</label>
<input type="text" class="form-control" v-model="section" v-bind:class="{'is-invalid': validate && attemptSubmit && missingName }">
<div v-if="errors.section" :class="['invalid-feedback']">{{ errors.section[0] }}</div>
</div>
<button type="submit" class="btn btn-primary btn-block">Submit</button>
<button class="btn btn-primary btn-block">Edit</button>
</form>
<strong>Output:</strong>
<pre>
{{output}}
</pre>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
axios.get('/api/departments')
.then(response => this.rows = response.data)
.catch(error => console.log(error))
},
data() {
return {
department: '',
section: '',
output: '',
attemptSubmit: false,
validate: false,
errors: [],
};
},
computed: {
missingName() {
return this.section === ''
},
},
methods: {
addData() {
this.attemptSubmit = true;
this.validate = true;
this.errors = [];
if (this.errors) event.preventDefault();
axios
.post('/api/department', {
department: this.department,
section: this.section
})
.then(response => {
this.validate = false;
this.department = '';
this.section = '';
this.errors = '';
this.output = response.data;
})
.catch(error => this.errors = error.response.data.errors)
},
deleteData(id) {
if(confirm('Are you sure?')) {
axios
.delete(`/api/department/${id}`)
.then(response => {this.output = response.data;})
.catch(error => console.log(error))
}
}
}
}
</script>
Project.vue Component (data table)
<template>
<div class="projects">
<div class="tableFilters">
<input class="input" type="text" v-model="tableData.search" placeholder="Search Table"
@input="getProjects()">
<div class="control">
<div class="select">
<select v-model="tableData.length" @change="getProjects()">
<option v-for="(records, index) in perPage" :key="index" :value="records">{{records}}</option>
</select>
</div>
</div>
</div>
<datatable :columns="columns" :sortKey="sortKey" :sortOrders="sortOrders" @sort="sortBy">
<tbody>
<tr v-for="project in projects" :key="project.id">
<td>{{project.id}}</td>
<td>{{project.department_name}}</td>
<td>{{project.created_at}}</td>
<td> <a href="" @click="deleteData(project.id)"><i class="fas fa-trash" ></i></a></td>
</tr>
</tbody>
</datatable>
<pagination :pagination="pagination"
@prev="getProjects(pagination.prevPageUrl)"
@next="getProjects(pagination.nextPageUrl)">
</pagination>
</div>
</template>
<script>
import Datatable from './Datatable.vue';
import Pagination from './Pagination.vue';
export default {
components: { datatable: Datatable, pagination: Pagination },
created() {
this.getProjects();
},
data() {
let sortOrders = {};
let columns = [
{width: '33%', label: 'Deadline', name: 'id' },
{width: '33%', label: 'Budget', name: 'department_name'},
{width: '33%', label: 'Status', name: 'created_at'}
];
columns.forEach((column) => {
sortOrders[column.name] = -1;
});
return {
projects: [],
columns: columns,
sortKey: 'id',
sortOrders: sortOrders,
perPage: ['5', '20', '30'],
tableData: {
draw: 0,
length: 5,
search: '',
column: 0,
dir: 'desc',
},
pagination: {
lastPage: '',
currentPage: '',
total: '',
lastPageUrl: '',
nextPageUrl: '',
prevPageUrl: '',
from: '',
to: ''
},
}
},
methods: {
getProjects(url = '/api/departments') {
this.tableData.draw++;
axios
.get(url, {params: this.tableData})
.then(response => {
let data = response.data;
if (this.tableData.draw == data.draw) {
this.projects = data.data.data;
this.configPagination(data.data);
}
})
.catch(errors => {
console.log(errors);
});
},
configPagination(data) {
this.pagination.lastPage = data.last_page;
this.pagination.currentPage = data.current_page;
this.pagination.total = data.total;
this.pagination.lastPageUrl = data.last_page_url;
this.pagination.nextPageUrl = data.next_page_url;
this.pagination.prevPageUrl = data.prev_page_url;
this.pagination.from = data.from;
this.pagination.to = data.to;
},
sortBy(key) {
this.sortKey = key;
this.sortOrders[key] = this.sortOrders[key] * -1;
this.tableData.column = this.getIndex(this.columns, 'name', key);
this.tableData.dir = this.sortOrders[key] === 1 ? 'asc' : 'desc';
this.getProjects();
},
getIndex(array, key, value) {
return array.findIndex(i => i[key] == value)
},
deleteData(id) {
if(confirm('Are you sure?')) {
axios.delete(`/api/department/${id}`)
.then(response => {
this.output = response.data;
this.$parent.reload();
})
.catch(error => console.log(error))
}
}
}
};
</script>
Upvotes: 1
Views: 2894
Reputation: 840
If you want to use laravel routing then it will refresh when you change the route. There is few ways to create SPA.
I will prefer to use inertiajs/livewire in your case and it can easily integrate with laravel and vuejs.
Upvotes: 2