Answer the question
In order to leave comments, you need to log in
How, when clicking on a button in a block, open a modal window / pop-up sidebar with the data of the block in which the button is located?
I'm learning vuex, I'm making an interface "like an admin panel"
Interface prototype:
I use vuex to store data, the code is below
Vuex container code
export default {
actions: {
fetchData(ctx) {
const data = require('../../data')
localStorage.setItem('blocks', JSON.stringify(data))
const blocks = JSON.parse(localStorage.getItem('blocks'))
ctx.commit('updateBlockConfig', blocks)
},
toggle(state) {
return state.isNavOpen = !state.isNavOpen;
},
loadConfigToBlock() {
}
},
mutations: {
updateBlockConfig(state, blocks) {
return state.block_config = blocks
},
setIsNavOpen(state) {
return state.isNavOpen = true;
},
toggleNav(state, i) {
state.block_config[i]
return state.isNavOpen = !state.isNavOpen;
},
closeSidebarPanel(state) {
return state.isNavOpen = !state.isNavOpen;
}
},
state: {
block_config: [],
isNavOpen: false,
},
getters: {
getBlockConfig(state) {
return state.block_config
},
getBlockModal(state) {
return state.block_config.settings
},
isPanelOpen(state) {
return state.isNavOpen
}
},
}
<template>
<div id="app">
<div class="content">
<div class="blocks">
<div class="block" v-for="block in getBlockConfig" :key="block.blockID" v-bind:style="{ background: `${block.color}` }">
<h2 class="block-title">{{block.bName}}</h2>
<div class="block-text">{{block.bText}}</div>
<div>{{block.settings}}</div>
<Trigger></Trigger> <!-- Кнопка вызова модального окна -->
</div>
</div>
<Sidebar>
<div class="sidebar-panel-settings">
<div class="setting-block">
<!-- Тут вывод данных блока, из которого вызвано окно -->
</div>
</div>
</Sidebar>
</div>
</div>
</template>
<script>
import {mapGetters, mapActions} from 'vuex'
import Sidebar from './components/Menu/Sidebar.vue'
import Trigger from './components/Menu/Trigger.vue'
export default {
name: 'app',
components: {
Sidebar,
Trigger
},
computed: mapGetters(['getBlockConfig', 'isPanelOpen']),
methods: mapActions(['fetchData', 'toggle']),
async mounted() {
this.fetchData()
},
}
</script>
[
{
"blockID": 1,
"bName": "Желтый блок",
"bText": "Любая компания-производитель связывает с каждой своей новой моделью определенные надежды. Зачастую в связи с этим звучат громкие и красивые заявления - прорыв, революция, законодатель моды на ближайшее десятилетие... Но время тут - единственный по-настоящему объективный эксперт.",
"color": "#FFFF00",
"isOpen": false,
"settings": [
{
"ID": 34,
"Name": "Ширина",
"stringType": "int",
"filedType": "input",
"fieldValue": "600",
"fieldSize": 4
},
{
"ID": 35,
"Name": "Высота",
"stringType": "int",
"filedType": "input",
"fieldValue": "500",
"fieldSize": 4
}
]
},
{
"blockID": 2,
"bName": "Розовый блок",
"bText": "Любая компания-производитель связывает с каждой своей новой моделью определенные надежды. Зачастую в связи с этим звучат громкие и красивые заявления - прорыв, революция, законодатель моды на ближайшее десятилетие... Но время тут - единственный по-настоящему объективный эксперт.",
"isOpen": false,
"color": "#ffc0cb",
"settings": [
{
"ID": 39,
"Name": "Скрытое",
"stringType": "int",
"filedType": "input",
"fieldValue": "600",
"fieldSize": 4
}
]
}
]
<template>
<button class="button-config" :class="{ 'active' : isPanelOpen }" @click.prevent="toggleNav" >Настройки</button>
</template>
<script>
import {mapMutations, mapGetters} from 'vuex'
export default {
name: 'Trigger',
methods: mapMutations(['toggleNav']),
computed: mapGetters(['fetchData', 'isPanelOpen']),
}
</script>
<template>
<div class="sidebar">
<div class="sidebar-backdrop" @click="closeSidebarPanel" v-if="isPanelOpen"></div>
<transition name="slide">
<div v-if="isPanelOpen"
class="sidebar-panel">
<a href="#" class="close-button" @click="closeSidebarPanel"></a>
<slot></slot>
</div>
</transition>
</div>
</template>
<script>
import {mapMutations, mapGetters} from 'vuex'
export default {
name: 'Sidebar',
methods: mapMutations(['closeSidebarPanel']),
computed: mapGetters(['isBurgerActive', 'isPanelOpen']),
}
</script>
Answer the question
In order to leave comments, you need to log in
Add a property to the state that will represent the selected block:
state: {
opened: null,
...
toggleNav(state, block) {
state.opened = state.opened === block ? null : block;
},
state.opened = block
(the name of the mutation in this case, of course, should be changed). closeSidebarPanel(state) {
state.opened = null;
},
isPanelOpen(state) {
return !!state.opened;
},
<template #default="{ block }">
<div class="sidebar-panel-settings">
<div class="setting-block">
{{ block.bName }}
</div>
</div>
</template>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question