0

I am still new to Vuejs and confused by the many different possibilities in exchanging data between different components. So far I haven't found a working solution for my case.

My setup:

I am building an application of which four components are relevant here: AppComponent, MenuComponent, ContentDisplayComponent, NavigationComponent. In the MenuComponent there is a dropdown that selects a value. This value is displayed on ContentDisplayComponent and it affects the doings of NavigationComponent.

Already working:

In AppComponent, the data I want to pass around is initiated:

data() {
  return {
    selected_entity_type : "test",
  }},

The value is actually coming from MenuComponent by passing it an event function:

v-on:entity_type_selected="something_happened"

Function looks like this:

function something_happened(selected_type) {
    if (is_empty(selected_type)) {
        console.warn("selected type was empty");
    }
    this.selected_entity_type = selected_type;
}

In MenuComponent the dropdown reacts to changes:

<select v-model="selected_entity_type" v-on:change="entity_type_selected">

Function looks like this:

function entity_type_selected() {
    this.$emit('entity_type_selected', this.selected_entity_type)
}

It is given to ContentDisplayComponent

v-bind:selected_entity_type = "selected_entity_type"

where it is received as a prop and used

props: {
  selected_entity_type : ""
},

So in my understanding the variable is actually under the scope of AppComponent, but its value is passed into ContentDisplayComponent and its content is changed by the event MenuComponent emits which is caught by v-on:entity_type_selected="something_happened".

I assume that because the function "something_happened" is given to MenuComponent from AppComponent, the "this" it contains refers to AppComponent and thus can handle the variable.

What I want to add, but don't know how:

NavigationComponent can change the data displayed in ContentDisplayComponent. When this happens, I would like to also change the state of the dropdown in MenuComponent and the value of the selected_entity_type prop in ContentDisplayComponent. ContentDisplayComponent's data is manipulated via and maintained in a Composable. NavigationComponent uses that Composable to change the contents. But the selected_entity_type prop is not in there, since it's in AppComponent and I don't know how to reach it.

What would be the best way to achieve this?

I would like to understand the principle idea.

Looking through these two discussions I don't want to violate any principles with things that might work. I would like to do it right.

I am trying to emit information from ContentDisplayComponent, but it cannot change the variable and cannot use the functions MenuComponent and AppComponent use for their sharing.

Another possibility would be to move selected_entity_type prop into my data Composable so it is under direct control. But then ContentDisplayComponent has to exchange that information with MenuComponent and I don't know if that's possible.

Please help me understand what is the Vue3 idea of what I want to achieve.

anjuta
  • 333
  • 3
  • 12

1 Answers1

0

I found something that works for me - although I don't know if that's the most-native Vuejs style.

Looking at the documentation about state management, I wondered whether it would be wrong to use my existing Composable to manage the state by itself. Looking around on the internet, I found no article saying "absolutely no!". So that's what I did.

My Composable now defines this state variable once:

const selected_entity_type = ref("no type selected");

and exports getters and setters for it:

function set_selected_entity_type(new_type: string) {
  selected_entity_type.value = new_type;
}

function get_selected_entity_type(): string {
  return selected_entity_type.value;
}

These getters and setters can be used by all Components now via importing the Composable.

For the dropdown I am using a computed value as my v-model (like discussed here)

computed: {
  selected_entity_type: {
    get() { return this.get_selected_entity_type() },
    set(value) { 
      this.reset_state(); 
      this.set_selected_entity_type(value);
    }
  }
}

AppComponent now has nothing to do with all of this anymore - no more events, no more props ...

Please let me know if you see any problems with this approach and recommend improvements.

anjuta
  • 333
  • 3
  • 12