我在 Vue 中制作了我的第一個專案。
我有一個小問題。我需要從 Datatable 中獲取一個值(在代碼中標記:console.log (self.selectedContent); // 這是我的結果@@) - 到我的主視圖并顯示它。我怎樣才能做到這一點?
我的 Main.vue:
<template>
<CCard>
<CCardHeader>
<CIcon name="cil-input-power"/>
Dodaj zlecenie
</CCardHeader>
<CCardBody>
<CRow>
<CCol sm="12">
<CForm>
<div class="tab-content py-3" id="myTabContent">
<div class="tab-pane fade" :class="{ 'active show': isActive('tab1') }" id="tab1">
<h4 class="py-3 d-inline-block pe-5 me-5">Dane przewo?nika </h4>
<CButton
@click="warningModal = true"
color="primary"
>
Uzupe?nij
</CButton>
<CInput
v-model.trim="$v.form.carrier_id.$model"
:isValid="checkIfValid('carrier_id')"
type="hidden"
/>
<CRow>
<CCol md="6">
<CInput
maxlength="255"
label="Nazwa przewo?nika*"
v-model.trim="$v.form.carrier_name.$model"
:isValid="checkIfValid('carrier_name')"
placeholder="Wpisz nazw? przewo?nika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
<CCol md="6">
<CInput
maxlength="255"
label="NIP przewo?nika*"
v-model.trim="$v.form.carrier_nip.$model"
:isValid="checkIfValid('carrier_nip')"
placeholder="Wpisz NIP przewo?nika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
</CRow>
<CRow>
<CCol md="6">
<CInput
maxlength="255"
label="Regon przewo?nika*"
v-model.trim="$v.form.carrier_regon.$model"
:isValid="checkIfValid('carrier_regon')"
placeholder="Wpisz regon przewo?nika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
<CCol md="6">
<CInput
maxlength="255"
label="Email przewo?nika*"
v-model.trim="$v.form.carrier_email.$model"
:isValid="checkIfValid('carrier_email')"
placeholder="Wpisz email przewo?nika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
</CRow>
<CRow>
<CCol md="6">
<CInput
maxlength="255"
label="Telefon przewo?nika*"
v-model.trim="$v.form.carrier_phone.$model"
:isValid="checkIfValid('carrier_phone')"
placeholder="Wpisz telefon przewo?nika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
<CCol md="6">
<CInput
maxlength="255"
label="Kod pocztowy przewodnika*"
v-model.trim="$v.form.carrier_postal_code.$model"
:isValid="checkIfValid('carrier_postal_code')"
placeholder="Wpisz kod pocztowy przewodnika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
</CRow>
<CRow>
<CCol md="6">
<CInput
maxlength="255"
label="Adres przewo?nika*"
v-model.trim="$v.form.carrier_street.$model"
:isValid="checkIfValid('carrier_street')"
placeholder="Wpisz adres przewo?nika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
<CCol md="6">
<CInput
maxlength="255"
label="Miasto przewodnika*"
v-model.trim="$v.form.carrier_city.$model"
:isValid="checkIfValid('carrier_city')"
placeholder="Wpisz miasto przewodnika"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
</CRow>
<CRow>
<CCol md="12">
<CInput
maxlength="255"
label="Email do powiadomień*"
v-model.trim="$v.form.carrier_email_to_notification.$model"
:isValid="checkIfValid('carrier_email_to_notification')"
placeholder="Wpisz email do powiadomień"
invalidFeedback="To pole jest wymagane i musi zawiera? minimum 3 znaki i maksimum 255 znaków"
/>
</CCol>
</CRow>
<h4 class="py-3">Kierowca </h4>
<CRow>
<CCol md="12">
<CSelect id="driver_id"
label="Wybierz kierowc?"
v-model.trim="$v.form.driver_id.$model"
:options="drivers"
>
</CSelect>
</CCol>
</CRow>
<h4 class="py-3">Rodzaj przewo?onego towaru </h4>
<template v-for="(option) in productDircionary">
<div class="form-group form-row" :key="option.name">
<CCol sm="12">
<input type="checkbox" name="selectedProducts[]" :value="option.value" v-model="selectedProducts"
:id="option.value" :checked="selectedProducts.includes(option.value)"/> {{ option.label }}
</CCol>
</div>
</template>
<div>wybrano: {{ selectedProducts }}</div>
<h4 class="py-3">Wymagane dokumenty </h4>
<template v-for="(option) in documentDircionary">
<div class="form-group form-row" :key="option.name">
<CCol sm="12">
<input type="checkbox" name="selectedDocuments[]" :value="option.value"
v-model="selectedDocuments" :id="option.value"
:checked="selectedDocuments.includes(option.value)"/> {{ option.label }}
</CCol>
</div>
</template>
<div>wybrano: {{ selectedDocuments }}</div>
<h4 class="py-3">Wymagane pliki dla dostawcy </h4>
<template v-for="(option) in fileDircionary">
<div class="form-group form-row" :key="option.name">
<CCol sm="12">
<input type="checkbox" name="selectedFiles[]" :value="option.value" v-model="selectedFiles"
:id="option.value" :checked="selectedFiles.includes(option.value)"/> {{ option.label }}
</CCol>
</div>
</template>
<div>wybrano: {{ selectedFiles }}</div>
<CButton
color="primary"
@click="submit"
>
Zapisz
</CButton>
<CButton
class="ml-1"
color="success"
@click="goBack"
>
Cofnij
</CButton>
</div>
<div class="tab-pane fade" :class="{ 'active show': isActive('tab2') }" id="tab2">Historia zmian</div>
<div class="tab-pane fade" :class="{ 'active show': isActive('tab3') }" id="tab3">Pliki</div>
<div class="tab-pane fade" :class="{ 'active show': isActive('tab4') }" id="tab4">
<CRow>
<CCol md="12">
<CTextarea
label="Uwagi do dostawy"
placeholder="Uwagi do dostawy"
rows="9"
v-model.trim="$v.form.deliver_comments.$model"
/>
</CCol>
</CRow>
<CRow>
<CCol md="12">
Podpis odbiorcy delivery_signature
</CCol>
</CRow>
<CButton
color="primary"
@click="submit"
>
Zapisz
</CButton>
<CButton
class="ml-1"
color="success"
@click="goBack"
>
Cofnij
</CButton>
</div>
</div>
</CForm>
<br/>
<div>
<CModal
title="Wybierz przewo?nika"
color="info"
:show.sync="warningModal"
size="xl"
:closeOnBackdrop=true
@closed="closedEvent"
:centered="true"
:onclose="closedEvent"
>
<data-table-select
:fetch-url="datatTableUrl"
:columns="['id', 'email', 'name', 'surname']"
:headers="{'id': 'ID','email': 'Email','name': 'Imi?','surname': 'Nazwisko'}"
:routeName="routeName"
></data-table-select>
</CModal>
</div>
</CCol>
</CRow>
</CCardBody>
</CCard>
</template>
<script>
import axios from 'axios';
import Vue from 'vue';
import CKEditor from 'ckeditor4-vue';
import Swal from "sweetalert2";
import {validationMixin} from "vuelidate"
import {required, minLength, email, sameAs, helpers} from "vuelidate/lib/validators"
import Datepicker from 'vuejs-datepicker';
import {pl} from 'vuejs-datepicker/dist/locale'
import DataTableSelect from "../../components/DataTableSelect";
export default {
components: {
DataTableSelect,
Datepicker
},
data() {
return {
warningModal: false,
datatTableUrl: '',
routeName: 'carriers',
modalClasses: ['modal', 'fade'],
checkedNames: [],
pl: pl,
activeItem: 'home',
form: {
carrier_id: null,
carrier_name: null,
carrier_nip: null,
carrier_regon: null,
carrier_email: null,
carrier_postal_code: null,
carrier_street: null,
carrier_city: null,
carrier_email_to_notification: null,
driver_id: null,
comments: null,
transport_content: null,
deliver_comments: null,
carrier_phone: null,
},
confirmationTypes: [],
transportTypes: [],
drivers: [],
productDircionary: [],
documentDircionary: [],
fileDircionary: [],
selectedProducts: [],
selectedDocuments: [],
selectedFiles: [],
}
},
computed: {
formString() {
return JSON.stringify(this.form, null, 4)
},
isValid() {
return !this.$v.form.$invalid
},
isDirty() {
return this.$v.form.$anyDirty
},
},
mixins: [validationMixin],
validations: {
form: {
speed_number: {
required,
minLength: minLength(3),
maxLength: 255
},
...
}
},
methods: {
closedEvent(){
alert();
},
isActive(menuItem) {
return this.activeItem === menuItem
},
setActive(menuItem) {
this.activeItem = menuItem
},
goBack() {
this.$router.replace({path: '/tasks'})
},
checkIfValid(fieldName) {
const field = this.$v.form[fieldName]
if (!field.$dirty) {
return null
}
return !(field.$invalid || field.$model === '')
},
store() {
let self = this;
axios.post(this.$apiAdress '/api/tasks?token=' localStorage.getItem("api_token"),
{
carrier_id: self.form.carrier_id,
carrier_name: self.form.carrier_name,
carrier_nip: self.form.carrier_nip,
carrier_regon: self.form.carrier_regon,
carrier_email: self.form.carrier_email,
carrier_postal_code: self.form.carrier_postal_code,
carrier_street: self.form.carrier_street,
carrier_city: self.form.carrier_city,
carrier_email_to_notification: self.form.carrier_email_to_notification,
driver_id: self.form.driver_id,
comments: self.form.comments,
transport_content: self.form.transport_content,
deliver_comments: self.form.deliver_comments,
carrier_phone: self.form.carrier_phone,
selected_products: self.selectedProducts,
selected_documents: self.selectedDocuments,
selected_files: self.selectedFiles,
})
.then(function (response) {
if (response.data.status == 'success') {
Swal.fire(
'Sukces',
'Rekord dodany poprawnie!',
'success'
).then(function () {
// self.$router.push('/tasks');
});
} else {
Swal.fire(
'B??d',
response,
'error'
)
}
}).catch(function (error) {
if (error.response.data.message != '') {
let errorDetails = ""
for (let key in error.response.data.errors) {
errorDetails = `${error.response.data.errors[key]}<br/>`
}
Swal.fire(
'B??d',
errorDetails,
'error'
)
window.scrollTo({top: 0});
} else {
Swal.fire(
'B??d',
error,
'error'
)
self.$router.push({path: 'login'});
}
});
},
submit() {
let self = this;
Swal.fire({
title: "Czy zapisa? dane",
text: "zlecenia w bazie?",
type: "question",
showCancelButton: true,
confirmButtonText: "Tak, zapisz",
cancelButtonText: "Anuluj",
reverseButtons: true
}).then(function (result) {
if (result.value) {
self.runSubmit();
}
});
},
runSubmit() {
let self = this;
self.validate();
if (!this.$v.form.$invalid) {
this.store();
}
},
validate() {
this.$v.$touch()
},
reset() {
this.form = this.getEmptyForm()
this.submitted = false
this.$v.$reset()
},
getEmptyForm() {
return {
speed_number: null,
order_number: null,
data_start: null,
data_finish: null,
address_from: null,
address_to: null,
is_neutral_option: null,
transport_type: null,
carrier_id: null,
carrier_name: null,
carrier_nip: null,
carrier_regon: null,
carrier_email: null,
carrier_postal_code: null,
carrier_street: null,
carrier_city: null,
carrier_email_to_notification: null,
driver_id: null,
comments: null,
transport_content: null,
deliver_comments: null,
carrier_phone: null,
selected_products: null,
selectedProducts: [],
selectedDocuments: [],
selectedFiles: [],
}
}
},
created: function () {
this.datatTableUrl = Vue.prototype.$apiAdress '/api/tasks/carriers-table?token=' localStorage.getItem("api_token");
let self = this;
self.setActive('tab1');
axios.get(this.$apiAdress '/api/tasks/create?token=' localStorage.getItem("api_token"))
.then(function (response) {
self.confirmationTypes = response.data.confirmationTypes;
self.drivers = response.data.drivers;
self.transportTypes = response.data.transportTypes;
self.productDircionary = response.data.productDircionary;
self.documentDircionary = response.data.documentDircionary;
self.fileDircionary = response.data.fileDircionary;
}).catch(function (error) {
console.log(error);
self.$router.push({path: '/login'});
});
}
}
</script>
和資料表:
<template>
<div>
<div class="row mb-3">
<div class="col-3">
<div class="input-group">
<input
v-model="search"
class="form-control"
placeholder="Szukaj..."
type="text"
@keyup.enter="handleSearch"
>
<div class="input-group-append">
<button class="btn btn-primary" type="button" @click.prevent="handleSearch">
<font-awesome-icon icon="fas fa-search"/>
</button>
</div>
</div>
</div>
<div class="col-2">
<div class="input-group">
<label for="pageOption" class="mt-2 mr-2">Na stronie</label>
<select class="form-control" v-model="perPage" @change="handlePerPage" id="pageOption">
<option v-for="page in pageOptions" :key="page" :value="page">{{ page }}</option>
</select>
</div>
</div>
</div>
<table class="table table-hover">
<thead>
<tr>
<th class="table-head">#</th>
<th v-for="(label, column) in headers" :key="column" @click="sortByColumn(column)" class="table-head">
{{ label | columnHead }}
<span v-if="column === sortedColumn">
<font-awesome-icon v-if="order === 'asc'" icon="fas fa-angle-up" />
<font-awesome-icon v-else icon="fas fa-angle-down" />
</span>
</th>
<th class="table-head">Opcje</th>
</tr>
</thead>
<tbody>
<tr class="" v-if="tableData.length === 0">
<td class="lead text-center" :colspan="columns.length 1">Brak danych do wy?wietlenia.</td>
</tr>
<tr v-for="(data, key1) in tableData" :key="data.id" class="m-datatable__row" v-else>
<td>{{ serialNumber(key1) }}</td>
<td v-for="(value, key) in data" style="cursor: pointer">{{ value }}</td>
<td><button class="btn btn-primary" @click="prepareAddToTask(data.id)">Wybierz</button></td>
</tr>
</tbody>
</table>
<nav v-if="pagination && tableData.length > 0">
<ul class="pagination">
<li class="page-item" :class="{'disabled' : currentPage === 1}">
<a class="page-link" href="#" @click.prevent="changePage(currentPage - 1)">Poprzednia</a>
</li>
<li v-for="page in pagesNumber" class="page-item"
:class="{'active': page == pagination.meta.current_page}">
<a href="javascript:void(0)" @click.prevent="changePage(page)" class="page-link">{{ page }}</a>
</li>
<li class="page-item" :class="{'disabled': currentPage === pagination.meta.last_page }">
<a class="page-link" href="#" @click.prevent="changePage(currentPage 1)">Nast?pna</a>
</li>
<span style="margin-top: 8px;"> <i>Wy?wietlam {{ pagination.data.length }} z {{ pagination.meta.total }} wyników.</i></span>
</ul>
</nav>
</div>
</template>
<script type="text/ecmascript-6">
import axios from 'axios';
import Vue from 'vue';
import 'vuejs-datatable/dist/themes/bootstrap-4.esm';
import {
VuejsDatatableFactory,
IDataFnParams,
IDisplayHandlerParam,
ITableContentParam,
TColumnsDefinition,
VueDatatable
} from 'vuejs-datatable';
Vue.use(VuejsDatatableFactory, VueDatatable);
import Swal from 'sweetalert2';
export default {
props: {
fetchUrl: {type: String, required: true},
columns: {type: Array, required: true},
headers: {type: Object, required: true},
routeName: {type: String, required: true},
showUrl: {type: String, required: false},
},
data() {
return {
tableData: [],
url: '',
pagination: {
meta: {to: 1, from: 1}
},
offset: 4,
currentPage: 1,
perPage: 100,
sortedColumn: this.columns[0],
order: 'asc',
search: '',
pageOptions: [100, 200, 500, 1000],
selectedContent: ''
}
},
watch: {
fetchUrl: {
handler: function (fetchUrl) {
this.url = fetchUrl
},
immediate: true
}
},
created() {
console.log(this.fetchUrl);
return this.fetchData()
},
computed: {
/**
* Get the pages number array for displaying in the pagination.
* */
pagesNumber() {
if (!this.pagination.meta.to) {
return []
}
let from = this.pagination.meta.current_page - this.offset
if (from < 1) {
from = 1
}
let to = from (this.offset * 2)
if (to >= this.pagination.meta.last_page) {
to = this.pagination.meta.last_page
}
let pagesArray = []
for (let page = from; page <= to; page ) {
pagesArray.push(page)
}
return pagesArray
},
/**
* Get the total data displayed in the current page.
* */
totalData() {
return (this.pagination.meta.to - this.pagination.meta.from) 1
}
},
methods: {
fetchData() {
let dataFetchUrl = `${this.url}&page=${this.currentPage}&column=${this.sortedColumn}&order=${this.order}&per_page=${this.perPage}&search=${this.search}`
axios.get(dataFetchUrl)
.then(({data}) => {
this.pagination = data
this.tableData = data.data
}).catch(error => this.tableData = [])
},
/**
* Get the serial number.
* @param key
* */
serialNumber(key) {
return (this.currentPage - 1) * this.perPage 1 key
},
/**
* Change the page.
* @param pageNumber
*/
changePage(pageNumber) {
this.currentPage = pageNumber
this.fetchData()
},
/**
* Sort the data by column.
* */
sortByColumn(column) {
if (column === this.sortedColumn) {
this.order = (this.order === 'asc') ? 'desc' : 'asc'
} else {
this.sortedColumn = column
this.order = 'asc'
}
this.fetchData()
},
handleSearch() {
this.fetchData()
},
handlePerPage($event) {
this.perPage = $event.target.value;
this.fetchData()
},
recordLink(id) {
return this.routeName `/${id.toString()}`
},
showRecord(id) {
const recordLink = this.recordLink(id);
this.$router.push({path: recordLink});
},
getDataRecord(id) {
let self = this;
axios.get(this.$apiAdress '/api/carriers/' id '/edit?token=' localStorage.getItem("api_token"))
.then(function (response) {
self.selectedContent = response.data.record;
console.log(self.selectedContent); // here is my result @@
}).catch(function (error) {
console.log(error);
self.$router.push({path: '/login'});
});
},
prepareAddToTask(id){
const copyId = id;
Swal.fire({
title: 'Czy na pewno',
text: "Chcesz doda? tego przewo?nika?",
type: 'question',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Tak!',
cancelButtonText: 'Anuluj',
buttonsStyling: true
}).then((isConfirm) => {
// now 'this' depends on the lexical enviroment.
if(isConfirm.value === true) {
this.getDataRecord(copyId);
}
});
}
///
},
filters: {
columnHead(value) {
return value.split('_').join(' ').toUpperCase()
}
},
name: 'DataTable'
}
</script>
我需要在控制臺日志中顯示從模態/資料表獲得的 Main.VUE 內容。
我怎樣才能做到?
uj5u.com熱心網友回復:
由于您是 Vue.js 的新手,我建議您閱讀有關props-down and events-up patternVue 組件之間資料流的描述。
- props-down 部分描述了資料流 PARENT -> CHILD,這意味著子組件應該通過props從父組件接收資料。
- Events-up 部分描述的是資料流 CHILD -> PARENT,這意味著子組件應該通過發出事件來向父組件發送資料。
要回到您的具體情況,您需要從Datatable.vue您將處理的組件中發出一個事件Main.vue:
在你的Datatable.vue你應該添加這個:
getDataRecord(id) {
let self = this;
axios.get(this.$apiAdress '/api/carriers/' id '/edit?token=' localStorage.getItem("api_token"))
.then(function (response) {
self.selectedContent = response.data.record;
self.$emit('content-selected', self.selectedContent); <-- add this line
}).catch(function (error) {
console.log(error);
self.$router.push({path: '/login'});
});
},
現在,Main.vue您需要像這樣處理事件:
<data-table-select
:fetch-url="datatTableUrl"
:columns="['id', 'email', 'name', 'surname']"
:headers="{'id': 'ID','email': 'Email','name': 'Imi?','surname': 'Nazwisko'}"
:routeName="routeName"
@content-selected="handleContentSelected($event)" <-- add this line
></data-table-select>
現在,添加將處理事件的函式,在您的方法中添加:
handleContentSelected(content) {
console.log(content); <-- your data should be here
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/426725.html
標籤:javascript Vue.js
