Как передать данные от одного дочернего компонента к другому?

Как можно передать данные из одного дочернего компонента в другой в Vue, сохраняя их в каком-либо хранилище (аналогично кешу или сессиям на бэкенде), без использования цепочки эмитов, рефов и прочих решений? Приведите пример структуры: 

```javascript
<Roditel>
  <Sinok />
  <Docha />
</Roditel>
```
  • 22 ноября 2024 г. 20:03
Ответы на вопрос 2
В Vue.js есть несколько подходов для передачи данных между дочерними компонентами, не используя цепочку эмитов или рефов. Один из распространённых способов — использование глобального состояния, например, с помощью Vuex, или более простых решений, таких как `Provide / Inject`.

Вот пример с использованием Vuex для хранения состояния, которое доступно всему приложению, включая дочерние компоненты.

### Шаг 1: Установка Vuex

Сначала установите Vuex, если он ещё не установлен:

```bash
npm install vuex
```

### Шаг 2: Создание хранилища Vuex

Создайте файл хранилища, например `store.js`:

```javascript
import { createStore } from 'vuex';

const store = createStore({
  state: {
    sharedData: null,
  },
  mutations: {
    setSharedData(state, data) {
      state.sharedData = data;
    },
  },
  actions: {
    updateSharedData({ commit }, data) {
      commit('setSharedData', data);
    },
  },
  getters: {
    getSharedData(state) {
      return state.sharedData;
    },
  },
});

export default store;
```

### Шаг 3: Подключение Vuex в основном файле приложения

Импортируйте и подключите Vuex в свой основной файл приложения, например `main.js`:

```javascript
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

createApp(App)
  .use(store)
  .mount('#app');
```

### Шаг 4: Использование хранилища в дочерних компонентах

Теперь вы можете использовать Vuex в своих дочерних компонентах. Например, компонент `Sinok` может обновлять данные:

```javascript
<!-- Sinok.vue -->
<template>
  <div>
    <input v-model="inputData" @input="updateData" placeholder="Введите данные"/>
  </div>
</template>

<script>
import { mapActions } from 'vuex';

export default {
  data() {
    return {
      inputData: '',
    };
  },
  methods: {
    ...mapActions(['updateSharedData']),
    updateData() {
      this.updateSharedData(this.inputData);
    },
  },
};
</script>
```

А компонент `Docha` может получать эти данные:

```javascript
<!-- Docha.vue -->
<template>
  <div>
    <p>Полученные данные: {{ sharedData }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['getSharedData']),
  },
};
</script>
```

### Шаг 5: Использование компонентов внутри родителя

Теперь вы можете использовать оба дочерних компонента в родителе `Roditel`:

```javascript
<!-- Roditel.vue -->
<template>
  <div>
    <Sinok />
    <Docha />
  </div>
</template>

<script>
import Sinok from './Sinok.vue';
import Docha from './Docha.vue';

export default {
  components: {
    Sinok,
    Docha,
  },
};
</script>
```

### Вывод

Теперь `Sinok` может обновлять данные в Vuex, а `Docha` может получать эти данные, не используя эмиты или рефы. Такое решение легко масштабируется и позволяет управлять состоянием вашего приложения централизованно.
Собственно взаимодействие меж несвязанными компонентами осущетвляется следующими способами: 
1. В простых случаях обычный vue-flow: вверх до общего родителя события через $emit и @on , вниз props .
2. Общее хранилище в рамках всего приложения: pinia , vuex .
3. Для связки детей которые не могут жить без конкретного родителя можно использовать: provide \ inject .
4. Для плотной связки единичных компонентов: просто отдельный reactive объект импортируемый в нужных компонентах. (использовать осторожно при SSR)

Конкретно тебе, похоже, нужен п.2.
Похожие вопросы