1

I am new to Vue and have a component A) Notification bar which has a Reactive object containing state, message. Then I want to show a div in another component based on the status of Reactive object in component A. Also I want to be able to change the Reactive object in component A from a method in component B. How do you achieve this?

Component A:

<template>
<div v-html="$notificationStore.message" v-if="$notificationStore.notify"></div>
</template>

<script setup>
import { reactive } from "vue";

const $notificationStore = reactive({
    notify: false,
    type: "",
    message: ""
});
</script>

Component B:

<template>
<div v-if="!$notificationStore.notify"></div> <!-- Should read "notify" from Component A"-->
<button type="button" @click="ShowNotification('Message to show')"/>
</template>

<script setup>
import { reactive } from "vue";

function ShowNotification(message){
   this.$notificationStore.notify = true;
   this.$notificationStore.Message = message;
};
</script>

Thank you very much!

Aleksey
  • 61
  • 6
  • Check the answer [how to pass a reactive variable from child component to parent component in vue js composition api](https://stackoverflow.com/a/75566693/2487565) – Tolbxela Feb 27 '23 at 18:16

1 Answers1

0

You don't need to use $ for your data properties.

Be sure that you understand the security risks bound with using v-html directive

There are better ways to achieve the same result, without using v-html.

UPDATE

I have changed the example to cover using SFCs.

You can pass your store to your components through props.

<comp-a :store="myStore"></comp-a>

Pay attention, that props are readonly. Since we pass an reactive object, you still can change the object properties from the component but this is a bad practice and is not recommended.

It is recommended to keep any mutations to reactive state inside of the provider whenever possible.

I would also suggest you to try using Pinia instead of developing your own custom store solution.

Working playground

const { createApp, reactive } = Vue;

const myStore = reactive({
    notify: false,
    type: "",
    message: "",
    showNotification: function(message) {
      this.notify = true;
      this.message = message;
   }
})

const CompA = {
  props: ['store'],
  template: 'CompA: <div v-html="store.message" v-if="store.notify"></div>'
}

const CompB = {
  props: ['store'],
  template: `CompB:
    <div v-if="!store.notify">
      <button type="button" @click="store.showNotification('Message from CompB')">show</button>
    </div>`
}

const App = {
 components: { CompA, CompB },
 setup() {
  return  { myStore }
 }
}

const app = createApp(App)
app.mount('#app')
#app { line-height: 1.75; }
[v-cloak] { display: none; }
<div id="app">
<comp-a :store="myStore"></comp-a><br/>
<comp-b :store="myStore"></comp-b>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
Tolbxela
  • 4,767
  • 3
  • 21
  • 42
  • Hello @Tolbxela, thank you very much for your response. My structure is following: 1) Main.js is where i initialize vue and mount app. 2) Vue.app, this is where i import Header.vue, Router View (a specific page content is displayed via router) and Footer.vue. So to follow your example, i can have my reactive notificationStore in Header.vue and then in my main.js where I initialize app, i import the notificationStore, declare it as App component and then mount? – Aleksey Feb 28 '23 at 08:11
  • This is a very basic example. If you want to build it with SFC, then you will need to pass your store to the components. Or you can use Pinia instead. I will update the answer for SFC scenario. – Tolbxela Feb 28 '23 at 09:57
  • 1
    Thank you! Using Props I guess is not solving my issue as I want to change the state trigger Notification state from any component. However, Pinia seem to be the great tool for that! – Aleksey Feb 28 '23 at 11:16
  • The way I did it using internal myStore function you can easily change the state of myStore from any component. You could also `provide/inject` things to child components. Just don't change the properties directly from the component. – Tolbxela Feb 28 '23 at 13:27
  • Pinia is great, but a bit overkill for small apps. – Tolbxela Feb 28 '23 at 13:27