Vue Basics

Posted on  by admin

You’re browsing the documentation for v2.x and earlier. For v3.x, click here. Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable.


The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects.

On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries. If you’d like to learn more about Vue before diving in, we created a video walking through the core principles and a sample project.

Objective: To setup a local Vue development environment, create a starter app, and understand the basics of how it works.

Anatomy of a Vue file

If you are an experienced frontend developer and want to know how Vue compares to other libraries/frameworks, check out the Comparison with Other Frameworks. The official guide assumes intermediate level knowledge of HTML, CSS, and JavaScript.

If you are totally new to frontend development, it might not be the best idea to jump right into a framework as your first step - grasp the basics then come back! Prior experience with other frameworks helps, but is not required. The easiest way to try out Vue.js is using the Hello World example. Feel free to open it in another tab and follow along as we go through some basic examples. Or, you can create an index.html file and include Vue with:. The Installation page provides more options of installing Vue. Note: We do not recommend that beginners start with vue-cli, especially if you are not yet familiar with Node.js-based build tools.

If you prefer something more interactive, you can also check out this tutorial series on Scrimba, which gives you a mix of screencast and code playground that you can pause and play around with anytime. At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax:. We have already created our very first Vue app!

This looks pretty similar to rendering a string template, but Vue has done a lot of work under the hood. The data and the DOM are now linked, and everything is now reactive. How do we know? Open your browser’s JavaScript console (right now, on this page) and set app.message to a different value.

Working with Forms

You should see the rendered example above update accordingly. Note that we no longer have to interact with the HTML directly. A Vue app attaches itself to a single DOM element (#app in our case) then fully controls it. The HTML is our entry point, but everything else happens within the newly created Vue instance. In addition to text interpolation, we can also bind element attributes like this:.

Conditional Rendering

Hover your mouse over me for a few seconds to see my dynamically bound title! Here we are encountering something new. The v-bind attribute you are seeing is called a directive.

  1. Directives are prefixed with v- to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM.
  2. Here, it is basically saying “keep this element’s title attribute up-to-date with the message property on the Vue instance.”.
  3. If you open up your JavaScript console again and enter app2.message = 'some new message', you’ll once again see that the bound HTML - in this case the title attribute - has been updated. It’s easy to toggle the presence of an element, too:. Go ahead and enter app3.seen = false in the console.
  4. You should see the message disappear. This example demonstrates that we can bind data to not only text and attributes, but also the structure of the DOM. Moreover, Vue also provides a powerful transition effect system that can automatically apply transition effects when elements are inserted/updated/removed by Vue.
  5. There are quite a few other directives, each with its own special functionality. For example, the v-for directive can be used for displaying a list of items using the data from an Array:.
  6. In the console, enter app4.todos.push({ text: 'New item' }). You should see a new item appended to the list. To let users interact with your app, we can use the v-on directive to attach event listeners that invoke methods on our Vue instances:. Note that in this method we update the state of our app without touching the DOM - all DOM manipulations are handled by Vue, and the code you write is focused on the underlying logic.
  7. Vue also provides the v-model directive that makes two-way binding between form input and app state a breeze:. The component system is another important concept in Vue, because it’s an abstraction that allows us to build large-scale applications composed of small, self-contained, and often reusable components.

If we think about it, almost any type of application interface can be abstracted into a tree of components:.

In Vue, a component is essentially a Vue instance with pre-defined options. Registering a component in Vue is straightforward:. Now you can compose it in another component’s template:. But this would render the same text for every todo, which is not super interesting. We should be able to pass data from the parent scope into child components. Let’s modify the component definition to make it accept a prop:. Now we can pass the todo into each repeated component using v-bind:. This is a contrived example, but we have managed to separate our app into two smaller units, and the child is reasonably well-decoupled from the parent via the props interface.

We can now further improve our component with more complex template and logic without affecting the parent app.

Deploying a Build to GitHub Pages

In a large application, it is necessary to divide the whole app into components to make development manageable. We will talk a lot more about components later in the guide, but here’s an (imaginary) example of what an app’s template might look like with components:.

  • You may have noticed that Vue components are very similar to Custom Elements, which are part of the Web Components Spec.
  • That’s because Vue’s component syntax is loosely modeled after the spec. For example, Vue components implement the Slot API and the is special attribute. However, there are a few key differences:. The Web Components Spec has been finalized, but is not natively implemented in every browser.
  • Safari 10.1+, Chrome 54+ and Firefox 63+ natively support web components. In comparison, Vue components don’t require any polyfills and work consistently in all supported browsers (IE9 and above).
  • When needed, Vue components can also be wrapped inside a native custom element. Vue components provide important features that are not available in plain custom elements, most notably cross-component data flow, custom event communication and build tool integrations. Although Vue doesn’t use custom elements internally, it has great interoperability when it comes to consuming or distributing as custom elements. Vue CLI also supports building Vue components that register themselves as native custom elements. We’ve briefly introduced the most basic features of Vue.js core - the rest of this guide will cover them and other advanced features with much finer details, so make sure to read through it all!
  • We will be doing the following:. Learn how to define routes and setup the Curi router. Learn how to render Vue components based on the current location. Learn how to navigate within the application. We will be [email protected]/clito develop this website. The instructions here assume that you have NodeJS and NPM > 5.2 installed on your computer. If you do not, cannot, or prefer to avoid setup altogether, you can follow along usingCodeSandbox. Some of the boilerplate will be different, but the differences are minor. Begin by opening a terminal and navigating to the directory where you want to save your code. Then, we will use @vue/cli to create the application. The dev server will automatically update when we change files, so we can leave that running.

When we create the router, we will pass it a history function that will be used to enable navigation. Curi uses the Hickorylibrary for its history. There are a few Hickory packages to choose from for different environments.

History and Locations

For most websites, [email protected]/browser is the right choice for the front end. We can import the browser function [email protected]/browser in our index file (src/index.js, which create-react-app created for us). Routes are JavaScript objects that define the valid locations for a router.

They have a name and a path. A route's name needs to be unique. We will use route names when we navigate within the application. A route's pathdescribes the location pathname that it should match. Route paths are strings describing the pathname segments they should match. Paths never begin with a slash. Paths can include dynamic parameters. These are specified with a string that starts with a colon (:) followed by the name of the params.

Routes can be nested using the children property of a route. A nested route inherits the path from its ancestor route(s), so its path is only the additional part of the pathname that should be matched. The website will start with four routes. The catch all route uses a regular expression syntax to indicate that it should match everything.

Curi uses thepath-to-regexppackage for route matching.

What is Vue?

We will only be using some of its basic syntax, but you can read its documentation to learn about more advanced path syntax. Inside of the src directory, we will create aroutes.js file where we can define the application's routes. We can create an array of routes using the above names and paths.

@curi/router provides a prepareRoutes function, which is used to setup routes for the router. We will pass the routes array to prepareRoutes and export the result of that function call.

With the history object created and the routes defined, we are ready to create the router. Back in the src/index.js file, we should import the createRouter function [email protected]/router as well as our routes fromsrc/routes.js. Creating the router is done by calling thecreateRouter function and passing it the history function and the routes array.

The Eslint warning has now moved to the router, but this is still nothing to worry about. The router is now ready and we can render the application, but first we should do something really important: make the site more accessible. In a multi-page application, a screen reader will announce navigation to users. This happens automatically when a new Document is loaded. A single-page application reuses its Document, which is great for removing unnecessary server requests, but also means that the navigation is no longer automatically announced.

Curi has a concept of "side effects". These are functions that are called after a navigation happens and are passed an object with data about the navigation. The @curi/router package provides a few side effects that are useful for websites. For now, we will focus on theannounceside effect. The announce side effect returns a string, which sets the text content of aARIA Live region. Screen readers will detect the changed text and read it to the users. Let's go ahead and add the announce side effect to the router.

We will have it return a string of the response'spathname. We will add router support to the Vue application using a plugin. This plugin does a couple of things. First, it makes some Curi components available within the application.

The only one of these components that we will be using is the curi-link. Second, it makes router related values accessible to the components in the application. The router is available asthis.$router and the response andnavigation (we will cover these next) are grouped underthis.$curi.

When the CuriPlugin is installed, the router as passed in the options object. We can now render our application. We will re-use the provideApp.vue file. Whenever Curi receives a location, it matches its routes against it and generates a response. This is an object with data related to the route that matched the location.

DOM Template Parsing Caveats

Later on we will modify this data ourselves, but for now the important thing to know is that the response lets us know about the current route. The router uses an observer model to let functions subscribe to be called when a new response is generated. The CuriPluginsets up an observer so that it can trigger a re-render whenever there is a new one.

The navigation object contains additional information about a navigation that doesn't make sense to include in the response object. This includes the navigation's "action" (push, pop, or replace) and the previous response object.

This can be useful for animation and modals. Most of the time, the response is the only property you will need to use to render, but the other two may occasionally be useful. How do we use the response to render? Any way you want. Based on the sample response above, the name stands out as the best way to identify which route matched. We can make this even easier by adding another property to the response: body.

Computed Properties

Earlier it was mentioned that response objects can be modified. This is done by returning an object from a route's respondfunction. respond receives an object with a whole bunch of properties that we can use to help determine how to modify the response, but for the time being, we don't care about any of those.

All we need to know is that if we return an object with abody property, that value will be set on our response object. If the return object's body property is a Vue component, we can render it using .

We haven't actually defined components for our routes yet, so we should throw together some placeholders.

These components can be imported in src/routes.js and attached to their respective routes. We can now update App.vue to renderresponse.body as a component, which as mentioned above is available through this.$curi. We can also remove the HelloWorld component.

At this point in time our app is rendering, but is isn't very interesting because we cannot navigate between locations.

The CuriPlugin makes a curi-link component available with the appliaction. We can use that to navigate between locations within our application.

Navigation isn't done by manually typing the pathname of the location the link should navigate to. Instead, we specify the name of the route using the name prop. If a route has params, we provide these to the curi-linkas a params object.

For a nested route, we would also need to provide params for any ancestor routes.

Attribute Binding

The curi-link is only for in-app navigation. If you want to link to pages outside of the application, use an anchor. If you need to attach query or hash data to a curi-link, use the query and hash props.

We will start with creating a navigation menu component with links to our home page and checkout page. We can import that in our App.vue file and add it to our template. This is a good opportunity to also add some structure to the elements in the template.

We want to be able to link to individual books from the home page. First, we need data about the books. For now, we're going to hard-code the books in the src/books.js module.

Deleting Items

  • You can copy+paste or modify the data, but the structure of the provided data should stay the same.
  • The data can be imported in the Home component.
  • We will iterate over the books with a curi-link to each one.
  • Now that we can navigate to the books, we should fill out the UI for the Book component.
  • We will once again import thebooks.js data.