-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Description
I have a store:
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import constructor from './modules/constructor'
Vue.use(Vuex);
const debug = process.env.NODE_ENV !== 'production';
export default new Vuex.Store({
modules: {
constructor
},
strict: debug
})
//store/modules/constructor.js
export default {
state: { // initial state
slides: []
},
mutations: {
['constructor.addSlide'](state, type) {
const slides = state.slides;
slides.push({
id: Math.round(Math.random() * 10000),
type,
});
Vue.set(state, 'slides', slides);
},
['constructor.updateSlide'](state, slide) {
const slides = state.slides;
const targetSlide = slides.find(s => s.id === slide.id);
if (targetSlide) targetSlide.data = slide.data;
//Vue.set(state, 'slides', {...slides});
state.slides = Object.assign({}, slides);
}
}
}
I've tried different variations guided by http://vuex.vuejs.org/en/mutations.html#mutations-follow-vues-reactivity-rules
On the page I've got two almost similar components slides-previews
and presentation-editor
:
<div class="presentation-construtor">
<slides-previews :slides="$store.state.constructor.slides"></slides-previews>
<presentation-editor :slides="$store.state.constructor.slides"></presentation-editor>
<templates-list @sidebar-toggle="toggleSidebar"></templates-list>
</div>
<presentation-editor>
:
<div class="slide-editor">
<div class="viewport">
<div class="wrap">
<div class="slide-holder" v-for="slide in slides">
<div class="slide-container">
<component :is="slide.type" :data="slide.data" :id="slide.id"></component>
</div>
</div>
</div>
</div>
</div>
and currently one slide type:
<template>
<div class="slide presentation-slide">
<div class="label">Идея</div>
<div class="column" v-for="(value, index) in columns">
<text-editor :content="value.title" mode="inline" @change="setTitle(index, ...arguments)"></text-editor>
<text-editor :content="value.body" mode="partial" @change="setBody(index, ...arguments)"></text-editor>
</div>
<div class="controls">
<button v-if="data.columns.length < 2" @click="addColumn">+</button>
</div>
</div>
</template>
<script>
export default{
props: {
id: {},
data: {
default: () => {
return {
columns: [
{
title: 'Заголовок',
body: 'Контент'
}
]
}
}
}
},
components: {
textEditor: require('../ui/text-editor.vue')
},
methods: {
addColumn()
{
let data = this.data;
data.columns.push({
title: 'Заголовок',
body: 'Контент'
});
this.update(data);
},
setTitle(column, value)
{
let data = this.data;
data.columns[column].title = value;
this.update(data);
},
setBody(column, value)
{
let data = this.data;
data.columns[column].body = value;
this.update(data);
},
update(data) {
this.$store.commit('constructor.updateSlide', {
id: this.id,
data
});
}
}
}
</script>
Both store actions update vuex state and this is seen in vuex inspector.
When I commit constructor.addSlide
that pushes a new slide in the array — it updates both slides-previews
and presentation-editor
, however commiting constructor.updateSlide
, that changes the data of some slide does not affect all instances:
The same in opposite way: if I change something in previews, state changes but editor is not affected.
Also even after constructor.addSlide
previously changed slides don't update, only new one is added in both components