Vue inline templates



  • Hoping someone can help.

    I am trying to set up quasar to work with rails, and am using the UMD option. It’s been tricky so far, but I’ve got things basically working. Quasar components appear in properly in html.erb templates. But, when I try to make a vue component using the inline-template method, any quasar components I put inside the vue component inline-template do not appear; and are not present in the DOM.

    Here is my code:

    <my-test inline-template>
      <div> {{message}} </p></div>
      <q-btn color="amber" label="I don't appear" ></q-btn>
    </my-test>
    
    <div><q-btn color="amber" label="I appear" ></q-btn></div>
    
    <script>
      Vue.component('my-test', {
        data: function () {
          return {
            message: "This text appears!"
          }
        }
      })
    </script>
    

    Any advice on what I am doing wrong? I am guessing that you need to register the Qbtn component within the vue component, but I don’t know how you would do that because using UMD does not enable you to do a quasar component import, at least not that I can figure out.



  • You could try using the components property to locally register the q-btn component.

    https://vuejs.org/v2/guide/components-registration.html#Local-Registration

    Scott



  • And why not just use Ruby as an API with something like Ruby Grape and go full SPA with Quasar’s own SSR? You’ll have it a whole lot easier during development and have a whole lot more flexibility.

    Scott



  • @s-molinari

    Thank you for the reply!

    Your suggestion to use the components property is along the lines of what I suspected to be the answer, or at least part of it.

    Using the following code, I am able to get rid of the error, but the button inside the inline-template still does not render:

    <my-test inline-template>
      <div> {{message}} </p></div>
      <div><q-btn color="amber" label="I don't appear" ></q-btn></div>
    </my-test>
    
    <div><q-btn color="amber" label="I work fine" ></q-btn></div>
    
    
    <script>
      var qbutton = Quasar.components.Qbtn;
    
      Vue.component('my-test', {
        data: function () {
          return {
            message: "Hello!"
          }
        },
        components: {
         'q-btn': qbutton
        }
      })
    </script>
    

    In devtools, you can see the variable window.qbutton, but it is undefined. The question is, how do you you get a hold of the Quasar component to assign it to a variable within the script tag? If Quasar was installed as an npm package rather the using the UMD, I am guessing I could do an import.

    Regarding your question as to why I am not just developing a standalone front end app using the CLI, I would very much like to do so, but am still trying to wrap my head around how to keep data synchronized across multiple clients. I am trying to find the path of least resistance, and don’t want to get involved with firebase or couchdb at the moment. Admittedly, I know only enough about this stuff to get myself into trouble. If anything I am saying sounds silly, please correct me.



  • Try Quasar.components.QBtn. Notice the capital “B”. 😄

    If you need synchronized clients, your Ruby backend API would need to handle something like web sockets and you’d need a websocket client. That is, if you mean synchronized like in a chat application.

    Scott



  • By the way, you might have known this, but for anyone else out there that found this thread and wonders how we came to get the QBtn component name, you can find the list of components under the components property in the Quasar global variable.

    https://codepen.io/smolinari/pen/NVvGOV

    Scott



  • @s-molinari That’s VERY useful to know … thanks for letting us all know that.



  • @s-molinari, thanks for continuing to humor me on this.

    Good catch on “QBtn” vs “Qbtn”, but, unfortunately, it doesn’t fix it. I thought we were really on to something.

    Just so everything is documented, here is the code (I removed a stray </p> tag):

    <my-test inline-template>
      <div> {{message}} </div>
      <div><q-btn color="amber" label="I don't appear" ></q-btn></div>
    </my-test>
    
    <div><q-btn color="amber" label="I work fine" ></q-btn></div>
    
    <script>
      var qbutton = Quasar.components.QBtn;
    
      Vue.component('my-test', {
        data: function () {
          return {
            message: "Hello!"
          }
        },
        components: {
         'q-btn': qbutton
        }
      })
    </script>
    

    FYI, for data synchronization, I was going down the actioncable path until I discovered that it doesn’t offer guaranteed delivery, i.e. if a message is broadcast while a client is disconnected, it will not be resent when the client reconnects. I have to look at polling and SSE to see if either offer an acceptable solution.

    Thanks for pointing out Grape. I had a very vague awareness of it, but will look into it more closely. Maybe it would be a good fit for a future project. I am curious how it differs from Sinatra. I stuck with rails on this project because I foresee needing to use a mailer, and other stuff.





  • @s-molinari
    You won’t believe it! I’ve been trying every permutation between my broken code, and your example that works, to figure out what the magic ingredient is. It turns out that all I needed to do was put a parent div within the component tags. I guess it works just like the template tags in vue single file components.

    This works:

    <my-test inline-template>
      <div>
        <div> {{message}} </p></div>
        <div><q-btn color="amber" label="I finally appear!!" ></q-btn></div>
      </div>
    </my-test>
    
    <script>
      Vue.component('my-test', {
        data: function () {
          return {
            message: "This text appears!"
          }
        }
      })
    </script>
    

    The way I am using this in rails is I have all the quasar UMD stuff and the new vue instance in the main application layout template, and then each route template I code like above. It is like simulating vue single file components, only without the css. Notice too that you don’t have to assign the component to a variable, or register it in the main vue instance.

    Thank you for helping me figure this out!!



  • Yes. A template can only have one root element. If you didn’t see this as an error in the console in your rendered app, then that will be a huge disadvantage for your architectural approach. You are also missing out on a lot of cool development experience without the Quasar CLI. Like Webpack’s HMR.

    I’d still suggest you use Rails only as an API backend. Use Node for developing Quasar in a pure Vue application. You are basically killing almost every advantage given to you by Quasar above and beyond the components. And there is a whole lot more than the components being offered in Quasar. 😃

    Scott



  • @s-molinari
    As gratifying as it was to figure this out, I strongly suspect you are right about developing separate front and backend apps, and using the CLI, being the better way to go. I have a gut feeling that roadblocks are going to keep popping up if I continue down this road, and I will be deserving of many I told you so’s. It’s the data synchronization piece that I have to come to terms with. From my research so far, SSE sounds the most attractive, but then I have to set up a message queue (was looking at rabbit), and who knows what all else. Guess it is best just to bite the bullet and learn how to do it right.

    Again, many thanks!


Log in to reply