3

I am writing a Vue.js app using Vue.js 3.0. I'm using this as a way to learn the composition API. One thing that is unclear to me is how to conditionally update my component UI when a store value is updated. To demonstrate my issue, I've created this fiddle. The code is detailed here:

JavaScript

const store = {
  state: reactive({
    result = null
  }),
  generateNewValue() {
    this.state.result = Math.floor(Math.random() * 10);
  }
};

const MyApp = {
  setup() {
    return {
    }
  }
}
const myApp = Vue.createApp(MyApp)

myApp.component("banner", 
  { 
    template: '<button @click="onGenerateClick">generate</button>',
    setup(props) {
      console.log('setting up...');
    },
    methods: {
      onGenerateClick() {
        store.generateNewValue();
      }
    }
  }
);

myApp.component("content", {
  template: '<div><span>Content</span><button @click="onGenerateClick">generate</button></div>',
  methods: {
    onGenerateClick() {
      store.generateNewValue();
    }
  }  
});

myApp.mount('#my-vue')

HTML

<div id="my-vue">
  <banner></banner>
  <hr />
  <content></content>
</div>

CSS

.even-banner {
  background-color:navy;
  color: #fff;
}

.even-content {
  background-color:blue;
  color: #fff;
}

.odd-banner {
  background-color:maroon;
  color:#fff;
}

.odd-content {
  background-color:red;
  color:#fff;
}

When I click the "generate" button, a random number is generated. If that number is even, I want to set the content div to use the even CSS class. If it is an odd number, I want to apply the odd CSS class. I'm somewhat stuck though.

My problem is, I can successfully set the state value in the global store. However, I do not know how to react to property value changes in the components. I added a watchEffect, in my setup functions. However, that does not give me access to the state of the individual component itself. I'm trying to figure out a way in each component to say "hey, when this property in the store changes, update the UI like this.".

What am I missing?

1 Answer 1

5

You could use a computed() prop to track the state's value (e.g., to test whether it's even):

const MyApp = {
  setup() {
    return {
      isEven: computed(() => store.state.result % 2 === 0)
    }
  }
}

Then, use that prop in the template to apply a conditional class:

<content :class="{ 'even-content': isEven, 'odd-content': !isEven }">

updated fiddle

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.