Phoenix with: a JSON API and Vue.js, or, HTML (eex) with partial use of Vue?

I hope you can help me choose between two possible setups:

a. Phoenix JSON API on the back-end and Vue.js on the front end to render views / lists / filters / forms (basically all UI).

b. Phoenix HTML views (eex) and partial use of Vue.js on the UI for special elements (such as nested forms).

Which solution gives better overall user performance experience?

4 Likes

I am seeing that using Vue.js within Pheonix HTML files can be better, since Phoenix keeps taking care of routing and there is no need to run two servers, one for backend and another for front end.

2 Likes

It depends on what you want to build…

If you build a simple webapp with some simple forms and static sites, you are better off using Phoenix html…

If you build a highly interactive single page application and you might want to add other clients later (for example a mobile app) I would recommend to build the front end completely with Vue.js.

1 Like

Let’s say that I need to render some html element conditionally if the currently logged in user has a particular role. How could VueJS access that information inside its templates and render accordingly ? In Phoenix HTML, that’s easy but how to do that in a complete VueJS build with a Phoenix JSON API backend?

When You are completely separating frontend from backend, it is usually nice to use a state manager that will hold the state of your UI. In your case, storing user and maybe roles.

This can be done by Redux, or Vuex if You use Vue. Or by any similar tools…

Here is a blogpost that compares both…

1 Like

I’m curious too. No answer for this?

@hlx and I are using a different approach, also using Vue and Elixir. We’re running a Elixir server with a GraphQL endpoint using Absinthe, which allows for a lot of flexibility and is quite nice to work with. Alongside that, we’re deploying our Vue application as a static web app to Netlify which is also incredibly easy to do.

GraphQL allows you to query multiple resources in one HTTP request, which might end up getting better performance for your users.

3 Likes

What part specifically? It’s highly dependent on what you’re doing. There’s plenty of ways to communicate with the back-end, either by implementing router solutions for your front-end, making ajax calls, using libraries that handle that, etc.

That’s a game I’m developing (it’s fairly more developed now than when that video went up). All the logic is processed in the server, which then serves the state through Phoenix Channels, on the front-end it’s a Vue application, that hooks to the “game” channel the user is playing and to a particular “user” channel just for him.

From the state that I pass from the server I bind information to each user’s Vue instance, which then is used on the component to draw the gameboard. Users only emit certain messages to the server, such as “pass”, “cast” (with the additional info of what they chose), “strike” (again with the relevant info), the server processes those calls, checks for legality, and if everything lines up correctly broadcasts a new state, which the vue instance receives through the form of a event listener, and re-binds the information to it’s relevant variables, from which the component again redraws the gameboard.

The “game lobby” parts is also composed of a vue instance, with two components, a “list” of games (open, closed, etc, that gets refreshed through a broadcast from the back-end whenever there are changes), and a component to “create/open” a new game and wait opponents. Then the same logic, when someone joins a game, the back-end processes that, and fires a broadcast which is interpreted in the vue part of the front-end and reflected on the page.

4 Likes

Here I am answering my own question :slight_smile:

I have gained in the meantime some experience in VueJS. Any use of VueJS inside Phoenix means creating JSON API endpoints, so the best solution is to create a pure JSON/API Phoenix application and use VueJS for the UI (front-end).

VueJS is simply amazing. I have already created some friendly UI using VueJS with log-in, pagination, routes, filters etc.

1 Like

Hi, thank you for your reply. Your game looked so smooth!

I want to dynamically adding element like when using Jquery but this time using Vuejs. But after seeing author’s latest answer I think it’s impossible.

@herdibintang you are welcome to share what you want to achieve using jQuery (the code) and get feedback as to if the same can be done in VueJS.

Ah thank you very much.

What i want is something like TodoMVC but using HTML generated by Phoenix. Using Jquery i can use append to insert an element, but i don’t know how to do it using Vuejs.

The site you mentioned already have such a thing written in VueJS… There should be an object holding all the todos with a for each like rendering for every todo (e.g. li). You append new todo to the todos object and that’s it. Or post a new todo to the back-end and refresh the list by a subsequent api call (to index action).

VueJS supports also Server side rendering, yet I have not tried it yet.

But the HTML file is already written using Vuejs syntax in the first place. What i want is manipulate HTML file generated by Phoenix. Just like when you can manipulate it with Jquery but this time with Vuejs.

I’m sorry but what is the relation between the one i want to Server side rendering?

You can do that. You can manipulate any html file with VueJS without using the template tag. Look at this: https://jsfiddle.net/pu8pp62v/3/

I think Vue works in a different way than what you’re trying to do, you define “templates” and “components” and vue only interacts with the contents of these components, it has no knowledge of the external or involving html, beyond the root mounting element.

If you just intend to bind a “value” you get from your controller into a vue component, then you can do something like this: https://jsfiddle.net/keL13yzk/1/
(you’ll probably need to render the value raw so it doesn’t get escaped by phoenix)
So that the “list” is started with the values you got from the controller.

You’ll still need to create your template interactions and so on in vue to have the interactivity, so you’ll need to extend that a bit more.

1 Like

What do you find so compelling about this particular approach?

  • You have to maintain two distinct implementations of how a list item is rendered that have to be kept in sync, one with EEx on the server side, another with jQuery in the browser.
  • The jQuery functionality still only works if the JavaScript is enabled in the browser and jQuery appended elements are still “JavaScript rendered”.
  • Because jQuery manipulates the browser’s DOM directly you have to carefully consider the approach you take when you manipulate the DOM - some approaches are quick and clean, while others are sluggish and glitchy. With Vue.js it’s VDOM’s job to figure out the best way to update the DOM so it’s one less thing to worry about.

Now if it’s progressive enhancement you’re after then it’s possible to delivery base HTML to the browser and have Vue.js components replace it if JavaScript is enabled. Unfortunately that would still mean that you have two ways of doing the same thing. Note that progressive enhancement is different from a progressive web app.

I personally like Vue.js 2 Single File Components - the markup and the code that manipulates it are in the same place (whether the styles belong there is a separate issue), keeping it nicely compartmentalized. Code organization and compartmentalization takes a lot more discipline in jQuery based projects; unfortunately in many cases things are often not as well separated (and therefore decoupled) as they should be.

Yeah but you can’t do this if the html file is generated by Phoenix right?

You’re right.
I read some articles that suggests to learn Vuejs after learning Jquery. Because of that i thought you can do things in Vuejs the same way you can do things in Jquery.[quote=“peerreynders, post:17, topic:9185”]
What do you find so compelling about this particular approach?
[/quote]
Hello. Thank you your reply is rich of references!
I just want to add interactivity to Phoenix. But splitting Vuejs and Phoenix (as API server) will do a lot of work.

If you have experience with JS frameworks like Angular or React and if you have some general programming experience, believe me it will not take you more than 3 days to learn it all and create super interactive application with Phoenix in the back-end and VueJS on the front-end. 3 week ago I didn’t even know about VueJS at all :slight_smile:

You may be underestimating the work of the jQuery version. After you append that item to the list in the browser you still have to make an AJAX call to insert that item into the database. So most likely you are going to be building an API anyway. So in fact a separate Vue.js frontend with a Phoenix API could be a much cleaner solution.

I think the idea that was being conveyed is that Vue.js can be gradually introduced into an existing web site that already used jQuery - i.e. it isn’t necessary to switch to Vue.js all at once.

Have you had a look at Vue.js vs jQuery: Use Cases and Comparison with Examples yet?

Some other articles:
A Vue.js introduction for people who know just enough jQuery to get by
Vue.js Tutorial: From jQuery to Vue.js
Guide to Vue.js for jQuery developers