Я пишу компонент "вкладки".
Я пытаюсь отправить данные с использованием метода sendTabsData()
в моем коде, и по какой-то причине он не работает с использованием $emit
.
Это код компонента моей вкладки:
<template>
<div id="tabs">
<div id="tabs-cont">
<div class="tabbable-panel">
<div class="tabbable-line">
<ul class="nav nav-tabs" role="tablist">
</ul>
<div class="tab-content">
<slot></slot>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'DashboardTabs',
props: {
tabs: {
type: Object,
required: true,
default: {}
}
},
data() {
return {
displayed: '',
tabName: '',
$tabsContainer: null,
navTabs: null,
tabContent: null
}
},
created() {
},
mounted() {
this.init();
},
watch: {
},
methods: {
init: function() {
// Fetch UI elements
this.$tabsContainer = $('#tabs');
this.navTabs = this.$tabsContainer.find('.nav-tabs');
this.tabContent = this.$tabsContainer.find('.tab-content');
this.createTabs(this.tabs);
},
// Create tabs by result
createTabs: function(tabs) {
if ( this.tabs !== undefined || this.tabs.length > 0 ) {
this.setTabsBtns(tabs);
}
},
//
tabClick: function(e) {
this.changeDisplayNames(e);
this.sendTabsData();
},
// Change display names
changeDisplayNames: function(e) {
let liItem = e['target']['dataset']['displaytable'];
if (liItem) {
// Update variable table name
this.displayed = liItem;
// Remove the '$' and 'Table' text
let tableCategory = this.displayed.replace('Table', '');
tableCategory = tableCategory.replace('$', '');
// Update "global" variable of the current table
this.tabName = tableCategory.charAt(0).toUpperCase() + tableCategory.slice(1);
}
},
// Set tabs li btns
setTabsBtns: function(tabs) {
for (let key in tabs) {
this.navTabs.append(`<li class="nav-item" @click="this.tabClick"> <a href="#tab_default_${key}" class="nav-link" data-toggle="tab" data-displayTable="${tabs[key]}"> ${tabs[key]} </a> </li>`);
}
this.navTabs.find('li:first a').addClass('active');
this.displayed = this.tabs[0];
this.tabName = this.tabs[0];
},
// Set tabs content divs - not relevant if you don't want to load extra data to the DOM
setTabsContent: function(tabs) {
for (let key in tabs) {
this.tabContent.append(`<div class="tab-pane" id="tab_default_${key}"> <table class="aTable hover display" id="${tabs[key]}"> </table> </div>`);
}
this.tabContent.find('.tab-pane').first().addClass('active');
},
hideTabs: function() {
this.$tabsContainer.slideUp('slow');
},
showTabs: function() {
this.$tabsContainer.slideDown('slow');
},
// Send tab data to parent
sendTabsData: function(){
let data = {
'tabDisplayed': this.displayed,
'tabName': this.tabName
};
this.$emit('tabsData', data);
}
}
};
</script>
и это родительский компонент:
<script>
// import ProgressBar from "../components/ProgressBar.vue";
// import _ from 'lodash';
import DashboardForm from "../components/DashboardForm.vue";
import DashboardTabs from "../components/DashboardTabs.vue";
export default {
name: 'testcomponent',
components: {
// ProgressBar,
DashboardForm,
DashboardTabs
},
// mixins: [GF],
data() {
return {
};
},
created() {
},
mounted() {
},
destroyed() {
},
watch: {
},
methods: {
// Submit form
formSubmit: function(data) {
console.log('Submit form here');
console.log(data);
},
// Tabs data
fetchTabsData: function(data) {
console.log('tab was clicked');
console.log(data);
}
}
}
</script>
<!-- Template -->
<template>
<div id="testcomponent">
<!-- DashboardForm -->
<DashboardForm
:useGroupFilter="true"
:useDateRange="true"
@submit="formSubmit"
/>
<!-- Main Data Container -->
<div id="data-container">
<div id="chart-container"></div>
<!-- Dashboard Tabs and Tab Container -->
<DashboardTabs
:tabs="{ 0: 'potato', 1: 'banana' }"
@tabsData="fetchTabsData"
>
<!-- Datatable -->
<!-- <DashboardDatatable/> -->
</DashboardTabs>
</div>
<!-- END data-container -->
</div>
</template>
Как вы можете видеть, в моем родительском компоненте у меня есть emit submit, который извлекает данные (и работает нормально).
Единственное различие между компонентом вкладок и компонентом формы состоит в том, что компонент вкладки генерирует <li>
s, с которыми связано событие click.
Так что для ясности с моим вопросом:
Как отправить данные из дочернего компонента в родительский компонент, используя $ emit, если в этом случае элемент, с которым связано событие click, (onClick ==> отправить / прослушать данные для родительского компонента) динамически самогенерируемый и не "статичный".
EDIT:
использование v-for не дает запрошенного результата:
<li class="nav-item" @click="this.tabClick" v-for="(tab,index) in tabs">
<a :href="`#tab_default_${index}`" class="nav-link" data-toggle="tab" :data-displayTable="`${tab}`"> ${tab} </a>
</li>
Я получаю ошибку:
Ошибка при рендеринге: «Ошибка типа: невозможно прочитать свойство tabClick of undefined»
Похоже, это не позволяет мне добавить @ click
Edit2:
пробовал использовать @click.native="this.tabClick"
в v-for - ошибок не возникает, но мои фиктивные console.logs не отображаются. событие клика не выполняется правильно.