Home » vue » Array in Vue Plugin is not reactive

Array in Vue Plugin is not reactive

Posted by: admin November 26, 2021 Leave a comment

Questions:

I created a simple plugin available in all components which handles communicates in my application. There is also a special component “Communicates.vue” which listens on array declared in plugin and displays toasts. I have a problem with reactivity, my array is always empty. I am pretty sure I did something similar previously and it worked. Did I miss something?

Communicates.vue

    <div class="communicates">
        {{$communicates.messages}} <!-- always empty :( -->
        <transition-group mode="fade" name="toasts">
            <Toast
                v-for="communicate in $communicates.messages"
                :key="communicate"
                :communicate="communicate"
                @close="$communicates.remove(communicate)"
            />
        </transition-group>
    </div>
</template>
<script>
import Toast from '@/components/Toast';
import { mapGetters, mapActions } from 'vuex';

export default {
    components: {
        Toast
    }
}
</script>

Plugin:

const Communicates = {
    install(Vue) {
        Vue.prototype.$communicates = {
            messages: [],
            success(message) {
                this.messages.push({ type: 'success', message })
                debugger; // OK, app stops here, so it should be added
            },
            error(message) {
                this.messages.push({ type: 'error', message })
            },
            remove(communicate) {
                this.messages.splice(this.messages.indexOf(communicate), 1)
            }
        }
    }
}

export default Communicates // of course I did Vue.use in main.js

Answers:

Your $communicates object likely isn’t reactive. Try this:

Vue.prototype.$communicates = Vue.observable({
  messages: [],
  // etc
})

###

Can you try creating new references?

Vue.prototype.$communicates = {
  messages: [],
  success(message) {
    this.messages = this.messages.concat([{ type: 'success', message }])
  },
  error(message) {
    this.messages = this.messages.concat([{ type: 'error', message }])
  },
  remove(communicate) {
    this.messages = this.messages.filter(message => message !== communicate)
  }
}