Getting started with React - Learn web development

Getting started with React
==========================

* Previous
* Overview: Client-side JavaScript frameworks
* Next

In this article we will say hello to React. We'll discover a little bit of detail about its background and use cases, set up a basic React toolchain on our local computer, and create and play with a simple starter app — learning a bit about how React works in the process.

|  |  |
| --- | --- |
| Prerequisites: |
 Familiarity with the core HTML,
 CSS, and
 JavaScript languages,
 knowledge of the
 terminal/command line.

 React uses an HTML-in-JavaScript syntax called JSX (JavaScript and
 XML). Familiarity with both HTML and JavaScript will help you to learn
 JSX, and better identify whether bugs in your application are related
 to JavaScript or to the more specific domain of React.
  |
| Objective: |
 To set up a local React development environment, create a start app, and
 understand the basics of how it works.
  |

Hello React
-----------

As its official tagline states, React is a library for building user interfaces. React is not a framework – it's not even exclusive to the web. It's used with other libraries to render to certain environments. For instance, React Native can be used to build mobile applications.

To build for the web, developers use React in tandem with ReactDOM. React and ReactDOM are often discussed in the same spaces as — and utilized to solve the same problems as — other true web development frameworks. When we refer to React as a "framework", we're working with that colloquial understanding.

React's primary goal is to minimize the bugs that occur when developers are building UIs. It does this through the use of components — self-contained, logical pieces of code that describe a portion of the user interface. These components can be composed together to create a full UI, and React abstracts away much of the rendering work, leaving you to concentrate on the UI design.

Use cases
---------

Unlike the other frameworks covered in this module, React does not enforce strict rules around code conventions or file organization. This allows teams to set conventions that work best for them, and to adopt React in any way they would like to. React can handle a single button, a few pieces of an interface, or an app's entire user interface.

While React *can* be used for small pieces of an interface, it's not as easy to "drop into" an application as a library like jQuery, or even a framework like Vue — it is more approachable when you build your entire app with React.

In addition, many of the developer-experience benefits of a React app, such as writing interfaces with JSX, require a compilation process. Adding a compiler like Babel to a website makes the code on it run slowly, so developers often set up such tooling with a build step. React arguably has a heavy tooling requirement, but it can be learned.

This article is going to focus on the use case of using React to render the entire user interface of an application with the support of Vite, a modern front-end build tool.

How does React use JavaScript?
------------------------------

React utilizes features of modern JavaScript for many of its patterns. Its biggest departure from JavaScript comes with the use of JSX syntax. JSX extends JavaScript's syntax so that HTML-like code can live alongside it. For example:

```jsx
const heading = <h1>Mozilla Developer Network</h1>;
```

This heading constant is known as a **JSX expression**. React can use it to render that `<h1>` tag in our app.

Suppose we wanted to wrap our heading in a `<header>` tag, for semantic reasons? The JSX approach allows us to nest our elements within each other, just like we do with HTML:

```jsx
const header = (
  <header>
 <h1>Mozilla Developer Network</h1>
 </header>
);
```

**Note:** The parentheses in the previous snippet aren't unique to JSX, and don't have any effect on your application. They're a signal to you (and your computer) that the multiple lines of code inside are part of the same expression. You could just as well write the header expression like this:

```jsx
const header = <header>
 <h1>Mozilla Developer Network</h1>
</header>;
```

However, this looks kind of awkward, because the `<header>` tag that starts the expression is not indented to the same position as its corresponding closing tag.

Of course, your browser can't read JSX without help. When compiled (using a tool like Babel or Parcel), our header expression would look like this:

```jsx
const header = React.createElement(
  "header",
  null,
  React.createElement("h1", null, "Mozilla Developer Network"),
);
```

It's *possible* to skip the compilation step and use `React.createElement()` to write your UI yourself. In doing this, however, you lose the declarative benefit of JSX, and your code becomes harder to read. Compilation is an extra step in the development process, but many developers in the React community think that the readability of JSX is worthwhile. Plus, modern front-end development almost always involves a build process anyway — you have to downlevel modern syntax to be compatible with older browsers, and you may want to minify your code to optimize loading performance. Popular tooling like Babel already comes with JSX support out-of-the-box, so you don't have to configure compilation yourself unless you want to.

Because JSX is a blend of HTML and JavaScript, some developers find it intuitive. Others say that its blended nature makes it confusing. Once you're comfortable with it, however, it will allow you to build user interfaces more quickly and intuitively, and allow others to better understand your codebase at a glance.

To read more about JSX, check out the React team's Writing Markup with JSX article.

Setting up your first React app
-------------------------------

There are many ways to create a new React application. We're going to use Vite to create a new application via the command line.

It's possible to add React to an existing project by copying some `<script>` elements into an HTML file, but using Vite will allow you to spend more time building your app and less time fussing with setup.

### Requirements

In order to use Vite, you need to have Node.js installed. As of Vite 5.0, at least Node version 18 or later is required, and it's a good idea to run the latest long term support (LTS) version when you can. As of 24th October 2023, Node 20 is the latest LTS version. Node includes npm (the Node package manager).

To check your version of Node, run the following in your terminal:

```bash
node -v
```

If Node is installed, you'll see a version number. If it isn't, you'll see an error message. To install Node, follow the instructions on the Node.js website.

You may use the Yarn package manager as an alternative to npm but we'll assume you're using npm in this set of tutorials. See Package management basics for more information on npm and yarn.

If you're using Windows, you will need to install some software to give you parity with Unix/macOS terminal in order to use the terminal commands mentioned in this tutorial. **Gitbash** (which comes as part of the git for Windows toolset) or **Windows Subsystem for Linux** (**WSL**) are both suitable. See Command line crash course for more information on these, and on terminal commands in general.

Also bear in mind that React and ReactDOM produce apps that only work on a fairly modern set of browsers like Firefox, Microsoft Edge, Safari, or Chrome when working through these tutorials.

See the following for more information:

* "About npm" on the npm blog
* "Introducing npx" on the npm blog
* Vite's documentation
### Initializing your app

The npm package manager comes with a `create` command that allows you to create new projects from templates. We can use it to create a new app from Vite's standard React template. Make sure you `cd` to the place you'd like your app to live on your machine, then run the following in your terminal:

```bash
npm create vite@latest moz-todo-react -- --template react
```

This creates a `moz-todo-react` directory using Vite's `react` template.

**Note:** The `--` is necessary to pass arguments to npm commands such as `create`, and the `--template react` argument tells Vite to use its React template.

Your terminal will have printed some messages if this command was successful. You should see text prompting you to `cd` to your new directory, install the app's dependencies, and run the app locally. Let's start with two of those commands. Run the following in your terminal:

```bash
cd moz-todo-react && npm install
```

Once the process is complete, we need to start a local development server to run our app. Here, we're going to add some command line flags to Vite's default suggestion to open the app in our browser as soon as the server starts, and use port 3000.

Run the following in your terminal:

```bash
npm run dev -- --open --port 3000
```

Once the server starts, you should see a new browser tab containing your React app:

![Screenshot of Firefox MacOS open to localhost:3000, showing an application made from Vite's React template](/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started/default-vite.png)

### Application structure

Vite gives us everything we need to develop a React application. Its initial file structure looks like this:
```

moz-todo-react
├── README.md
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── public
│   └── vite.svg
├── src
│   ├── App.css
│   ├── App.jsx
│   ├── assets
│   │   └── react.svg
│   ├── index.css
│   └── main.jsx
└── vite.config.js
```

**`index.html`** is the most important top-level file. Vite injects your code into this file so that your browser can run it. You won't need to edit this file during our tutorial, but you should change the text inside the `<title>` element in this file to reflect the title of your application. Accurate page titles are important for accessibility.

The **`public`** directory contains static files that will be served directly to your browser without being processed by Vite's build tooling. Right now, it only contains a Vite logo.

The **`src`** directory is where we'll spend most of our time, as it's where the source code for our application lives. You'll notice that some JavaScript files in this directory end in the extension `.jsx`. This extension is necessary for any file that contains JSX – it tells Vite to turn the JSX syntax into JavaScript that your browser can understand. The `src/assets` directory contains the React logo you saw in the browser.

The `package.json` and `package-lock.json` files contain metadata about our project. These files are not unique to React applications: Vite populated `package.json` for us, and npm created `package-lock.json` for when we installed the app's dependencies. You don't need to understand these files at all to complete this tutorial. However, if you'd like to learn more about them, you can read about `package.json` and `package-lock.json` in the npm docs. We also talk about `package.json` in our Package management basics tutorial.

### Customizing our dev script

Before we move on, you might want to change your `package.json` file a little bit so that you don't have to pass the `--open` and `--port` flags every time you run `npm run dev`. Open `package.json` in your text editor and find the `scripts` object. Change the `"dev"` key so that it looks like this:

```diff
- "dev": "vite",
+ "dev": "vite --open --port 3000",
```

With this in place, your app will open in your browser at `http://localhost:3000` every time you run `npm run dev`.

**Note:** You *don't* need the extra `--` here because we're passing arguments directly to `vite`, rather than to a pre-defined npm script.

Exploring our first React component — `<App />`
-----------------------------------------------

In React, a **component** is a reusable module that renders a part of our overall application. Components can be big or small, but they are usually clearly defined: they serve a single, obvious purpose.

Let's open `src/App.jsx`, since our browser is prompting us to edit it. This file contains our first component, `<App />`:

```jsx
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  return (
    <>
 <div>
 <a href="https://vitejs.dev" target="\_blank">
 <img src={viteLogo} className="logo" alt="Vite logo" />
 </a>
 <a href="https://react.dev" target="\_blank">
 <img src={reactLogo} className="logo react" alt="React logo" />
 </a>
 </div>
 <h1>Vite + React</h1>
 <div className="card">
 <button onClick={() => setCount((count) => count + 1)}>
 count is {count}
 </button>
 <p>
 Edit <code>src/App.jsx</code> and save to test HMR
 </p>
 </div>
 <p className="read-the-docs">
 Click on the Vite and React logos to learn more
 </p>
 </>
  );
}

export default App;
```

The `App.jsx` file consists of three main parts: some `import` statements at the top, the `App()` function in the middle, and an `export` statement at the bottom. Most React components follow this pattern.

### Import statements

The `import` statements at the top of the file allow `App.jsx` to use code that has been defined elsewhere. Let's look at these statements more closely.

```jsx
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
```

The first statement imports the `useState` hook from the `react` library. Hooks are a way of using React's features inside a component. We'll talk more about hooks later in this tutorial.

After that, we import `reactLogo` and `viteLogo`. Note that their import paths start with `./` and `/` respectively and that they end with the `.svg` extension at the end. This tells us that these imports are *local*, referencing our own files rather than npm packages.

The final statement imports the CSS related to our `<App />` component. Note that there is no variable name and no `from` directive. This is called a *side-effect import* — it doesn't import any value into the JavaScript file, but it tells Vite to add the referenced CSS file to the final code output, so that it can be used in the browser.

### The `App()` function

After the imports, we have a function named `App()`, which defines the structure of the `App` component. Whereas most of the JavaScript community prefers lower camel case names like `helloWorld`, React components use Pascal case (or upper camel case) variable names, like `HelloWorld`, to make it clear that a given JSX element is a React component and not a regular HTML tag. If you were to rename the `App()` function to `app()`, your browser would throw an error.

Let's look at `App()` more closely.

```jsx
function App() {
  const [count, setCount] = useState(0);

  return (
    <>
 <div>
 <a href="https://vitejs.dev" target="\_blank">
 <img src={viteLogo} className="logo" alt="Vite logo" />
 </a>
 <a href="https://react.dev" target="\_blank">
 <img src={reactLogo} className="logo react" alt="React logo" />
 </a>
 </div>
 <h1>Vite + React</h1>
 <div className="card">
 <button onClick={() => setCount((count) => count + 1)}>
 count is {count}
 </button>
 <p>
 Edit <code>src/App.jsx</code> and save to test HMR
 </p>
 </div>
 <p className="read-the-docs">
 Click on the Vite and React logos to learn more
 </p>
 </>
  );
}
```

The `App()` function returns a JSX expression. This expression defines what your browser ultimately renders to the DOM.

Just under the `return` keyword is a special bit of syntax: `<>`. This is a fragment. React components have to return a single JSX element, and fragments allow us to do that without rendering arbitrary `<div>`s in the browser. You'll see fragments in many React applications.

### The `export` statement

There's one more line of code after the `App()` function:

```jsx
export default App;
```

This export statement makes our `App()` function available to other modules. We'll talk more about this later.

Moving on to `main`
-------------------

Let's open `src/main.jsx`, because that's where the `<App />` component is being used. This file is the entry point for our app, and it initially looks like this:

```jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
 <App />
 </React.StrictMode>,
);
```

As with `App.jsx`, the file starts by importing all the JS modules and other assets it needs to run.

The first two statements import the `React` and `ReactDOM` libraries because they are referenced later in the file. We don't write a path or extension when importing these libraries because they are not local files. In fact, they are listed as dependencies in our `package.json` file. Be careful of this distinction as you work through this lesson!

We then import our `App()` function and `index.css`, which holds global styles that are applied to our whole app.

We then call the `ReactDOM.createRoot()` function, which defines the root node of our application. This takes as an argument the DOM element inside which we want our React app to be rendered. In this case, that's the DOM element with an ID of `root`. Finally, we chain the `render()` method onto the `createRoot()` call, passing it the JSX expression that we want to render inside our root. By writing `<App />` as this JSX expression, we're telling React to call the `App()` *function* which renders the `App` *component* inside the root node.

**Note:** `<App />` is rendered inside a special `<React.StrictMode>` component. This component helps developers catch potential problems in their code.

You can read up on these React APIs, if you'd like:

* `ReactDOM.createRoot()`
* `React.StrictMode`
Starting fresh
--------------

Before we start building our app, we're going to delete some of the boilerplate code that Vite provided for us.

First, as an experiment, change the `<h1>` element in `App.jsx` so that it reads "Hello, World!", then save your file. You'll notice that this change is immediately rendered in the development server running at `http://localhost:3000` in your browser. Bear this in mind as you work on your app.

We won't be using the rest of the code! Replace the contents of `App.jsx` with the following:

```jsx
import "./App.css";

function App() {
  return (
    <>
 <header>
 <h1>Hello, World!</h1>
 </header>
 </>
  );
}

export default App;
```

Practice with JSX
-----------------

Next, we'll use our JavaScript skills to get a bit more comfortable writing JSX and working with data in React. We'll talk about how to add attributes to JSX elements, how to write comments, how to render content from variables and other expressions, and how to pass data into components with props.

### Adding attributes to JSX elements

JSX elements can have attributes, just like HTML elements. Try adding a `<button>` below the `<h1>` element in your `App.jsx` file, like this:

```jsx
<button type="button">Click me!</button>
```

When you save your file, you'll see a button with the words `Click me!`. The button doesn't do anything yet, but we'll learn about adding interactivity to our app soon.

Some attributes are different than their HTML counterparts. For example, the `class` attribute in HTML translates to `className` in JSX. This is because `class` is a reserved word in JavaScript, and JSX is a JavaScript extension. If you wanted to add a `primary` class to your button, you'd write it like this:

```jsx
<button type="button" className="primary">
 Click me!
</button>
```

### JavaScript expressions as content

Unlike HTML, JSX allows us to write variables and other JavaScript expressions right alongside our other content. Let's declare a variable called `subject` just above the `App()` function:

```jsx
const subject = "React";
function App() {
  // code omitted for brevity
}
```

Next, replace the word "World" in the `<h1>` element with `{subject}`:

```jsx
<h1>Hello, {subject}!</h1>
```

Save your file and check your browser. You should see "Hello, React!" rendered.

The curly braces around `subject` are another feature of JSX's syntax. The curly braces tell React that we want to read the value of the `subject` variable, rather than render the literal string `"subject"`. You can put any valid JavaScript expression inside curly braces in JSX; React will evaluate it and render the *result* of the expression as the final content. Following is a series of examples, with comments above explaining what each expression will render:

```jsx
{/\* Hello, React :)! \*/}
<h1>Hello, {subject + ' :)'}!</h1>
{/\* Hello, REACT \*/}
<h1>Hello, {subject.toUpperCase()}</h1>
{/\* Hello, 4 \*/}
<h1>Hello, {2 + 2}!</h1>
```

Even comments in JSX are written inside curly braces! This is because comments, too, are technically JavaScript expressions. The `/* block comment syntax */` is necessary for your program to know where the comment starts and ends.

### Component props

**Props** are a means of passing data into a React component. Their syntax is identical to that of attributes, in fact: `prop="value"`. The difference is that whereas attributes are passed into plain elements, props are passed into React components.

In React, the flow of data is unidirectional: props can only be passed from parent components down to child components.

Let's open `main.jsx` and give our `<App />` component its first prop.

Add a prop of `subject` to the `<App />` component call, with a value of `Clarice`. When you are done, it should look something like this:

```jsx
<App subject="Clarice" />
```

Back in `App.jsx`, let's revisit the `App()` function. Change the signature of `App()` so that it accepts `props` as a parameter and log `props` to the console so you can inspect it. Also delete the `subject` const; we don't need it anymore. Your `App.jsx` file should look like this:

```jsx
function App(props) {
  console.log(props);
  return (
    // code omitted for brevity
  );
}
```

Save your file and check your browser. You'll see a blank background with no content. This is because we're trying to read a `subject` variable that's no longer defined. Fix this by commenting out the `<h1>Hello {subject}!</h1>` line.

**Note:** If your code editor understands how to parse JSX (most modern editors do!), you can use its built-in commenting shortcut — `Ctrl + /` (on Windows) or `Cmd + /` (on macOS) — to create comments more quickly.

 Save the file with that line commented out. This time, you should see your
 "Click me!" button rendered by itself. If you open your browser's developer console, you'll see a message that looks like this:
```

Object { subject: "Clarice" }
```

The object property `subject` corresponds to the `subject` prop we added to our `<App />` component call, and the string `Clarice` corresponds to its value. Component props in React are always collected into objects in this fashion.

Let's use this `subject` prop to fix the error in our app. Uncomment the `<h1>Hello, {subject}!</h1>` line and change it to `<h1>Hello, {props.subject}!</h1>`, then delete the `console.log()` statement. Your code should look like this:

```jsx
function App(props) {
  return (
    <>
 <header>
 <h1>Hello, {props.subject}!</h1>
 <button type="button" className="primary">
 Click me!
 </button>
 </header>
 </>
  );
}
```

When you save, the app should now greet you with "Hello, Clarice!". If you return to `main.jsx`, edit the value of `subject`, and save, your text will change.

For additional practice, you could try adding an additional `greeting` prop to the `<App />` component call inside `main.jsx` and using it alongside the `subject` prop inside `App.jsx`.

Summary
-------

This brings us to the end of our initial look at React, including how to install it locally, creating a starter app, and how the basics work. In the next article, we'll start building our first proper application — a todo list. Before we do that, however, let's recap some of the things we've learned.

In React:

* Components can import modules they need and must export themselves at the bottom of their files.
* Component functions are named with `PascalCase`.
* You can render JavaScript expressions in JSX by putting them between curly braces, like `{so}`.
* Some JSX attributes are different than HTML attributes so that they don't conflict with JavaScript reserved words. For example, `class` in HTML translates to `className` in JSX.
* Props are written just like attributes inside component calls and are passed into components.
* Previous
* Overview: Client-side JavaScript frameworks
* Next


Focus management with Vue refs - Learn web development

Focus management with Vue refs
==============================

* Previous
* Overview: Client-side JavaScript frameworks
* Next

We are nearly done with Vue. The last bit of functionality to look at is focus management, or put another way, how we can improve our app's keyboard accessibility. We'll look at using **Vue refs** to handle this — an advanced feature that allows you to have direct access to the underlying DOM nodes below the virtual DOM, or direct access from one component to the internal DOM structure of a child component.

|  |  |
| --- | --- |
| Prerequisites: |
 Familiarity with the core HTML,
 CSS, and
 JavaScript languages,
 knowledge of the
 terminal/command line.

 Vue components are written as a combination of JavaScript objects that
 manage the app's data and an HTML-based template syntax that maps to
 the underlying DOM structure. For installation, and to use some of the
 more advanced features of Vue (like Single File Components or render
 functions), you'll need a terminal with node + npm installed.
  |
| Objective: | To learn how to handle focus management using Vue refs. |

The focus management problem
----------------------------

While we do have working edit functionality, we aren't providing a great experience for non-mouse users. Specifically, when a user activates the "Edit" button, we remove the "Edit" button from the DOM, but we don't move the user's focus anywhere, so in effect it just disappears. This can be disorienting for keyboard and non-visual users.

To understand what's currently happening:

1. Reload your page, then press `Tab`. You should see a focus outline on the input for adding new to-do items.
2. Press `Tab` again. The focus should move to the "Add" button.
3. Hit it again, and it'll be on the first checkbox. One more time, and focus should be on the first "Edit" button.
4. Activate the "Edit" button by pressing `Enter`.
 The checkbox will be replaced with our edit component, but the focus outline will be gone.

This behavior can be jarring. In addition, what happens when you press `Tab` again varies depending on the browser you're using. Similarly, if you save or cancel your edit, focus will disappear again as you move back to the non-edit view.

To give users a better experience, we'll add code to control the focus so that it gets set to the edit field when the edit form is shown. We'll also want to put focus back on the "Edit" button when a user cancels or saves their edit. In order to set focus, we need to understand a little bit more about how Vue works internally.

Virtual DOM and refs
--------------------

Vue, like some other frameworks, uses a virtual DOM (VDOM) to manage elements. This means that Vue keeps a representation of all of the nodes in our app in memory. Any updates are first performed on the in-memory nodes, and then all the changes that need to be made to the actual nodes on the page are synced in a batch.

Since reading and writing actual DOM nodes is often more expensive than virtual nodes, this can result in better performance. However, it also means you often should not edit your HTML elements directly through native browser APIs (like `Document.getElementById`) when using frameworks, because it results in the VDOM and real DOM going out of sync.

Instead, if you need to access the underlying DOM nodes (like when setting focus), you can use Vue refs. For custom Vue components, you can also use refs to directly access the internal structure of a child component, however this should be done with caution as it can make code harder to reason about and understand.

To use a ref in a component, you add a `ref` attribute to the element that you want to access, with a string identifier for the value of the attribute. It's important to note that a ref needs to be unique within a component. No two elements rendered at the same time should have the same ref.

### Adding a ref to our app

So, let's attach a ref to our "Edit" button in `ToDoItem.vue`. Update it like this:

```html
<button
 type="button"
 class="btn"
 ref="editButton"
 @click="toggleToItemEditForm">
  Edit
  <span class="visually-hidden">{{label}}</span>
</button>
```

To access the value associated with our ref, we use the `$refs` property provided on our component instance. To see the value of the ref when we click our "Edit" button, add a `console.log()` to our `toggleToItemEditForm()` method, like so:

```js
toggleToItemEditForm() {
  console.log(this.$refs.editButton);
  this.isEditing = true;
}
```

If you activate the "Edit" button at this point, you should see an HTML `<button>` element referenced in your console.

Vue's $nextTick() method
------------------------

We want to set focus on the "Edit" button when a user saves or cancels their edit. To do that, we need to handle focus in the `ToDoItem` component's `itemEdited()` and `editCancelled()` methods.

For convenience, create a new method which takes no arguments called `focusOnEditButton()`. Inside it, assign your `ref` to a variable, and then call the `focus()` method on the ref.

```js
focusOnEditButton() {
  const editButtonRef = this.$refs.editButton;
  editButtonRef.focus();
}
```

Next, add a call to `this.focusOnEditButton()` at the end of the `itemEdited()` and `editCancelled()` methods:

```js
itemEdited(newItemName) {
  this.$emit("item-edited", newItemName);
  this.isEditing = false;
  this.focusOnEditButton();
},
editCancelled() {
  this.isEditing = false;
  this.focusOnEditButton();
},
```

Try editing and then saving/cancelling a to-do item via your keyboard. You'll notice that focus isn't being set, so we still have a problem to solve. If you open your console, you'll see an error raised along the lines of *"can't access property "focus", editButtonRef is undefined"*. This seems weird. Your button ref was defined when you activated the "Edit" button, but now it's not. What is going on?

Well, remember that when we change `isEditing` to `true`, we no longer render the section of the component featuring the "Edit" button. This means there's no element to bind the ref to, so it becomes `undefined`.

You might now be thinking "hey, don't we set `isEditing=false` before we try to access the `ref`, so therefore shouldn't the `v-if` now be displaying the button?" This is where the virtual DOM comes into play. Because Vue is trying to optimize and batch changes, it won't immediately update the DOM when we set `isEditing` to `false`. So when we call `focusOnEditButton()`, the "Edit" button has not been rendered yet.

Instead, we need to wait until after Vue undergoes the next DOM update cycle. To do that, Vue components have a special method called `$nextTick()`. This method accepts a callback function, which then executes after the DOM updates.

Since the `focusOnEditButton()` method needs to be invoked after the DOM has updated, we can wrap the existing function body inside a `$nextTick()` call.

```js
focusOnEditButton() {
  this.$nextTick(() => {
    const editButtonRef = this.$refs.editButton;
    editButtonRef.focus();
  });
}
```

Now when you activate the "Edit" button and then cancel or save your changes via the keyboard, focus should be returned to the "Edit" button. Success!

Vue lifecycle methods
---------------------

Next, we need to move focus to the edit form's `<input>` element when the "Edit" button is clicked. However, because our edit form is in a different component to our "Edit" button, we can't just set focus inside the "Edit" button's click event handler. Instead, we can use the fact that we remove and re-mount our `ToDoItemEditForm` component whenever the "Edit" button is clicked to handle this.

So how does this work? Well, Vue components undergo a series of events, known as a **lifecycle**. This lifecycle spans from all the way before elements are *created* and added to the VDOM (*mounted*), until they are removed from the VDOM (*destroyed*).

Vue lets you run methods at various stages of this lifecycle using **lifecycle methods**. This can be useful for things like data fetching, where you may need to get your data before your component renders, or after a property changes. The list of lifecycle methods are below, in the order that they fire.

1. `beforeCreate()` — Runs before the instance of your component is created. Data and events are not yet available.
2. `created()` — Runs after your component is initialized but before the component is added to the VDOM. This is often where data fetching occurs.
3. `beforeMount()` — Runs after your template is compiled, but before your component is rendered to the actual DOM.
4. `mounted()` — Runs after your component is mounted to the DOM. Can access `refs` here.
5. `beforeUpdate()` — Runs whenever data in your component changes, but before the changes are rendered to the DOM.
6. `updated()` — Runs whenever data in your component has changed and after the changes are rendered to the DOM.
7. `beforeDestroy()` — Runs before a component is removed from the DOM.
8. `destroyed()` — Runs after a component has been removed from the DOM.
9. `activated()` — Only used in components wrapped in a special `keep-alive` tag. Runs after the component is activated.
10. `deactivated()` — Only used in components wrapped in a special `keep-alive` tag. Runs after the component is deactivated.

**Note:** The Vue Docs provide a nice diagram for visualizing when these hooks happen. This article from the Digital Ocean Community Blog dives into the lifecycle methods more deeply.

Now that we've gone over the lifecycle methods, let's use one to trigger focus when our `ToDoItemEditForm` component is mounted.

In `ToDoItemEditForm.vue`, attach `ref="labelInput"` to the `<input>` element, like so:

```html
<input
 :id="id"
 ref="labelInput"
 type="text"
 autocomplete="off"
 v-model.lazy.trim="newName" />
```

Next, add a `mounted()` property just inside your component object — **note that this should not be put inside the `methods` property, but rather at the same hierarchy level as `props`, `data()`, and `methods`.** Lifecycle methods are special methods that sit on their own, not alongside the user-defined methods. This should take no inputs. Note that you cannot use an arrow function here since we need access to `this` to access our `labelInput` ref.

```js
mounted() {

}
```

Inside your `mounted()` method, assign your `labelInput` ref to a variable, and then call the `focus()` function of the ref. You don't have to use `$nextTick()` here because the component has already been added to the DOM when `mounted()` is called.

```js
mounted() {
   const labelInputRef = this.$refs.labelInput;
   labelInputRef.focus();
}
```

Now when you activate the "Edit" button with your keyboard, focus should immediately be moved to the edit `<input>`.

Handling focus when deleting to-do items
----------------------------------------

There's one more place we need to consider focus management: when a user deletes a to-do. When clicking the "Edit" button, it makes sense to move focus to the edit name text box, and back to the "Edit" button when canceling or saving from the edit screen.

However, unlike with the edit form, we don't have a clear location for focus to move to when an element is deleted. We also need a way to provide assistive technology users with information that confirms that an element was deleted.

We're already tracking the number of elements in our list heading — the `<h2>` in `App.vue` — and it's associated with our list of to-do items. This makes it a reasonable place to move focus to when we delete a node.

First, we need to add a ref to our list heading. We also need to add a `tabindex="-1"` to it — this makes the element programmatically focusable (i.e. it can be focused via JavaScript), when by default it is not.

Inside `App.vue`, update your `<h2>` as follows:

```html
<h2 id="list-summary" ref="listSummary" tabindex="-1">{{listSummary}}</h2>
```

**Note:** `tabindex` is a really powerful tool for handling certain accessibility problems. However, it should be used with caution. Over-using `tabindex="-1"` can cause problems for all sorts of users, so only use it exactly where you need to. You should also almost never use `tabindex` > = `0`, as it can cause problems for users since it can make the DOM flow and the tab-order mismatch, and/or add non-interactive elements to the tab order. This can be confusing to users, especially those using screen readers and other assistive technology.

Now that we have a `ref` and have let browsers know that we can programmatically focus the `<h2>`, we need to set focus on it. At the end of `deleteToDo()`, use the `listSummary` ref to set focus on the `<h2>`. Since the `<h2>` is always rendered in the app, you do not need to worry about using `$nextTick()` or lifecycle methods to handle focusing it.

```js
deleteToDo(toDoId) {
    const itemIndex = this.ToDoItems.findIndex((item) => item.id === toDoId);
    this.ToDoItems.splice(itemIndex, 1);
    this.$refs.listSummary.focus();
}
```

Now, when you delete an item from your list, focus should be moved up to the list heading. This should provide a reasonable focus experience for all of our users.

Summary
-------

So that's it for focus management, and for our app! Congratulations for working your way through all our Vue tutorials. In the next article we'll round things off with some further resources to take your Vue learning further.

**Note:** If you need to check your code against our version, you can find a finished version of the sample Vue app code in our todo-vue repository. For a running live version, see https://mdn.github.io/todo-vue/.

* Previous
* Overview: Client-side JavaScript frameworks
* Next


Styling our Angular app - Learn web development

Styling our Angular app
=======================

* Previous
* Overview: Client-side JavaScript frameworks
* Next

Now that we've got our basic application structure set up and started displaying something useful, let's switch gears and spend an article looking at how Angular handles styling of applications.

|  |  |
| --- | --- |
| Prerequisites: |
 Familiarity with the core HTML,
 CSS, and
 JavaScript languages,
 knowledge of the
 terminal/command line.
  |
| Objective: | To learn how to style an Angular app. |

Adding some style to Angular
----------------------------

The Angular CLI generates two types of style files:

* Component styles: The Angular CLI gives each component its own file for styles.
 The styles in this file apply only to its component.
* `styles.css`: In the `src` directory, the styles in this file apply to your entire application unless you specify styles at the component level.

 Depending on whether you are using a CSS preprocessor, the extension on your CSS files can vary.
 Angular supports plain CSS, SCSS, Sass, Less, and Stylus.

In `src/styles.css`, paste the following styles:

```css
body {
  font-family: Helvetica, Arial, sans-serif;
}

.btn-wrapper {
  /\* flexbox \*/
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
}

.btn {
  color: #000;
  background-color: #fff;
  border: 2px solid #cecece;
  padding: 0.35rem 1rem 0.25rem 1rem;
  font-size: 1rem;
}

.btn:hover {
  background-color: #ecf2fd;
}

.btn:active {
  background-color: #d1e0fe;
}

.btn:focus {
  outline: none;
  border: black solid 2px;
}

.btn-primary {
  color: #fff;
  background-color: #000;
  width: 100%;
  padding: 0.75rem;
  font-size: 1.3rem;
  border: black solid 2px;
  margin: 1rem 0;
}

.btn-primary:hover {
  background-color: #444242;
}

.btn-primary:focus {
  color: #000;
  outline: none;
  border: #000 solid 2px;
  background-color: #d7ecff;
}

.btn-primary:active {
  background-color: #212020;
}
```

 The CSS in `src/styles.css` apply to the entire application, however, these styles don't affect everything on the page.
 The next step is to add styles that apply specifically to the `AppComponent`.

In `app.component.css`, add the following styles:

```css
.main {
  max-width: 500px;
  width: 85%;
  margin: 2rem auto;
  padding: 1rem;
  text-align: center;
  box-shadow:
    0 2px 4px 0 rgb(0 0 0 / 20%),
    0 2.5rem 5rem 0 rgb(0 0 0 / 10%);
}

@media screen and (min-width: 600px) {
  .main {
    width: 70%;
  }
}

label {
  font-size: 1.5rem;
  font-weight: bold;
  display: block;
  padding-bottom: 1rem;
}

.lg-text-input {
  width: 100%;
  padding: 1rem;
  border: 2px solid #000;
  display: block;
  box-sizing: border-box;
  font-size: 1rem;
}

.btn-wrapper {
  margin-bottom: 2rem;
}

.btn-menu {
  flex-basis: 32%;
}

.active {
  color: green;
}

ul {
  padding-inline-start: 0;
}

ul li {
  list-style: none;
}
```

The last step is to revisit your browser and look at how the styling has updated. Things now make a bit more sense.

Summary
-------

Now that our brief tour of styling in Angular is done with, let's return to creating our app functionality. In the next article we will create a proper component for to-do items, and make it so that you can check, edit, and delete to-do items.

* Previous
* Overview: Client-side JavaScript frameworks
* Next


Creating an item component - Learn web development

Creating an item component
==========================

* Previous
* Overview: Client-side JavaScript frameworks
* Next

Components provide a way for you to organize your application. This article walks you through creating a component to handle the individual items in the list, and adding check, edit, and delete functionality. The Angular event model is covered here.

|  |  |
| --- | --- |
| Prerequisites: |
 Familiarity with the core HTML,
 CSS, and
 JavaScript languages,
 knowledge of the
 terminal/command line.
  |
| Objective: |
 To learn more about components, including how events work to handle
 updates. To add check, edit, and delete functionality.
  |

Creating the new component
--------------------------

At the command line, create a component named `item` with the following CLI command:

```bash
ng generate component item
```

 The `ng generate component` command creates a component and folder with the name you specify.
 Here, the folder and component name is `item`.
 You can find the `item` directory within the `app` folder.

Just as with the `AppComponent`, the `ItemComponent` is made up of the following files:

* `item.component.html` for HTML
* `item.component.ts` for logic
* `item.component.css` for styles

You can see a reference to the HTML and CSS files in the `@Component()` decorator metadata in `item.component.ts`.

```js
@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
  styleUrls: ['./item.component.css'],
})
```

Add HTML for the ItemComponent
------------------------------

The `ItemComponent` can take over the task of giving the user a way to check items off as done, edit them, or delete them.

Add markup for managing items by replacing the placeholder content in `item.component.html` with the following:

```html
<div class="item">
  <input
 [id]="item.description"
 type="checkbox"
 (change)="item.done = !item.done"
 [checked]="item.done" />
  <label [for]="item.description">{{item.description}}</label>

  <div class="btn-wrapper" \*ngIf="!editable">
    <button class="btn" (click)="editable = !editable">Edit</button>
    <button class="btn btn-warn" (click)="remove.emit()">Delete</button>
  </div>

  <!-- This section shows only if user clicks Edit button -->
  <div \*ngIf="editable">
    <input
 class="sm-text-input"
 placeholder="edit item"
 [value]="item.description"
 #editedItem
 (keyup.enter)="saveItem(editedItem.value)" />

    <div class="btn-wrapper">
      <button class="btn" (click)="editable = !editable">Cancel</button>
      <button class="btn btn-save" (click)="saveItem(editedItem.value)">
        Save
      </button>
    </div>
  </div>
</div>
```

 The first input is a checkbox so users can check off items when an item is complete.
 The double curly braces, `{{}}`, in the `<label>` for the checkbox signifies Angular's interpolation.
 Angular uses `{{item.description}}` to retrieve the description of the current `item` from the `items` array.
 The next section explains how components share data in detail.

 The next two buttons for editing and deleting the current item are within a `<div>`.
 On this `<div>` is an `*ngIf`, a built-in Angular directive that you can use to dynamically change the structure of the DOM.

This `*ngIf` means that if `editable` is `false`, this `<div>` is in the DOM. If `editable` is `true`, Angular removes this `<div>` from the DOM.

```html
<div class="btn-wrapper" \*ngIf="!editable">
  <button class="btn" (click)="editable = !editable">Edit</button>
  <button class="btn btn-warn" (click)="remove.emit()">Delete</button>
</div>
```

 When a user clicks the **Edit** button, `editable` becomes true, which removes this `<div>` and its children from the DOM.
 If, instead of clicking **Edit**, a user clicks **Delete**, the `ItemComponent` raises an event that notifies the `AppComponent` of the deletion.

 An `*ngIf` is also on the next `<div>`, but is set to an `editable` value of `true`.
 In this case, if `editable` is `true`, Angular puts the `<div>` and its child `<input>` and `<button>` elements in the DOM.

```html
<!-- This section shows only if user clicks Edit button -->
<div \*ngIf="editable">
  <input
 class="sm-text-input"
 placeholder="edit item"
 [value]="item.description"
 #editedItem
 (keyup.enter)="saveItem(editedItem.value)" />

  <div class="btn-wrapper">
    <button class="btn" (click)="editable = !editable">Cancel</button>
    <button class="btn btn-save" (click)="saveItem(editedItem.value)">
      Save
    </button>
  </div>
</div>
```

 With `[value]="item.description"`, the value of the `<input>` is bound to the `description` of the current item.
 This binding makes the item's `description` the value of the `<input>`.
 So if the `description` is `eat`, the `description` is already in the `<input>`.
 This way, when the user edits the item, the value of the `<input>` is already `eat`.

 The template variable, `#editedItem`, on the `<input>` means that Angular stores whatever a user types in this `<input>` in a variable called `editedItem`.
 The `keyup` event calls the `saveItem()` method and passes in the `editedItem` value if the user chooses to press enter instead of click **Save**.

 When a user clicks the **Cancel** button, `editable` toggles to `false`, which removes the input and buttons for editing from the DOM.
 When `editable` is `false`, Angular puts `<div>` with the **Edit** and **Delete** buttons back in the DOM.

 Clicking the **Save** button calls the `saveItem()` method.
 The `saveItem()` method takes the value from the `#editedItem` element and changes the item's `description` to `editedItem.value` string.

Prepare the AppComponent
------------------------

In the next section, you will add code that relies on communication between the `AppComponent` and the `ItemComponent`.

Add the following line near the top of the `app.component.ts` file to import the `Item`:

```ts
import { Item } from "./item";
```

Then, configure the AppComponent by adding the following to the same file's class:

```js
remove(item: Item) {
  this.allItems.splice(this.allItems.indexOf(item), 1);
}
```

 The `remove()` method uses the JavaScript `Array.splice()` method to remove one item at the `indexOf` the relevant item.
 In plain English, this means that the `splice()` method removes the item from the array.
 For more information on the `splice()` method, see the MDN Web Docs article on `Array.prototype.splice()`.

Add logic to ItemComponent
--------------------------

To use the `ItemComponent` UI, you must add logic to the component such as functions, and ways for data to go in and out.

In `item.component.ts`, edit the JavaScript imports as follows:

```js
import { Component, Input, Output, EventEmitter } from "@angular/core";
import { Item } from "../item";
```

 The addition of `Input`, `Output`, and `EventEmitter` allows `ItemComponent` to share data with `AppComponent`.
 By importing `Item`, `ItemComponent` can understand what an `item` is.

Further down `item.component.ts`, replace the generated `ItemComponent` class with the following:

```js
export class ItemComponent {

  editable = false;

  @Input() item!: Item;
  @Output() remove = new EventEmitter<Item>();

  saveItem(description: string) {
    if (!description) return;
    this.editable = false;
    this.item.description = description;
  }
}
```

 The `editable` property helps toggle a section of the template where a user can edit an item.
 `editable` is the same property in the HTML as in the `*ngIf` statement, `*ngIf="editable"`.
 When you use a property in the template, you must also declare it in the class.

`@Input()`, `@Output()`, and `EventEmitter` facilitate communication between your two components.
 An `@Input()` serves as a doorway for data to come into the component, and an `@Output()` acts as a doorway for data to go out of the component.
 An `@Output()` has to be of type `EventEmitter`, so that a component can raise an event when there's data ready to share with another component.

>
> **Note**: The `!` in the class's property declaration is called a definite assignment assertion. This operator tells Typescript that the `item` field is always initialized and not `undefined`, even when TypeScript cannot tell from the constructor's definition. If this operator is not included in your code and you have strict TypeScript compilation settings, the app will fail to compile.
>
>
>

 Use `@Input()` to specify that the value of a property can come from outside of the component.
 Use `@Output()` in conjunction with `EventEmitter` to specify that the value of a property can leave the component so that another component can receive that data.

 The `saveItem()` method takes as an argument a `description` of type `string`.
 The `description` is the text that the user enters into the HTML `<input>` when editing an item in the list.
 This `description` is the same string from the `<input>` with the `#editedItem` template variable.

 If the user doesn't enter a value but clicks **Save**, `saveItem()` returns nothing and does not update the `description`.
 If you didn't have this `if` statement, the user could click **Save** with nothing in the HTML `<input>`, and the `description` would become an empty string.

If a user enters text and clicks save, `saveItem()` sets `editable` to false, which causes the `*ngIf` in the template to remove the edit feature and render the **Edit** and **Delete** buttons again.

Though the application should compile at this point, you need to use the `ItemComponent` in `AppComponent` so you can see the new features in the browser.

Use the ItemComponent in the AppComponent
-----------------------------------------

Including one component within another in the context of a parent-child relationship gives you the flexibility of using components wherever you need them.

The `AppComponent` serves as a shell for the application where you can include other components.

 To use the `ItemComponent` in `AppComponent`, put the `ItemComponent` selector in the `AppComponent` template.
 Angular specifies the selector of a component in the metadata of the `@Component()` decorator.
 In this example, the selector is `app-item`:

```js
@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
  styleUrls: ['./item.component.css']
})
```

 To use the `ItemComponent` selector within the `AppComponent`, you add the element, `<app-item>`, which corresponds to the selector you defined for the component class to `app.component.html`.
 Replace the current unordered list in `app.component.html` with the following updated version:

```html
<h2>
  {{items.length}}
  <span \*ngIf="items.length === 1; else elseBlock">item</span>
  <ng-template #elseBlock>items</ng-template>
</h2>

<ul>
  <li \*ngFor="let i of items">
    <app-item (remove)="remove(i)" [item]="i"></app-item>
  </li>
</ul>
```

The double curly brace syntax, `{{}}`, in the `<h2>` interpolates the length of the `items` array and displays the number.

 The `<span>` in the `<h2>` uses an `*ngIf` and `else` to determine whether the `<h2>` should say "item" or "items".
 If there is only a single item in the list, the `<span>` containing "item" displays.
 Otherwise, if the length of the `items` array is anything other than `1`, the `<ng-template>`, which we've named `elseBlock`, with the syntax `#elseBlock`, shows instead of the `<span>`.
 You can use Angular's `<ng-template>` when you don't want content to render by default.
 In this case, when the length of the `items` array is not `1`, the `*ngIf` shows the `elseBlock` and not the `<span>`.

 The `<li>` uses Angular's repeater directive, `*ngFor`, to iterate over all of the items in the `items` array.
 Angular's `*ngFor` like `*ngIf`, is another directive that helps you change the structure of the DOM while writing less code.
 For each `item`, Angular repeats the `<li>` and everything within it, which includes `<app-item>`.
 This means that for each item in the array, Angular creates another instance of `<app-item>`.
 For any number of items in the array, Angular would create that many `<li>` elements.

You can use an `*ngFor` on other elements, too, such as `<div>`, `<span>`, or `<p>`, to name a few.

 The `AppComponent` has a `remove()` method for removing the item, which is bound to the `remove` property in the `ItemComponent`.
 The `item` property in the square brackets, `[]`, binds the value of `i` between the `AppComponent` and the `ItemComponent`.

 Now you should be able to edit and delete items from the list.
 When you add or delete items, the count of the items should also change.
 To make the list more user-friendly, add some styles to the `ItemComponent`.

Add styles to ItemComponent
---------------------------

 You can use a component's style sheet to add styles specific to that component.
 The following CSS adds basic styles, flexbox for the buttons, and custom checkboxes.

Paste the following styles into `item.component.css`.

```css
.item {
  padding: 0.5rem 0 0.75rem 0;
  text-align: left;
  font-size: 1.2rem;
}

.btn-wrapper {
  margin-top: 1rem;
  margin-bottom: 0.5rem;
}

.btn {
  /\* menu buttons flexbox styles \*/
  flex-basis: 49%;
}

.btn-save {
  background-color: #000;
  color: #fff;
  border-color: #000;
}

.btn-save:hover {
  background-color: #444242;
}

.btn-save:focus {
  background-color: #fff;
  color: #000;
}

.checkbox-wrapper {
  margin: 0.5rem 0;
}

.btn-warn {
  background-color: #b90000;
  color: #fff;
  border-color: #9a0000;
}

.btn-warn:hover {
  background-color: #9a0000;
}

.btn-warn:active {
  background-color: #e30000;
  border-color: #000;
}

.sm-text-input {
  width: 100%;
  padding: 0.5rem;
  border: 2px solid #555;
  display: block;
  box-sizing: border-box;
  font-size: 1rem;
  margin: 1rem 0;
}

/\* Custom checkboxes
Adapted from https://css-tricks.com/the-checkbox-hack/#custom-designed-radio-buttons-and-checkboxes \*/

/\* Base for label styling \*/
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
  position: absolute;
  left: -9999px;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
  position: relative;
  padding-left: 1.95em;
  cursor: pointer;
}

/\* checkbox aspect \*/
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 1.25em;
  height: 1.25em;
  border: 2px solid #ccc;
  background: #fff;
}

/\* checked mark aspect \*/
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
  content: "\2713\0020";
  position: absolute;
  top: 0.15em;
  left: 0.22em;
  font-size: 1.3em;
  line-height: 0.8;
  color: #0d8dee;
  transition: all 0.2s;
  font-family: "Lucida Sans Unicode", "Arial Unicode MS", Arial;
}
/\* checked mark aspect changes \*/
[type="checkbox"]:not(:checked) + label:after {
  opacity: 0;
  transform: scale(0);
}
[type="checkbox"]:checked + label:after {
  opacity: 1;
  transform: scale(1);
}

/\* accessibility \*/
[type="checkbox"]:checked:focus + label:before,
[type="checkbox"]:not(:checked):focus + label:before {
  border: 2px dotted blue;
}
```

Summary
-------

 You should now have a styled Angular to-do list application that can add, edit, and remove items.
 The next step is to add filtering so that you can look at items that meet specific criteria.

* Previous
* Overview: Client-side JavaScript frameworks
* Next


Getting started with Vue - Learn web development

Getting started with Vue
========================

* Previous
* Overview: Client-side JavaScript frameworks
* Next

Now let's introduce Vue, the third of our frameworks. In this article we'll look at a little bit of Vue background, learn how to install it and create a new project, study the high-level structure of the whole project and an individual component, see how to run the project locally, and get it prepared to start building our example.

|  |  |
| --- | --- |
| Prerequisites: |
 Familiarity with the core HTML,
 CSS, and
 JavaScript languages,
 knowledge of the
 terminal/command line.

 Vue components are written as a combination of JavaScript objects that
 manage the app's data and an HTML-based template syntax that maps to
 the underlying DOM structure. For installation, and to use some of the
 more advanced features of Vue (like Single File Components or render
 functions), you'll need a terminal with node + npm installed.
  |
| Objective: |
 To setup a local Vue development environment, create a starter app, and
 understand the basics of how it works.
  |

A clearer Vue
-------------

Vue is a modern JavaScript framework that provides useful facilities for progressive enhancement — unlike many other frameworks, you can use Vue to enhance existing HTML. This lets you use Vue as a drop-in replacement for a library like jQuery.

That being said, you can also use Vue to write entire Single Page Applications (SPAs). This allows you to create markup managed entirely by Vue, which can improve developer experience and performance when dealing with complex applications. It also allows you to take advantage of libraries for client-side routing and state management when you need to. Additionally, Vue takes a "middle ground" approach to tooling like client-side routing and state management. While the Vue core team maintains suggested libraries for these functions, they are not directly bundled into Vue. This allows you to select a different routing/state management library if they better fit your application.

In addition to allowing you to progressively integrate Vue into your applications, Vue also provides a progressive approach to writing markup. Like most frameworks, Vue lets you create reusable blocks of markup via components. Most of the time, Vue components are written using a special HTML template syntax. When you need more control than the HTML syntax allows, you can write JSX or plain JavaScript functions to define your components.

 As you work through this tutorial, you might want to keep the Vue guide and API documentation open in other tabs, so you can refer to them if you want more information on any sub topic.
 For a good (but potentially biased) comparison between Vue and many of the other frameworks, see Vue Docs: Comparison with Other Frameworks.

Installation
------------

To use Vue in an existing site, you can drop one of the following `<script>` elements onto a page. This allows you to start using Vue on existing sites, which is why Vue prides itself on being a progressive framework. This is a great option when migrating an existing project using a library like jQuery to Vue. With this method, you can use a lot of the core features of Vue, such as the attributes, custom components, and data-management.

* Development Script (not optimized, but includes console warnings which is great for development.)

```html
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
```

* Production Script (Optimized version, minimal console warnings. It is recommended that you specify a version number when including Vue on your site so that any framework updates do not break your live site without you knowing.)

```html
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
```

However, this approach has some limitations. To build more complex apps, you'll want to use the Vue npm package. This will let you use advanced features of Vue and take advantage of bundlers like WebPack. To make building apps with Vue easier, there is a CLI to streamline the development process. To use the npm package & the CLI you will need:

1. Node.js 8.11+ installed.
2. npm or yarn.

**Note:** If you don't have the above installed, find out more about installing npm and Node.js here.

To install the CLI, run the following command in your terminal:

```bash
npm install --global @vue/cli
```

Or if you'd prefer to use yarn:

```bash
yarn global add @vue/cli
```

Once installed, to initialize a new project you can then open a terminal in the directory you want to create the project in, and run `vue create <project-name>`. The CLI will then give you a list of project configurations you can use. There are a few preset ones, and you can make your own. These options let you configure things like TypeScript, linting, vue-router, testing, and more.

We'll look at using this below.

Initializing a new project
--------------------------

To explore various features of Vue, we will be building up a sample todo list app. We'll begin by using the Vue CLI to create a new app framework to build our app into.

 In terminal, `cd` to where you'd like to create your sample app, then run `vue create moz-todo-vue`.
 You can choose the default option `Default ([Vue 3] babel, eslint)` by pressing `Enter` to proceed.
 The CLI will now begin scaffolding out your project, and installing all of your dependencies.

 If you've never run the Vue CLI before, you'll get one more question — you'll be asked to choose a package manager which defaults to `yarn`.
 The Vue CLI will default to this package manager from now on. If you need to use a different package manager after this, you can pass in a flag `--packageManager=<package-manager>`, when you run `vue create`. So if you wanted to create the `moz-todo-vue` project with npm and you'd previously chosen yarn, you'd run `vue create moz-todo-vue --packageManager=npm`.

**Note:** We've not gone over all of the options here, but you can find more information on the CLI in the Vue docs.

Project structure
-----------------

If everything went successfully, the CLI should have created a series of files and directories for your project. The most significant ones are as follows:

* `package.json`: This file contains the list of dependencies for your project, as well as some metadata and `eslint` configuration.
* `yarn.lock`: If you chose `yarn` as your package manager, this file will be generated with a list of all the dependencies and sub-dependencies that your project needs.
* `babel.config.js`: This is the config file for Babel, which transforms modern JavaScript features being used in development code into older syntax that is more cross-browser compatible in production code. You can register additional babel plugins in this file.
* `jsconfig.json`: This is a config file for Visual Studio Code and gives context for VS Code on your project structure and assists auto-completion.
* `public`: This directory contains static assets that are published, but not processed by Webpack during build (with one exception; `index.html` gets some processing).
    + `favicon.ico`: This is the favicon for your app. Currently, it's the Vue logo.
    + `index.html`: This is the template for your app. Your Vue app is run from this HTML page, and you can use lodash template syntax to interpolate values into it.

    **Note:** this is not the template for managing the layout of your application — this template is for managing static HTML that sits outside of your Vue app. Editing this file typically only occurs in advanced use cases.
* `src`: This directory contains the core of your Vue app.
    + `main.js`: this is the entry point to your application. Currently, this file initializes your Vue application and signifies which HTML element in the `index.html` file your app should be attached to. This file is often where you register global components or additional Vue libraries.
    + `App.vue`: this is the top-level component in your Vue app. See below for more explanation of Vue components.
    + `components`: this directory is where you keep your components. Currently, it just has one example component.
    + `assets`: this directory is for storing static assets like CSS and images. Because these files are in the source directory, they can be processed by Webpack. This means you can use pre-processors like Sass/SCSS or Stylus.

**Note:** Depending on the options you select when creating a new project, there might be other directories present (for example, if you choose a router, you will also have a `views` directory).

.vue files (single file components)
-----------------------------------

Like in many front-end frameworks, components are a central part of building apps in Vue. These components let you break a large application into discrete building blocks that can be created and managed separately, and transfer data between each other as required. These small blocks can help you reason about and test your code.

While some frameworks encourage you to separate your template, logic, and styling code into separate files, Vue takes the opposite approach. Using Single File Components (SFC), Vue lets you group your templates, corresponding script, and CSS all together in a single file ending in `.vue`. These files are processed by a JS build tool (such as Webpack), which means you can take advantage of build-time tooling in your project. This allows you to use tools like Babel, TypeScript, SCSS and more to create more sophisticated components.

As a bonus, projects created with the Vue CLI are configured to use `.vue` files with Webpack out of the box. In fact, if you look inside the `src` folder in the project we created with the CLI, you'll see your first `.vue` file: `App.vue`.

Let's explore this now.

### App.vue

Open your `App.vue` file — you'll see that it has three parts: `<template>`, `<script>`, and `<style>`, which contain the component's template, scripting, and styling information. All Single File Components share this same basic structure.

`<template>` contains all the markup structure and display logic of your component. Your template can contain any valid HTML, as well as some Vue-specific syntax that we'll cover later.

**Note:** By setting the `lang` attribute on the `<template>` tag, you can use Pug template syntax instead of standard HTML — `<template lang="pug">`. We'll stick to standard HTML through this tutorial, but it is worth knowing that this is possible.

`<script>` contains all of the non-display logic of your component. Most importantly, your `<script>` tag needs to have a default exported JS object. This object is where you locally register components, define component inputs (props), handle local state, define methods, and more. Your build step will process this object and transform it (with your template) into a Vue component with a `render()` function.

In the case of `App.vue`, our default export sets the name of the component to `App` and registers the `HelloWorld` component by adding it into the `components` property. When you register a component in this way, you're registering it locally. Locally registered components can only be used inside the components that register them, so you need to import and register them in every component file that uses them. This can be useful for bundle splitting/tree shaking since not every page in your app necessarily needs every component.

```js
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "App",
  components: {
    //You can register components locally here.
    HelloWorld,
  },
};
```

**Note:** If you want to use TypeScript syntax, you need to set the `lang` attribute on the `<script>` tag to signify to the compiler that you're using TypeScript — `<script lang="ts">`.

`<style>` is where you write your CSS for the component. If you add a `scoped` attribute — `<style scoped>` — Vue will scope the styles to the contents of your SFC. This works similar to CSS-in-JS solutions, but allows you to just write plain CSS.

**Note:** If you select a CSS pre-processor when creating the project via the CLI, you can add a `lang` attribute to the `<style>` tag so that the contents can be processed by Webpack at build time. For example, `<style lang="scss">` will allow you to use SCSS syntax in your styling information.

Running the app locally
-----------------------

The Vue CLI comes with a built-in development server. This allows you to run your app locally so you can test it easily without needing to configure a server yourself. The CLI adds a `serve` command to the project's `package.json` file as an npm script, so you can easily run it.

In your terminal, try running `npm run serve` (or `yarn serve` if you prefer yarn). Your terminal should output something like the following:
```

INFO  Starting development server...
98% after emitting CopyPlugin

  DONE  Compiled successfully in 18121ms

  App running at:
  - Local:   <http://localhost:8080/>
  - Network: <http://192.168.1.9:8080/>

  Note that the development build is not optimized.
  To create a production build, run npm run build.
```

If you navigate to the "local" address in a new browser tab (this should be something like `http://localhost:8080` as stated above, but may vary based on your setup), you should see your app. Right now, it should contain a welcome message, a link to the Vue documentation, links to the plugins you added when you initialized the app with your CLI, and some other useful links to the Vue community and ecosystem.

![default Vue app render, with Vue logo, welcome message, and some documentation links](/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started/vue-default-app.png)

Making a couple of changes
--------------------------

Let's make our first change to the app — we'll delete the Vue logo. Open the `App.vue` file, and delete the `<img>` element from the template section:

```html
<img alt="Vue logo" src="./assets/logo.png" />
```

If your server is still running, you should see the logo removed from the rendered site almost instantly. Let's also remove the `HelloWorld` component from our template.

First of all delete this line:

```html
<HelloWorld msg="Welcome to Your Vue.js App" />
```

If you save your `App.vue` file now, the rendered app will throw an error because we've registered the component but are not using it. We also need to remove the lines from inside the `<script>` element that import and register the component:

Delete these lines now:

```js
import HelloWorld from "./components/HelloWorld.vue";
```

```js
components: {
  HelloWorld;
}
```

 The `<template>` tag is empty now so you'll see an error saying `The template requires child element` in both the console and the rendered app.
 You can fix this by adding some content inside the `<template>` tag and we can start with a new `<h1>` element inside a `<div>`.
 Since we're going to be creating a todo list app below, let's set our heading to "To-Do List" like so:

```html
<template>
  <div id="app">
    <h1>To-Do List</h1>
  </div>
</template>
```

`App.vue` will now show our heading, as you'd expect.

Summary
-------

Let's leave this here for now. We've learnt about some of the ideas behind Vue, created some scaffolding for our example app to live inside, inspected it, and made a few preliminary changes.

With a basic introduction out of the way, we'll now go further and build up our sample app, a basic Todo list application that allows us to store a list of items, check them off when done, and filter the list by all, complete, and incomplete todos.

In the next article we'll build our first custom component, and look at some important concepts such as passing props into it and saving its data state.

* Previous
* Overview: Client-side JavaScript frameworks
* Next


React resources - Learn web development

React resources
===============

* Previous
* Overview: Client-side JavaScript frameworks
* Next

Our final article provides you with a list of React resources that you can use to go further in your learning.

|  |  |
| --- | --- |
| Prerequisites: |
 Familiarity with the core HTML,
 CSS, and
 JavaScript languages,
 knowledge of the
 terminal/command line.
  |
| Objective: | To provide further resources for learning more about React. |

Component-level styles
----------------------

While we kept all the CSS for our tutorial in a single `index.css` file, it's common for React applications to define per-component stylesheets. In an application powered by Vite, this can be done by creating a CSS file and importing it into its corresponding component module.

For example: we could have written a dedicated `Form.css` file to house the CSS related to the `<Form />` component, then imported the styles into `Form.jsx`, like this:

```jsx
import Form from "./Form";
import "./Form.css";
```

This approach makes it easy to identify and manage the CSS that belongs to a specific component and distinguish it from your app-wide styles. However, it also fragments your stylesheet across your codebase, and this fragmentation might not be worthwhile. For larger applications with hundreds of unique views and lots of moving parts, it makes sense to use component-level styles and thereby limit the amount of irrelevant code that's sent to your user at any one time.

You can read more about this and other approaches to styling React components in the Smashing Magazine article, Styling Components In React.

React DevTools
--------------

We used `console.log()` to check on the state and props of our application in this tutorial, and you'll also have seen some of the useful warnings and error message that React gives you both in the CLI and your browser's JavaScript console. But there's more we can do here.

The React DevTools utility allows you to inspect the internals of your React application directly in the browser. It adds a new panel to your browser's developer tools that allows you to inspect the state and props of various components, and even edit state and props to make immediate changes to your application.

This screenshot shows our finished application as it appears in React DevTools:

![Our project being shown in React devtools](/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources/react-devtools.png)

On the left, we see all of the components that make up our application, including unique keys for the items that are rendered from arrays. On the right, we see the props and hooks that our App component uses. Notice, too, that the `Form`, `FilterButton`, and `Todo` components are indented to the right – this indicates that `App` is their parent. This view is great for understanding parent/child relationships at a glance and is invaluable for understanding more complex apps.

React DevTools is available in several forms:

* A Chrome browser extension.
* A Firefox browser extension.
* A Microsoft Edge browser extension.
* A stand-alone application you can install with npm or Yarn.

Try installing one of these, and then using it to inspect the app you've just built!

You can read more about React DevTools in the React docs.

The `useReducer()` hook
-----------------------

In this tutorial, we used the `useState()` hook to manage state across a small collection of event handler functions. This was fine for learning purposes, but it left our state management logic tied to our component's event handlers – especially those of the `<Todo />` component.

The `useReducer()` hook offers developers a way to consolidate different-but-related state management logic into a single function. It's a bit more complex than `useState()`, but it's a good tool to have in your belt. You can read more about `useReducer()` in the React docs.

The Context API
---------------

The application that we built in this tutorial utilized component props to pass data from its `App` component to the child components that needed it. Most of the time, props are an appropriate method for sharing data; for complex, deeply nested applications, however, they're not always best.

React provides the Context API as a way to provide data to components that need it *without* passing props down the component tree. There's also a useContext hook that facilitates this.

If you'd like to try this API for yourself, Smashing Magazine has written an introductory article about React context.

Class components
----------------

Although this tutorial doesn't mention them, it is possible to build React components using JavaScript classes – these are called class components. Until the arrival of hooks, classes were the only way to bring state into components or manage rendering side effects. They're still the only way to handle certain edge-cases, and they're common in legacy React projects. The official React docs maintain a reference for the `Component` base class, but recommend using hooks to manage state and side effects.

Testing
-------

Libraries such as React Testing Library make it possible to write unit tests for React components. There are many ways to *run* these tests. The testing framework Vitest is built on top of Vite, and is a great companion to your Vite-powered React applications. Jest is another popular testing framework that can be used with React.

Routing
-------

While routing is traditionally handled by a server and not an application on the user's computer, it is possible to configure a web application to read and update the browser's location, and render certain user interfaces. This is called *client-side routing*. It's possible to create many unique routes for your application (such as `/home`, `/dashboard`, or `/login`).

React Router is the most popular and most robust client-side routing library for React. It allows developers to define the routes of their application, and associate components with those routes . It also provides a number of useful hooks and components for managing the browser's location and history.

**Note:** Client-side routing can make your application feel fast, but it poses a number of accessibility problems, especially for people who rely on assistive techology. You can read more about this in Marcy Sutton's article, "The Implications of Client-Side Routing".

* Previous
* Overview: Client-side JavaScript frameworks
* Next