Academind Logo

Vue Q&A

ES6 vs ES5? Using 3rd party libraries? How to manage state? Hosting and deployment? Broken routing? Find out how it works!

Created by Maximilian Schwarzmüller
#

Summary

There are some questions I see quite a lot. Let me try to answer them - both in the video and this article!

  1. Do you need a complex project setup? (0:28)

#

Do I need a Complex Setup?

Or can you just import vue.js into your .html file and get started writing awesome Vue code?

The answer is: Yes, you can do that, you don't need a complex setup (i.e. one that uses Webpack, Babel and what have you).

The easiest way to get started with Vue is indeed to simply add the following import to your HTML file:

<body>
...
<script src="path/to/vue.js"></script>
</body>

Alternatively, you can of course use a CDN link.

You might want a more complex setup - that means a build workflow that includes JavaScript transpilation, linting, bundling etc - for bigger apps AND if you're building single page applications (SPAs).

Why?

Simply because it's easier for your as a developer!

You get a lot of convenience features, warnings if you're writing bad or incorrect code, highly optimized code and you can use Single File Components - a feature that's especially useful when creating SPAs.

But if you're just trying to add some Vue magic to your app, definitely go with the simple drop-in approach.

If you want a more complex workflow, I strongly recommend using the Vue CLI though - it makes the project setup a breeze!

#

Should you use ES6+ or ES5?

That's another question I see quite a lot. ES6+ vs ES5?

ES6+ simply means: "The latest JavaScript features" - for example arrow functions.

Here's an example for some ES5 Vue Code:

export default {
methods: {
onClick: function(event) {
// do something awesome
},
},
}

And here's one for ES6+:

export default {
methods: {
onClick(event) {
// do something awesome
},
},
}

Which one of the two should you use?

The answer is: It's really up to you but typically you have an easier life and more fun if you use the next-gen features. Some problems simply can be solved easier then.

#

What's the Difference between Vue Instances and Components?

Vue components in the end extend Vue instances. You have access to the same Vue features (like data, methods, ... - not to el though) in there but there's one super-important difference!

Vue components are re-usable. You can define your own "HTML Tag" (e.g. my-cool-component) and then use it anywhere in your Vue app (depending on whether it was defined as a global or local component).

Vue instances always only control one element of your DOM and therefore aren't re-usable.

Here's an example:

<div id="my-app">
<my-component />
</div>
Vue.component('my-component', {
template: 'Hi, here is a component!',
})
new Vue({
el: 'my-app',
})

In this example, we define the my-component component and use it within the <div> that has the my-app id. That <div> is controlled via a Vue instance that hence can render the Vue component. And we could use the component as often we want.

Of course Vue component templates can be more complex and use regular HTML markup as well as other components.

Components are the core building block of anything but very small Vue apps and I strongly recommend looking into Single File Components for creating them. You'll have much more fun with that approach!

#

How to integrate 3rd Party CSS and JS Libraries

"How can I add library XY to my Vue project?"

That's a question I see quite a lot. The good thing is: It's really easy to add libraries to a Vue project. I'm going to assume a project which uses a setup created by the CLI. If you just dropped Vue into a HTML file, you can do the same for other packages.

So how do you add a library to a CLI-created project?

The easiest solution is to use npm:

npm install --save my-library

Once that's done, you can import it into your main.js or index.js (whatever you have) file in your src/ folder.

Yes, you read this correctly - I didn't ask whether it's a CSS or JS library, you can import both types of files - Webpack (to be precise: some webpack module loader) will figure it out and make sure everything gets bundled and loaded correctly.

Here's an example how that would look like for some JS library:

import 'my-library';
// Or:
import 'path/to/my/file.js'; // though you can omit the .js
new Vue({...})

For a CSS file it would look like this:

import 'path/to/my/file.css'; // DON'T omit .css - Webpack needs that
new Vue({...})
#

Can Everyone see your Code?

If you open your developer tools, you'll notice that you can view your source code (even the un-minified one, thanks to sourcemaps) relatively easy.

Everyone can see your code!

JavaScript runs in the browser and it's not pre-compiled - this means that it's readable by everyone who's on your web page. It may be minified and obfuscated but this can only make it harder, not prevent it. There's nothing you can do about that!

Is this a deal breaker though?

No! It just means that you shouldn't put security-relevant or sensible information into your frontend JavaScript code. All your other code may be accessible but it typically also doesn't hold any important information for hackers.

Due to your code being accessible to everyone, you should always rely on server-side validation of user input though. You can write the best validation code in the world using Angular's form validation capabilities but since any use can simply re-write or break that code, you always need to validate on the server, too!

Frontend code is all about providing a good user experience (e.g. via instant validation results) not about securing your database.

#

"Can I use Vue with Redux?"

Yes - though you typically wouldn't use Redux but Vue's own implementation: Vuex.

Vuex is inspired by Redux but integrated nicely into "the Vue world". It also knows state and actions but then uses mutations instead of reducers and uses getters to fetch values.

#

"Can I use Vue with PHP/Node/...?"

I often see the question whether you can use Vue with PHP, Node.js or some other server-side language.

And the answer is: Yes, absolutely!

Vue doesn't care about your backend and your server-side language, it's a client-side framework, it runs in the browser!

It also doesn't matter if you drop your Vue import into the (server-rendered) HTML files or if you're building a SPA. In both cases, Vue only manages the frontend!

If you're building a SPA, you only communicate with servers through Ajax requests (via libraries like axios), hence your backend needs to provide a (RESTful) API to which Vue can send its requests. And that's all!

One exception is important though: If you're using server-side pre-rendering of Vue apps (e.g. via Nuxt.js), you'll still not use Vue to write server-side code (i.e. to access databases, work with file storage or anything like that) but you pre-render your Vue apps on the server. That only works with Node.js as of now though, so if that's important to you, you should go with Node.js

#

How to prevent State Loss after Page Refreshes

Here's a question I observed a lot: "If I press the refresh button in my browser, my app state resets. How can I prevent this?"

It's true! If you hit that refresh button, your page reloads and since Vue runs entirely in JavaScript, your script restarts and you app state is lost. That's not a bug but the expected behavior.

If you're coming from a "traditional" web development environment, where you built web pages by rendering views in your server-side language, that's a strange behavior. You used to use Sessions to manage the user state for example. Page refreshes would therefore not lose that state.

In single page applications Vue (or other frameworks and libraries) creates, you don't use sessions though. The reason is simple: Your app is decoupled from your backend. You only have one single page in the end and your (RESTful) API to which you talk occasionally doesn't care about your app - it's stateless.

If you're dropping Vue into server-rendered HTML files though, this doesn't matter. Your server is taking care about all views and tying them together.

But back to SPAs: So you don't use sessions - what do you do instead?

You have two common options to still persist user state (e.g. "Is the user logged in"?):

  1. Use localStorage to store simple key-value pairs like a JSON Web Token (JWT) you got from your backend (a pattern commonly used for authentication in SPAs).

  2. Use a server-side database for state/ data that needs to persists long-term.

localStorage is a common choice to store client state. It's lost if the user clears all browser data, so it's not suitable for data that needs to be stored long-term. It's also accessible via JavaScript (and by the user), so you shouldn't store security-relevant information there. You do regularly use it to store JWTs though - tokens that are short-lived (for security reasons) and grant the user access to some protected resources on the backend.

You can use localStorage to store state across page refreshes by following this pattern:

  1. Store data in localStorage once you have it (e.g. store a JWT once you received it).

  2. When your app starts, check if the data is stored in localStorage - a good place is inside the created() lifecycle method in your App.vue component since that will execute right at the start of your application life.

  3. Initialize your app with any (optionally validated) data you got from localStorage if available.

By using this pattern, you can start your app in the same state you left it.

Use server-side databases for any data that's not really relevant to the client upon page refreshes but which should instead be stored long-term or which should be synchronized across different devices (e.g. a selected user location).

#

"Can I host my App on Heroku etc?"

"Can I host my Vue single page app on Heroku or a comparable service"?

That's a question I also see a lot!

The answer is: Generally, yes - you can of course host your app on any web hosting service. But there are services which are better suited than others. Heroku for example is a service that's built to allow you to easily host PHP, Node.js etc. apps. It spins up fitting environments (i.e. configures the servers, interpreters etc needed by the selected language) and makes sure that you don't have to spend hours setting this all up.

But Vue doesn't use any server-side language! It's - after your ran npm run build - just a bunch of JavaScript and CSS files as well as the index.html file. You don't need a Node server for that!

Therefore, for Vue single page apps, static website hosts like AWS S3 or Firebase Hosting are better choices. They're typically cheaper, super-easy to setup and don't require you to add overhead code (like a dummy Node.js server) to just ship your files to your users.

If you're just using Vue in server-side rendere apps, i.e. where some server-side templating engine generates the views, you will need a host that runs that server-side language of course.

#

How to fix broken Routes after Deployment

After deploying a Vue single page app to a real server, I sometimes hear that the routing stops working. At least if users directly visit any other page than the main page - say https://my-app.com/products or if users refresh the browser whilst being on such a "sub-page".

To understand this "error" (it's not really an error), we have to understand how routing really works in an Vue app.

Vue stores the routes, not the server.

Vue stores and manages your routes, not the server that's hosting your Vue app! Keep in mind that that server only serves the index.html file - that's about its only job!

Important: This is only true for Vue single page apps!

Therefore, your server can't do anything with an incoming request pointing at a /products route - it's totally unknown to it! Due to the way the web works, requests reach the server though and your client (i.e. the Vue app) doesn't even get loaded as the server throws a 404 error.

So what can we do to solve that issue?

The solution is simple: Your server should always serve the index.html file, especially in 404 error cases! If you configure your server to do that (static hosts like AWS S3 or Firebase provide easy-to-use configurations to achieve this behavior), your Vue app gets loaded and gets a chance to handle the request.

If you still want to render a 404 error page for routes that are really unknown, i.e. that are also not configured in your Vue app, you'll ne to add a catch-all route like this:

// Configure all other routes first or they'll not be considered!
{ path: '404, component: My404Page },
{ path: '*', redirect: '/404' }

Recommended Courses