4

I've got a specific question that I'm struggling to find information online for. I've successfully installed VueJS into my Rails 6 app using webpacker and have a root component registering just fine on my application layout file:

<!-- application.html.erb -->
<!-- javascript pack tags loaded in head and my app component displays the template properly -->
<div id="vue-app-root">
    <app></app>
</div>

I'm aware that in a single-page app, the VueJS app initializes a single time upon visiting the website and then async requests are made and view/template changes are initiated by VueJS - all makes sense. My question pertains to how exactly the vue app initialization should work with a multi-page app.

Does the app initialize completely on every reload/turbolink load? If I'm just using a few components here and there in various pages, am I stuck with having the entire VueJS app initialize on each page load and then, subsequently, the components? If so, should I have the Vue JS app initialize on the body tag (or a root element) within the application.html.erb or should I have the app initialize only on the pages that have components?

karns
  • 5,391
  • 8
  • 35
  • 57

2 Answers2

1

To @sjaustirni's answer, I'd add that depending if you want to use Rails integrated routing or not, you may split the 2 codebases. What I mean: if you do only use Rails as an API and not it's routing, you should put the Vue project in it's own repo rather than mixing both.

Of course if you're using Rails' routing, it makes sense to keep both in the same place.

Also, I would like to share the existence of vue-turbolinks which may be useful in your case, especially if using Hotwire.
Here is a video explaining it: https://gorails.com/episodes/how-to-use-vuejs-and-turbolinks-together

kissu
  • 40,416
  • 14
  • 65
  • 133
1

You need to find out what is responsible for your routing - Vue or Rails?

If it is Rails, then yes, Vue app will need to be remounted on every page load. This applies whether or not you use Turbo/Turbolinks, as long as Vue app is in the fetched partial. If the fetched partial is outside the Vue container and you use Turbo/Turbolinks, Vue app will not be reloaded. This is true even for a server rendered Vue which hydrates on client.

If it is Vue that does the routing, Rails may not do it, otherwise Vue app will always be reloaded.

sjaustirni
  • 3,056
  • 7
  • 32
  • 50
  • 1
    I just want to add a comment that as I play with this I'm learning some good things. Though not directly related to the question, it's worth noting that wrapping the Vue app in a place in the layout.html.erb file means all loaded views into the yield will be processed by Vue. This caused some JQuery plugins that I was using to fail completely, so I had to initialize my Vue app specifically where I wanted to use it. – karns May 14 '21 at 18:23
  • I've since progressed to the stage where I replaced all Jquery objects with Vue JS plugins and have one single root vue app in the layout.html.erb. Now anywhere I want to add a piece of Vue JS logic or component, I'm able to and it will render it properly. The biggest challenge presently is maintaining state for the vue components since it isn't a full fledged vue app with router capabilities. – karns Nov 18 '21 at 17:37
  • @karns Do you want to maintain state across components on the same page, or across pages? – sjaustirni Nov 20 '21 at 09:35
  • Component(s) on the same page. I'm okay with the constraint that if a page reloads with a server side request that I'll have to start from a fresh VueJS state. – karns Nov 24 '21 at 18:57