Interested in web development? Level up your skills with thedevspace.io!
🏷️ #javascript #html #css #vuejs #frontend #webdev

Create a portfolio Website

This article is outdated. If you are interested in learning HTML and CSS, check out my new course ➡️ HTML & CSS: A Practical Guide.

In this article, we are going to use what we’ve learned about HTML, CSS, JavaScript, and Vue.js so far, to create a portfolio website, which you can use to tell the world about you and your projects. Without further ado, let’s get started.

Creating an HTML file #

First of all, let’s create a working directory, and you can call it portfolio. Everything related to the portfolio project should be stored inside the portfolio directory. You can do this differently, but remember to be organized because we are going to add quite a few things later.

Next, go to portfolio and create an HTML file, portfolio.html. Open it with a text editor, you can use the notepad that comes with your operating system if you want, but I recommend using a proper code editor such as Visual Studio Code .

Like we talked about before, an HTML file has the following structure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!doctype html>
<html>
  <head>
    . . .
  </head>

  <body>
    . . .
  </body>
</html>

To open this HTML file, you can simply double-click on the file and open it with a browser. Now, let’s start with the <head> section:

1
2
3
4
5
6
7
<head>
  <meta charset="utf-8" />
  <meta name="description" content="My Portfolio" />
  <meta name="keywords" content="HTML, CSS, JavaScript" />
  <meta name="author" content="Eric Hu" />
  <title>My Portfolio</title>
</head>

This part is pretty straightforward. We first defined the character set that this file is going to use, this information is used by the browser to make sure the characters and symbols are displayed correctly. Next, we defined the description, the keywords, and the author of this web page. This information is not displayed, but they are important for SEO (Search Engine Optimization) purposes. And finally, the title of this web page is declared as well.

Header and navigation bar

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!--Header and Navigation Bar-->
<header>
  <h1>Eric's Portfolio</h1>
</header>
<nav>
  <ul>
    <li><a href="/">Root</a></li>
    <li><a href="portfolio.html">Home1</a></li>
    <li><a href="/portfolio.html">Home2</a></li>
    <li><a href="https://www.ericsdevblog.com">Blog</a></li>
    <li><a href="#project">Projects</a></li>
  </ul>
</nav>

We can see that from line 7 to 11, we defined five different types of links. The first three are relative URLs, the fourth one is an absolute URL that you should already be familiar with, and the last one is an anchor link, which we’ll talk about later.

For the first link, Root (/), it will take you to the root of the server, if you are not using a web server, this link will take you to the root of the disk where this HTML file is stored.

For the second link Home1 (portfolio.html), the browser will look for a file named portfolio.html in the current directory. This will lead to problems because as your website gets bigger, it is possible that you don’t know which directory you are currently in.

As for the third link Home2 (/portfolio.html), it is basically the combination of the first two. The browser will always go back to the root directory and then look for the portfolio.html file. This eliminates the possibility of any unexpected errors.

Self introduction section

1
2
3
4
5
<!--Self Introduction Section-->
<section>
  <h2>Hello, I am Eric. Welcome to My Portfolio.</h2>
  <p>. . .</p>
</section>

Newsletter sign up section

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!--Newsletter Sign Up Section-->
<section>
  <h2>Would you like to see more tips and tutorials on web development?</h2>
  <form>
    <label for="firstname">First Name:</label>
    <input type="text" id="firstname" />
    <br /><br />
    <label for="lastname">Last Name:</label>
    <input type="text" id="lastname" />
    <br /><br />
    <label for="email">Enter your email:</label>
    <input type="email" id="email" name="email" />
  </form>
</section>

Skills section

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!--Skills Section-->
<section>
  <h2>My Skills</h2>
  <ul>
    <li>HTML (100%)</li>
    <li>CSS (90%)</li>
    <li>JavaScript (90%)</li>
    <li>Python (90%)</li>
    <li>PHP (100&#37;)</li>
    <li>Java (90&#37;)</li>
    <li>Vue.js (80&percnt;)</li>
    <li>Django (90&percnt;)</li>
    <li>Laravel (90&percnt;)</li>
  </ul>
</section>

Notice that I used three different methods to represent the percentage sign (%), and they should all give you the same result.

Projects section

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!--Projects Section-->
<section id="project">
  <h2>My Projects</h2>
  <div>
    <h3>First Project</h3>
    <img src="/images/first project.jpg" width="500" height="300" />
    <p>. . .</p>
  </div>

  <div>
    <h3>Second Project</h3>
    <img src="/images/second project.jpeg" width="500" height="300" />
    <p>. . .</p>
  </div>

  <div>
    <h3>Third Project</h3>
    <img src="/images/third project.jpeg" width="500" height="300" />
    <p>. . .</p>
  </div>
</section>

Notice that I give this <section> element an id attribute named project. This is to work with the anchor link that we mentioned before.

1
<a href="#project">Projects</a>

This link will send you to the element whose ID is project. Also note that you should always use the ID to specify which element you wish to anchor so that it is unique in the entire web page.

As for the images in this section, they are all stored in a folder called images under the folder portfolio.

images folder

Footer section

1
2
3
4
5
<!--Footer-->
<footer>
  <p>Created by Eric Hu</p>
  <p><a href="mailto:huericnan@gmail.com">huericnan@gmail.com</a></p>
</footer>

portfolio HTML only

This is what the final result looks like. However, we have a new problem, yes, it looks terrible, and it’s not going to land you any job looking like this. But don’t worry, in the next part of this tutorial, we’ll find a way to make this web page more appealing using CSS.

Adding CSS to our HTML document #

Now it is time for us to make our portfolio website look better with CSS. Please understand that I’m not a professional designer, so forgive me if my design is terrible. But I will try to explain the basic concepts as clear as possible.

Let’s first create a style.css file, and then import it into our HTML document.

Style CSS

Creating a responsive layout #

Let’s first start by designing a responsive layout for our portfolio. Remember that a responsive layout should have two key components, a container and a grid system.

First, we should have a fluid container that changes width as you resize your browser window. We usually set a maximum width on large screens so that the container does not stretch to the edge. However, on smaller screens, we usually set its width to 100% to utilize as much space as possible.

This is what we can do:

1
2
3
<body>
  <div class="container">. . .</div>
</body>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
/* Small Screen */
.container {
  max-width: 100%;
  display: flex;
  flex-wrap: wrap;
}

/* Large Screen */
@media only screen and (min-width: 1200px) {
  .container {
    max-width: 1140px;
    margin: auto;
    display: flex;
    flex-wrap: wrap;
  }
}

To keep things simple, here we only have one breakpoint. If the screen width is less than 1200px, the container stretches to its edge. If the screen is larger than 1200px, the maximum width of the container will be set to 1140px. Notice that in the second scenario, we defined margin: auto;, this is to make sure that the container is always entered.

Screen SizeResult
Small ScreenContainer on Small Screen
Medium ScreenContainer on Medium Screen
Large ScreenContainer on Large Screen

Second, we need to have different grid systems for the small screen (mobile phone), medium screen (tablet), and large screen (desktop). Each grid system contains 12 columns, and different elements could take up different columns on different screens. This could be realized by either the regular grid system or the flexbox. In this tutorial, we are going to use the flexbox.

1
2
3
4
5
6
7
8
9
<body>
  <div class="container">
    <div class="col-6 col-s-8">Div1</div>
    <div class="col-6 col-s-4">Div2</div>

    <div class="col-2 col-s-10">Div3</div>
    <div class="col-4 col-s-2">Div4</div>
  </div>
</body>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* For mobile phones: */
[class*="col-"] {
  width: 100%;
}

/* For tablets: */
@media only screen and (min-width: 600px) {
  .col-s-1 {
    width: 8.33%;
  }
  .col-s-2 {
    width: 16.66%;
  }
  .col-s-3 {
    width: 25%;
  }
  .col-s-4 {
    width: 33.33%;
  }
  .col-s-5 {
    width: 41.66%;
  }
  .col-s-6 {
    width: 50%;
  }
  .col-s-7 {
    width: 58.33%;
  }
  .col-s-8 {
    width: 66.66%;
  }
  .col-s-9 {
    width: 75%;
  }
  .col-s-10 {
    width: 83.33%;
  }
  .col-s-11 {
    width: 91.66%;
  }
  .col-s-12 {
    width: 100%;
  }
}

/* For desktop: */
@media only screen and (min-width: 768px) {
  .col-1 {
    width: 8.33%;
  }
  .col-2 {
    width: 16.66%;
  }
  .col-3 {
    width: 25%;
  }
  .col-4 {
    width: 33.33%;
  }
  .col-5 {
    width: 41.66%;
  }
  .col-6 {
    width: 50%;
  }
  .col-7 {
    width: 58.33%;
  }
  .col-8 {
    width: 66.66%;
  }
  .col-9 {
    width: 75%;
  }
  .col-10 {
    width: 83.33%;
  }
  .col-11 {
    width: 91.66%;
  }
  .col-12 {
    width: 100%;
  }
}

This is the exact same code we talked about before in this article: CSS Basics #2. Let’s see how it works.

Screen SizeResult
Small ScreenFlexbox Small Screen
Medium ScreenFlexbox on Medium Screen
Large ScreenFlexbox on Large Screen

Now that we are done with designing the general responsive layout, it is time for us to go into the details. As a guide, the portfolio page we design should look like this:

Small Screen Design

Medium Screen Design

Large Screen Design

The images are too big to be displayed here, but you can download them yourself.

Next, before we start designing the webpage, let’s first choose the color scheme and the font we are going to use. This might be difficult if you are not a professional designer, but don’t worry, there are several tools that can help us.

To find a nice-looking color scheme, we can use this website: Coolors , which offers hundreds of different color palettes with color codes. As for the fonts, the common practice is to use Google Fonts . We can select any font and use it in our CSS file.

Google Fonts

Here are the fonts I selected:

1
@import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&family=Poppins:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,200;1,300;1,400;1,500;1,600;1,700&display=swap");

This line of code imports all the necessary fonts we are going to use. Remember you should put it at the top of the CSS file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
h1 {
  font-family: "Comfortaa", cursive;
}

h2,
h3,
h4 {
  font-family: "Crimson Text", serif;
}

p,
a {
  font-family: "Poppins", sans-serif;
}

Styling each section #

Navigation bar

When designing web pages, we should always follow the rule of “mobile-first”. It means we should always start by designing the small screen layout.

We’ll start with the navigation bar. First, we wrap <header> and <nav> blocks inside a <div> block. The <div> block takes 12 columns on all devices.

1
2
3
4
<div class="col-12 col-s-12 header-and-nav">
  <header>. . .</header>
  <nav>. . .</nav>
</div>

Next, on small devices, we want <header> to stay on top of <nav>, and on larger screens, we want to put <header> on the left side and <nav> on the right side.

To achieve this, we need to make sure that the <div> element is also a flexbox container. So, this is what we can do:

1
2
3
4
.header-and-nav {
  display: flex;
  flex-wrap: wrap;
}
1
2
3
4
5
<div class="col-12 col-s-12 header-and-nav">
  <header class="col-4 col-s-4">. . .</header>

  <nav class="col-8 col-s-8">. . .</nav>
</div>

navbar

This is the navbar we have. Next, since we only care about small devices right now, we need to center the header and the nav list. This is what we can do:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!--Header and Navigation Bar-->
<div class="col-12 col-s-12 header-and-nav">
  <header class="col-4 col-s-4 header">
    <h1>Eric's Portfolio</h1>
  </header>
  <nav class="col-8 col-s-8">
    <ul class="nav-list">
      <li class="nav-item">
        <a href="/portfolio.html">Home</a>
      </li>
      . . .
    </ul>
  </nav>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
.header {
  text-align: center;
}

.nav-list {
  text-align: center;
}

.nav-item {
  display: inline-block;
}

.nav-item a {
  display: inline-block;
}

navbar

Finally, let’s add some colors, paddings, margins, text decorations, and so on.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.header {
  color: white;
  text-align: center;
}

.nav-list {
  list-style-type: none;
  margin: 0px;
  padding: 0px;

  text-align: center;
}

.nav-item {
  display: inline-block;
}

.nav-item a {
  display: inline-block;
  color: white;
  text-decoration: none;
  padding: 27px 20px;
}

.nav-item a:hover {
  background-color: #457b9d;
  text-decoration: underline;
}

navbar

Finally, we need to change how the navbar looks on desktops, and apparently, we don’t want everything to be centred. Instead, we want the links to align to the right side.

1
2
3
4
5
6
7
8
9
@media only screen and (min-width: 768px) {
  .nav-list {
    list-style-type: none;
    margin: 0px;
    padding: 0px;

    text-align: right;
  }
}

navbar

Self introduction section

Self Intro

1
2
3
4
5
6
7
8
<!--Self Introduction Section-->
<section class="col-12 col-s-12 self-intro">
  <img src="./images/profile-image.jpg" class="col-4 col-s-4 profile-image" />
  <div class="col-8 col-s-8 self-intro-text">
    <h2>Hello, I am XXXX. Welcome to My Portfolio.</h2>
    <p>. . .</p>
  </div>
</section>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
/* Self Introduction Section */
.self-intro {
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
}

.profile-image {
  object-fit: cover;
}

.self-intro-text h2 {
  text-decoration: underline;
}

@media only screen and (min-width: 768px) {
  .self-intro-text {
    padding: 0px 10px;
  }
}

Newsletter section

newsletter on small screen

On small screen

Newsletter on large screen

On large screen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!--Newsletter Sign up Section-->

<section class="col-12 col-s-12 newsletter-signup">
  <h2 class="col-6 col-s-6">
    Would you like to see more tips and tutorials on web development?
  </h2>
  <form class="col-6 col-s-6 newsletter-signup-form">
    <label for="firstname">First Name:</label><br />
    <input type="text" id="firstname" />
    <br />
    <label for="lastname">Last Name:</label><br />
    <input type="text" id="lastname" />
    <br />
    <label for="email">Enter your email:</label><br />
    <input type="email" id="email" name="email" />
    <button type="submit">Submit</button>
  </form>
</section>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* Newsletter Signup Section */
.newsletter-signup {
  background-color: #a8dadc;
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
}

.newsletter-signup h2 {
  text-align: center;
}

.newsletter-signup-form {
  margin: 0 auto;
}

.newsletter-signup-form label {
  font-family: "Poppins", sans-serif;
}

.newsletter-signup-form input {
  width: 100%;
  padding: 12px 20px;
  margin: 8px 0;
  box-sizing: border-box;
}

.newsletter-signup-form button {
  background-color: #a8dadc;
  border: solid 3px #e63946;
  color: #e63946;
  width: 100%;
  padding: 10px 0;
  margin: 10px 0;
  cursor: pointer;
  font-family: "Poppins", sans-serif;
  font-size: 1em;
  font-weight: 600;
}

.newsletter-signup-form button:hover {
  background-color: #e63946;
  border: solid 3px #e63946;
  color: white;
}

@media only screen and (min-width: 768px) {
  .newsletter-signup {
    background-color: #a8dadc;
    padding: 10px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }
  .newsletter-signup h2 {
    text-align: center;
    padding: 10px;
  }
}

Skills section

Skills

1
2
3
4
5
6
7
8
<!--Skills Section-->
<section class="col-12 col-s-12 skills-section">
  <h2 class="col-12 col-s-12">My Skills</h2>
  <ul class="col-8 col-s-8 skills-list">
    <li>HTML (100%)</li>
    . . .
  </ul>
</section>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* Skills Section */
.skills-section {
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
}

.skills-section h2 {
  text-decoration: underline;
}

.skills-list {
  column-count: 2;
}

@media only screen and (min-width: 768px) {
  .skills-list {
    column-count: 2;
    margin: 0 auto;
  }
}

One small trick worth mentioning here is that we used column-count: 2; to split the list into two columns.

Projects section

Projects Small Screen

On small screen

Projects on Large Screen

On large screen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!--Projects Section-->

<section class="col-12 col-s-12 porject-section" id="project">
  <h2 class="col-12 col-s-12">My Projects</h2>
  <div class="col-4 col-s-4">
    <div class="project-card">
      <h3>First Project</h3>
      <img src="/frontend/images/p1.jpg" />
      <p>. . .</p>
    </div>
  </div>
  . . .
</section>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Project Section */
.porject-section {
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
  background-color: #a8dadc;
}

.porject-section h2 {
  text-decoration: underline;
}

.project-card {
  border: solid 2px gray;
  border-radius: 5px;
  padding: 5px;
  margin: 5px;
}

.project-card img {
  max-width: 100%;
  object-fit: cover;
}

Footer

Footer

1
2
3
4
5
6
<!--Footer-->

<footer class="col-12 col-s-12 footer">
  <p>Created by Eric Hu</p>
  <p><a href="mailto:huericnan@gmail.com">huericnan@gmail.com</a></p>
</footer>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/* Footer */
.footer {
  background-color: #1d3557;
  color: white;
  text-align: center;
}

.footer a {
  color: white;
}

Creating a reactive application using Vue.js #

Lastly, in this section, we are going to upgrade our portfolio website using Vue.js. Let’s start by creating a new working folder and set up a new Vue.js project by running the following commands:

1
2
3
4
npm init vue@latest
cd <your-project-name>
npm install
npm run dev

Project structure #

For this project, I’ve decided to use the following structure:

portfolio vue components structure

App.vue is the root component, which has five child components. One of those child components, ProjectListComponent.vue, has another child, ProjectComponent.vue, forming a very simple nested structure.

Of course, you can use whatever structure you want. For example, you could have a MainComponent that contains self-introduction, skills, newsletter and project list as child components, which makes a slightly more complicated structure. Or, if you don’t want so many components, you can combine the self-intro, skills and newsletter section as one single component. Vue.js gives you the freedom to structure your project however you want, as long as it makes sense to you.

First, we need to edit the index.html file, which is the entry point of our project. We need to edit some meta information.

index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="description" content="My Portfolio" />
    <meta name="keywords" content="HTML, CSS, JavaScript" />
    <meta name="author" content="Eric Hu" />

    <title>My Portfolio</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

Recall that <div id="app"></div> is where we mount the root component (App.vue).

Creating the root and header components #

Now we can create our first component, HeaderComponent.vue, and copy and paste the corresponding HTML code into the <template> section.

src/components/HeaderComponent.vue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
export default {
  props: ["websiteName"],
};
</script>

<template>
  <!--Header and Navigation Bar-->
  <div class="col-12 col-s-12 header-and-nav">
    <header class="col-4 col-s-4 header">
      <h1>{{ websiteName }}</h1>
    </header>
    <nav class="col-8 col-s-8">
      <ul class="nav-list">
        <li><a href="/">Root</a></li>
        <li><a href="portfolio.html">Home1</a></li>
        <li><a href="/portfolio.html">Home2</a></li>
        <li><a href="https://www.ericsdevblog.com">Blog</a></li>
        <li><a href="#project">Projects</a></li>
      </ul>
    </nav>
  </div>
</template>

Next, we import the component we just created and put it into our root component (App.vue).

src/App.vue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
import HeaderComponent from "@/components/HeaderComponent.vue";

export default {
  data() {
    return {
      websiteName: "My Portfolio",
    };
  },
  components: {
    HeaderComponent,
  },
};
</script>

<template>
  <div class="container">
    <HeaderComponent></HeaderComponent>
  </div>
</template>

<style>
@import "./assets/style.css";
</style>

Remember that we need to import the CSS code inside the root component, so that it applies to all other components as well. In this tutorial, I put the CSS file under the directory /src/assets/. Go to the browser, and you should see the navbar appearing.

Everything seems to be working, but now we have a new problem, since everything is hardcoded, if you want to change something, you have to change the code itself. Our goal here, however, is to make the webpage dynamic and reactive, meaning if you wish to change something, all you need to do is to change the corresponding data stored in the database.

To achieve this, we need to bind some information with variables. In the case of our navbar, we can bind the website name as well as the navigation links.

HeaderComponent.vue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<script>
export default {
  data() {
    return {
      websiteName: "My Portfolio"
      navLinks: [
        { id: 1, name: "Home", link: "#" },
        { id: 2, name: "Features", link: "#" },
        { id: 3, name: "Pricing", link: "#" },
        { id: 4, name: "FAQs", link: "#" },
        { id: 5, name: "About", link: "#" },
      ],
    };
  },
};
</script>

<template>
  <!--Header and Navigation Bar-->
  <div class="col-12 col-s-12 header-and-nav">
    <header class="col-4 col-s-4 header">
      <h1>{{ websiteName }}</h1>
    </header>
    <nav class="col-8 col-s-8">
      <ul class="nav-list">
        <li
          class="nav-item"
          v-for="navLink in navLinks"
          v-bind:key="navLink.id"
        >
          <a href="/portfolio.html" v-bind:href="navLink.link">{{
            navLink.name
          }}</a>
        </li>
      </ul>
    </nav>
  </div>
</template>

As you can see, here we put both the websiteName and the navLinks in the HeaderComponent, but is that the best solution? We already know that the websiteName will appear again in the FooterComponent, and since different components are rendered separately, that means the websiteName has to be retrieved from the database twice, which would be a waste of valuable resources.

An alternate solution would be putting the websiteName inside the root component (App.vue), and from there, we can pass the data down to the child components that need to use it.

App.vue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<script>
import HeaderComponent from "@/components/HeaderComponent.vue";

export default {
  data() {
    return {
      websiteName: "My Portfolio",
    };
  },
  components: {
    HeaderComponent,
  },
};
</script>

<template>
  <div class="container">
    <HeaderComponent v-bind:websiteName="websiteName"></HeaderComponent>
  </div>
</template>

HeaderComponent.vue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
export default {
  data() {
    return {
      navLinks: [
        . . .
      ],
    };
  },

  props: ["websiteName"],
};
</script>

<template>
  <!--Header and Navigation Bar-->
  <div class="col-12 col-s-12 header-and-nav">
    <header class="col-4 col-s-4 header">
      <h1>{{ websiteName }}</h1>
    </header>
    . . .
  </div>
</template>

To save us some time, I’m not going to include the other components in this article, but you can still download the source code here . However, I do recommend you to try it yourself before looking at the source code.

portfolio-vue


If you think my articles are helpful, please consider making a donation to me. Your support is greatly appreciated.

Subscribe to my newsletter ➡️

✅ News and tutorials every other Monday

✅ Unsubscribe anytime

✅ No spam. Always free.