大家好,我试图用Vue js制作我的自定义标签,但是我遇到了问题,因为像我的data属性没有得到更新:(... 这是我遇到麻烦的情况: 当我打开3个选项卡时,如果我在第一个选项卡上打开我的模态,然后关闭该第一个选项卡,我将切换到第二个选项卡,但是来自第一个选项卡的我的模态保持打开状态,就像它是第一个选项卡而不是第二个模态...我希望每个标签都有自己的模态实例。
在这里,我发布了正在发生的事情的下面的表情。基本上,当上一个页面关闭时,我不希望我的模式再次出现在下一个选项卡上:)
好像我的数据值一样,不会在第一个选项卡中销毁,而是将它们复制到第二个选项卡上,我试图在几天之内找出问题所在,但没有成功...
这是我的App.vue
<template>
<div id="app">
<div class="event-tabs wrapper">
<div class="is-flex">
<div class="tabs is-boxed control">
<ul>
<li v-for="(newEvent, index) in newEventList" :key="index" :class="selectedEventClass(index)"
@click.left="selectEvent(index)" @click.middle="discardEvent(index)">
<span class="event-tab-title">
TAB
</span>
<span class="event-tab-close" @click.stop="closeEvent(index)">
<i class="fa fa-times"></i>
</span>
</li>
<li class="add-tab">
<a @click.prevent="createEvent" :title="'Create Tab'">
<span>+</span>
</a>
</li>
</ul>
</div>
</div>
<div class="tab-content">
<tab v-for="(event, index) in newEventList" :event="event" :index="index"
v-if="showEventTab" v-show="index === selectedEvent" :key="index"
ref="eventTab"></tab>
</div>
</div>
</div>
</template>
<script>
import tab from './components/EventTab.vue';
export default {
name: 'app',
components: {
tab,
},
computed: {
newEventList() {
return this.$store.getters['eventModule/getNewList'];
},
selectedEvent() {
return this.$store.getters['eventModule/getSelectedNew'];
},
eventToEdit() {
return this.$store.state.event.eventToEdit;
},
showEventTab() {
return this.newEventList.length > 0;
},
},
methods: {
selectedEventClass(eventIndex) {
return (eventIndex === this.selectedEvent) ? 'is-active' : '';
},
createEvent() {
this.$store.dispatch('eventModule/create');
},
selectEvent(eventIndex) {
this.$store.dispatch('eventModule/select', { eventIndex });
},
closeEvent(eventIndex) {
this.$store.dispatch('eventModule/close', { eventIndex });
},
},
}
</script>
<style lang="scss">
@import './assets/scss/main';
</style>
“我的标签”组件:
<template>
<div class="event-form" v-if="event">
<div class="columns">
<div class="column is-half">
<div class="field">
<h1>This is the TAB number {{ index}} </h1>
</div>
<p class="control">
<button class="button is-danger" @click.prevent="openDialog">
Open Dialog
</button>
</p>
<modalDialog type="none" :show="modal.show"
:className="'eventTabModal'" :title="'Test modal'"
:text="'Test modal'"
@hide="closeDiscardModal">
<h3>Modal is active</h3>
</modalDialog>
</div>
</div>
</div>
</template>
<script>
import modalDialog from './ModalDialog.vue';
export default {
components: {
modalDialog,
},
props: ['event', 'index'],
data() {
return {
eventDefault: {},
/**
* Discard event modal
*/
modal: {
show: false,
},
};
},
computed: {
eventList() {
return this.$store.getters['event/getNewList'];
},
eventTypeList() {
return this.$store.getters['eventType/getList'];
},
},
methods: {
/**
* Opens discarded Modal
*/
closeDiscardModal() {
this.modal = {
show: false,
};
},
openDialog() {
this.modal = {
show: true,
};
},
},
}
</script>
用于显示对话框的我的模态组件:
<template>
<transition name="fade">
<div class="modal is-active" v-show="shouldShowModal" :class="className">
<div class="modal-background" @click="hideModal"></div>
<div class="modal-card">
<header class="modal-card-head" v-if="title">
<p class="modal-card-title">{{ title }}</p>
</header>
<section class="modal-card-body">
<slot>
{{ text }}
</slot>
</section>
<footer class="modal-card-foot" v-if="type !== 'none'">
<template v-if="type === 'confirm'">
<a class="button is-success" @click.prevent="buttonClicked('yes')">Yes</a>
<a class="button is-danger" @click.prevent="buttonClicked('no')">No</a>
</template>
<template v-else-if="type === 'info'">
<a class="button" @click.prevent="buttonClicked('ok')">Ok</a>
</template>
</footer>
</div>
<button class="modal-close is-large" @click="hideModal"></button>
</div>
</transition>
</template>
<script>
export default {
props: {
show: {
type: Boolean,
default: false,
},
title: {
type: String,
default: '',
},
text: {
type: String,
default: '',
},
type: {
type: String,
default: 'info',
},
className: {
type: String,
default: '',
},
},
data() {
return {
shouldShowModal: this.show,
};
},
watch: {
show(newValue) {
this.shouldShowModal = newValue;
},
},
methods: {
hideModal() {
this.shouldShowModal = false;
this.$emit('hide');
},
buttonClicked(type) {
this.hideModal();
this.$emit('buttonClicked', type);
},
},
};
</script>
“标签”的“我的商店”模块:
const eventModule = {
namespaced: true,
state: {
/**
* List of opened tabs
*/
newList: [],
selectedNew: 0,
savedList: [],
eventToEdit: null,
},
getters: {
getNewList(state) {
return state.newList;
},
getSelectedNew(state) {
return state.selectedNew;
},
getSavedList(state) {
return state.savedList;
},
},
mutations: {
addNew(state, { location } = {}) {
state.newList.push({
typeId: null,
active: true,
logs: [],
});
},
removeNew(state, index) {
state.newList.splice(index, 1);
},
setNew(state, { index = state.selectedNew, event }) {
state.newList.splice(index, 1, event);
},
selectNew(state, selectedNew) {
state.selectedNew = selectedNew;
},
},
actions: {
/**
* opens tab for creating new event
*
* @param context
* @param location
* @param stopProp
* @returns {*}
*/
create(context, { location, stopProp } = {}) {
const newList = context.getters.getNewList;
context.commit('addNew', { location });
context.commit('selectNew', newList.length - 1);
// if (!stopProp) {
// context.dispatch('stateChanged', null, { root: true });
// }
return Promise.resolve();
},
/**
* Saves event
* @param context
* @param event
* @return {Promise|Promise.<TResult>}
*/
save(context, { event, index, hideMessage }) {
const method = (event.id) ? 'patch' : 'post';
// const data = { event, userId: context.rootGetters['user/getData'].id };
const data = { event };
const payload = { method, url: 'event', data, hideMessage };
return context.dispatch('server/http', payload, { root: true })
.then((response) => {
context.commit('setNew', { event: response.data.object, index });
context.dispatch('loadList');
})
.catch(error => Promise.reject(error));
},
select(context, { eventIndex, stopProp }) {
context.commit('selectNew', eventIndex);
},
opened(context) {
const event = JSON.parse(JSON.stringify(context.state.eventToEdit));
context.state.eventToEdit = null;
context.dispatch('create', { stopProp: true });
context.commit('setNew', { event });
},
/**
* Closes for event
* @param context
* @param eventIndex
* @param stopProp
* @return {Promise|Promise.<TResult>}
*/
close(context, { eventIndex, stopProp }) {
const newList = context.getters.getNewList;
const selectedNew = context.getters.getSelectedNew;
context.commit('removeNew', eventIndex);
if (selectedNew >= newList.length && selectedNew > 0) {
context.commit('selectNew', selectedNew - 1);
}
},
},
};
export default eventModule;
这也是我的github页面的链接,如果有人想看一下,这里有完整的测试代码:
先感谢
答案 0 :(得分:0)
解决了。问题在于v-for中的键,:key prop应该是唯一的,所以这是我解决的方法,在addNew变量中,添加新属性tabId像这样添加:
state.newList.push({
tabId: new Date.now(),
typeId: null,
active: true,
briefing: false,
logs: [],
});
和App.vue将:key =“ index”更改为:key =“ event.tabId”