Home > Net >  VUE.JS 3 Changing boolean value of one sibling component from another
VUE.JS 3 Changing boolean value of one sibling component from another

Time:02-02

I have two components - component A and component B that are siblings.

I need to change the boolean value inside of Component-A from the Watcher in Component-B.

Component A code:

<template>
  <div></div>
</template>

<script>
export default {
    data() {
        return {
            editIsClicked: false,
        }
    }
}
</script>

Component B code:

<template>
    <v-pagination
      v-model="currentPage"
      :length="lastPage"
      :total-visible="8"
    ></v-pagination>
  </template>
  
  <script>
  export default {
    props: ["store", "collection"],
  
    watch: {
      currentPage(newVal) {
        this.paginatePage(newVal);
        // NEED TO TOGGLE VALUE HERE - when i switch between pages
        
      },
    },
   },
 };
  </script>

CodePudding user response:

The Vue Documentation proposes communicating between Vue Components using props and events in the following way

             *--------- Vue Component -------*
some data => | -> props -> logic -> event -> | => other components 
             *-------------------------------*

It's also important to understand how v-model works with components in Vue v3 (Component v-model).

const { createApp } = Vue;

const myComponent = {   
  props: ['modelValue'],
  emits: ['update:modelValue'],
  data() {
    return {
      childValue: this.modelValue
    }
  },
  watch: {
    childValue(newVal) {
      this.$emit('update:modelValue', newVal)    
    }      
  },
  template: '<label>Child Value:</label> {{childValue}} <input type="checkbox" v-model="childValue" />'
}

const App = {
  components: { 
    myComponent 
  },
  data() {
    return {
      parentValue: false
    }
  }
}

const app = createApp(App)
app.mount('#app')
<div id="app">  
  Parent Value: {{parentValue}}<br />
  <my-component v-model="parentValue"/>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

CodePudding user response:

I have made a new playground. Hope it helps you now to understand the logic.

You can store data in the main Vue App instance or use a Pinia store for it.

But I would suggest you to start without Pinia to make your app simpler. Using Pinia will make your App much more complicated and your knowledge of Vue seems to be not solid enough for that.

const { createApp } = Vue;

const myComponentA = {   
  props: ['editIsClicked', 'currentPage'],
  template: '#my-component-a'
}

const myComponentB = {   
  emits: ['editIsClicked'],
  data() {
      return {
          currentPage: 1,
      }
  },
  watch: {
    currentPage(newVal) {
      this.$emit('editIsClicked', newVal)    
    }      
  },
  template: '#my-component-b'
}

const App = {
  components: { 
    myComponentA, myComponentB
  },
  data() { 
    return {
      editIsClicked: false,
      currentPage: 1
    }
  },
  methods: {
    setEditIsClicked(val) {
      this.editIsClicked = true;
      this.currentPage = val;
    }
  }
}

const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
.comp-a { background-color: #f8f9e0; }
.comp-b { background-color: #d9eba7; }
<div id="app">  
  <my-component-a :edit-is-clicked="editIsClicked" :current-page="currentPage"></my-component-a>
  <my-component-b @edit-is-clicked="setEditIsClicked"></my-component-b>
  
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script type="text/x-template" id="my-component-a">
  <div >
    My Component A: <br />editIsClicked: <b>{{editIsClicked}}</b><br/>
    currentPage: <b>{{currentPage}}</b><br/>
  </div>
</script>
<script type="text/x-template" id="my-component-b">
  <div >
    My Component B: <br />
    <label>CurrentPage:</label> <input type="number" v-model="currentPage" />
  </div>
</script>

  • Related