No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    [Solved] Is it the right way to using global event bus?

    Framework
    3
    11
    2965
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      Stanley last edited by Stanley

      I design the layout like this, there is a save button in the q-layout-header and different application in the child page. When I click save button, it will save different application. So I followed the documentation:
      1). in the child view, listen for an event

      export default {
      data (){ return …}
      created () {
      // listen for an event
      this.$root.$on(‘event_name’, saveXX())
      }
      methods: { }
      }
      function saveXX() { }
      

      2). in the main view, emitting an event when click save button

      this.$root.$emit(‘event_name’)
      

      There are two questions.
      1). Is it the best practice to trigger event? E.g., there are many buttons (save, print, download) in the toolbar in the main page, if child page want to support such function, how should they communicate.
      2). It seems saveXX can only be a function. If so, I can’t use data which is defined in the child vue component.

      1 Reply Last reply Reply Quote 0
      • A
        aryeh last edited by aryeh

        At question is really where to break down your application into different components, if at all. Once you decide that, you can communicate between components by having them raise events, which others listen out for and act on if necessary. Alternatively instead of notifying other components that something happened (and providing them with some optional information about that event), you might choose to store shared state globally, i.e. through Vuex.

        1. Best practice? No. The choice (depends on your circumstances and) remains yours as to whether you use events, callbacks between components, or shared state to communicate that something happened.
        2. You can pass data with the event, i.e. this.$root.$emit(‘event-name’, /some optional data/)
        S 1 Reply Last reply Reply Quote 0
        • Hawkeye64
          Hawkeye64 last edited by Hawkeye64

          @Stanley I usually do mine in the mounted() function. I have had some issues in the created() function which I think were race conditions.
          Also, don’t forget to call this.$root.$off('event_name', saveXX()) in your beforeDestroy() function. (notice the $off).
          And, looks like you have the wrong type of single quotes.

          S 1 Reply Last reply Reply Quote 0
          • S
            Stanley @aryeh last edited by

            @aryeh Thank you for your suggestion. I used Vuex to transfer state in different components, for current scenario, I know using Vuex could be a workaround, but it is a little complex because all different sub components have to handle the event when main component clicked the save button.
            Yes, it can pass data using method this.$root.$emit(‘event_name’, ‘some msg’). My current issue it that when triggering callback, the callback is a function and it can’t embedded in the sub vue component. It means it can’t access data defined in the sub component. (see fake code below the title)

            1 Reply Last reply Reply Quote 0
            • S
              Stanley @Hawkeye64 last edited by

              @hawkeye64 Thanks for your suggestion.
              Did you try to access sub component’s data when execute callback function. It seems the callback function saveXX cannot be defined inside “export default”, do you have any idea?

              export default {
              data (){ return …}
              …
              }
              function saveXX() { }

              1 Reply Last reply Reply Quote 0
              • A
                aryeh last edited by aryeh

                Make saveXX() a Vue instance method, rather than a global function as you’ve written, i.e. put it in “methods”. Alternatively, just execute your saveXX functionality in an anonymous function, e.g.

                created() {
                  this.$root.$on('event_name', () => {
                    // your saveXX functionality that can access current instances "data" through "this"
                    // e.g. let myAge = this.age;
                  }
                )
                
                S 2 Replies Last reply Reply Quote 0
                • S
                  Stanley @aryeh last edited by

                  @aryeh Thank you very much! It works now.

                  1 Reply Last reply Reply Quote 0
                  • S
                    Stanley @aryeh last edited by Stanley

                    @aryeh Could you please help me another problem? As Hawkeye64 suggested, don’t forget to call this.$root.$off(‘event_name’, saveXX()) in the beforeDestroy(), currently the callback is a anonymous function, so can I write simply as this?
                    this.$root.$off(‘event_name’). // ignore callback function

                    1 Reply Last reply Reply Quote 0
                    • A
                      aryeh last edited by aryeh

                      If you have a “long running application”, then use a “named” function as a global event bus listener rather than an anonymous one. This allows you to remove the event listener as Hawkeye64 mentioned.

                      You should not just use the event name as an argument for the $off method. Doing so will remove all event listeners for this event name. A specific listener is removed by providing both the event name, and a reference to the listener.

                      See the documentation for $off() at https://vuejs.org/v2/api/#vm-off for an explanation.

                      Be aware that a global event bus (i.e. via Quasar’s $root) is normally used between sibling components. Parent-child components do not need to do so, and do not require any explicit cleanup.

                      1 Reply Last reply Reply Quote 0
                      • Hawkeye64
                        Hawkeye64 last edited by

                        @Stanley if you do not turn the event off in the beforeDestroy() then that stale code will be run unexpectedly. Unless that’s what you want it to do. But when that component is mounted again, you’ll create another event instance and it’ll get run twice, and so on.

                        1 Reply Last reply Reply Quote 2
                        • S
                          Stanley last edited by

                          Thank you all! Appreciate for your help! I learnt a lot.

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post