I have made a project using Vue.JS 3 and I am migrating my static HTML website to Vue. I am currently using SFC and the Composition API.
Here is my directory tree of src/
src/
--- assets/
------ fonts/
------ img/
------ base.css
------ logo.svg
------ main.css
--- components/
------ MainComponent.vue
------ NavBar.vue
--- App.vue
I tried using pascal case instead of hyphen case like what others have recommended but the components won’t render. When I open chrome dev tools, all I see is the empty app div. I have made sure that I am regestering my components locally. Here is my source code:
App.vue:
<script setup lang="ts">
import NavBar from './components/NavBar.vue'
import MainContent from './components/MainContent.vue'
</script>
<template>
<div id="app">
<NavBar />
<MainContent />
</div>
</template>
<style>
@import './assets/base.css';
body {
color: white;
font-family: 'Segoe Script';
background-color: var(--background-primary);
overflow: scroll;
overflow-x: hidden;
margin: 0px;
padding: 0px;
}
body::-webkit-scrollbar {
width: 0.25rem;
background-color: #1e1e24;
}
body::-webkit-scrollbar-track {
background-color: #1e1e24;
}
body::-webkit-scrollbar-thumb {
background-color: #6649b8;
}
h1 {
font-size: 3rem;
}
/* Large Screens */
@media only screen and (min-width: 600px) {
body {
zoom: 80%;
}
}
</style>
MainContent.vue:
<script setup lang="ts">
import KUTE from "kute.js";
const anim = KUTE.fromTo(
'#blob1',
{
path: '#blob1'
},
{
path: '#blob2'
},
{
repeat: 999,
duration: 3000,
yoyo: true
}
)
anim.start()
</script>
<template>
<main
class="blurred"
@mouseover="($event.currentTarget as HTMLElement).classList.add('not-blurred')"
@mouseleave="($event.currentTarget as HTMLElement).classList.remove('not-blurred')"
>
<section class="blue">
<h1>To Code or Not to Code</h1>
<p>Front-end UI and UX developer. Python Backend Creator.</p>
<div class="curve"></div>
</section>
<section class="dark2" style="z-index: -1">
<h1>WIP</h1>
<p>
Error ea ut pariatur, ex dolore est incidunt distinctio obcaecati ab, inventore labore
quisquam facere a. Nostrum quisquam temporibus optio, quibusdam amet, repellendus iste
doloribus molestiae illum ab voluptatem magnam.
</p>
</section>
<section class="bubble dark2">
<h1>WIP</h1>
<p>
Non, voluptatum illum rem temporibus, repellat explicabo reiciendis est obcaecati cumque,
debitis ducimus. Repudiandae eveniet qui laboriosam consequuntur, ipsum maiores alias
consectetur, iure libero esse quibusdam doloribus? Facere, minus maxime.
</p>
</section>
<section class="dark">
<h1>WIP</h1>
<p>
Dolorum tempora et officiis quod recusandae odio quisquam possimus delectus quae nesciunt
cupiditate iure debitis tempore saepe atque, fugit repellat quasi provident magnam
asperiores qui aliquam hic quidem enim! Doloremque.
</p>
</section>
<section class="red">
<h1>WIP</h1>
<p>
Sunt assumenda similique sit soluta, ea molestias tempora doloribus ab saepe odio reiciendis
illum laudantium consequuntur quis possimus hic necessitatibus, provident incidunt, cum
culpa mollitia alias corporis voluptate. Ullam, saepe.
</p>
</section>
<div class="spacer layer1"></div>
<section class="dark2" style="z-index: -1">
<h1>WIP</h1>
<p>
Ex quia perferendis voluptatum iure repellendus, reiciendis at maxime, fugit, optio totam
nesciunt non maiores odio minima libero. Error modi cupiditate dolorem architecto mollitia
perferendis quas temporibus porro expedita eligendi!
</p>
</section>
<div class="spacer layer2"></div>
<section class="pink">
<h1 style="z-index: 1">WIP</h1>
<p style="z-index: 1">
Est sed ea nemo, itaque laborum nostrum velit accusamus? Aperiam, nesciunt iste! Iusto
distinctio quaerat at repellat assumenda, ipsam sit sed expedita! Impedit quasi tempora
rerum est? Laudantium, perferendis officia!
</p>
</section>
<div class="spacer layer3"></div>
<section class="dark2">
<h1>Contact Me</h1>
<iframe
src="https://canary.discord.com/widget?id=1132442213272518666&theme=dark"
width="350"
height="500"
allowtransparency="true"
frameborder="0"
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
></iframe>
</section>
</main>
</template>
<style scoped>
@import "../assets/base.css";
@import '../assets/main.css';
section {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
min-height: 400px;
padding: 100px 20vw;
}
.blue {
background-color: var(--blue);
}
.red {
background-color: var(--red);
}
.pink {
background-color: var(--pink);
}
.dark {
background-color: var(--background-primary);
}
.dark2 {
background-color: var(--background-secondary);
}
.curve {
position: absolute;
height: 225px;
width: 100%;
bottom: 0px;
z-index: 5;
}
.curve::before {
content: '';
display: block;
position: absolute;
border-radius: 100% 50%;
width: 55%;
height: 100%;
background-color: var(--background-secondary);
transform: translate(85%, 65%);
z-index: 20;
}
.curve::after {
content: '';
display: block;
position: absolute;
border-radius: 100% 50%;
width: 55%;
height: 100%;
background-color: var(--blue);
transform: translate(-1%, 40%);
z-index: 20;
}
.bubble {
z-index: 2;
}
.bubble::after {
content: '';
border-top-left-radius: 50% 100%;
border-top-right-radius: 50% 100%;
position: absolute;
bottom: 0px;
height: 85%;
width: 100%;
background-color: var(--background-primary);
z-index: -2;
}
.svg-wave-opacity-top {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
line-height: 0;
}
.spacer {
aspect-ratio: 900/450;
width: 100%;
background-size: no-repeat;
background-position: center;
background-size: cover;
}
.layer1 {
background-image: url('../assets/img/layer1.svg');
}
.layer2 {
background-image: url('../assets/img/layer2.svg');
}
.layer3 {
background-image: url('../assets/img/layer3.svg');
}
.flip {
transform: rotate(90deg) scaleX(-1);
}
.blob-motion {
position: absolute;
transform: translateY(-20%);
z-index: 0;
}
.blurred {
filter: blur(50px);
transition: all 3s;
}
@media (prefers-reduced-motion) {
.hidden {
transition: none;
}
}
.not-blurred {
filter: blur(0);
}
</style>
NavBar.vue:
<script setup lang="ts"></script>
<template>
<nav class="navbar">
<ul class="navbar-nav">
<li class="logo">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">To Code or Not to Code</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">HTML</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">CSS</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">JS</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">JSON</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">XML</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">Python</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">YouTube</span>
</a>
</li>
<li class="nav-item">
<a href="example.com" class="nav-link">
<span class="link-text fa-primary">Discord</span>
</a>
</li>
</ul>
</nav>
</template>
<style scoped>
@import '../assets/base.css';
@import '../assets/main.css';
@keyframes spin {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(90deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(-90deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes spin-reverse {
0% {
transform: rotate(360deg);
}
25% {
transform: rotate(-90deg);
}
50% {
transform: rotate(-180deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(0deg);
}
}
@-webkit-keyframes spin {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(90deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(-90deg);
}
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes spin-reverse {
0% {
transform: rotate(360deg);
}
25% {
transform: rotate(-90deg);
}
50% {
transform: rotate(-180deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(0deg);
}
}
@-moz-keyframes spin {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(90deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(-90deg);
}
100% {
transform: rotate(360deg);
}
}
@-moz-keyframes spin-reverse {
0% {
transform: rotate(360deg);
}
25% {
transform: rotate(-90deg);
}
50% {
transform: rotate(-180deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(0deg);
}
}
@-o-keyframes spin {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(90deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(-90deg);
}
100% {
transform: rotate(360deg);
}
}
@-o-keyframes spin-reverse {
0% {
transform: rotate(360deg);
}
25% {
transform: rotate(-90deg);
}
50% {
transform: rotate(-180deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(0deg);
}
}
.navbar {
position: fixed;
background-color: var(--background-secondary);
transition: width 500ms ease;
z-index: 10;
}
.navbar-nav {
list-style-type: none;
padding: 0px;
margin: 0px;
display: flex;
flex-direction: column;
align-content: center;
height: 100%;
}
.nav-item {
width: 100%;
}
.nav-item:nth-last-child(2) {
margin-top: auto;
}
.nav-link {
display: flex;
align-items: center;
height: 5rem;
color: var(--text-primary);
text-decoration: none;
filter: grayscale(100%) opacity(0.7);
transition: var(--transition-speed);
}
.link-text {
display: none;
margin-left: 1rem;
}
.nav-link svg {
min-width: 2rem;
margin: 0 1.5rem;
filter: grayscale(100%);
}
.fa-primary {
color: #df49a6;
fill: #df49a6;
transition: var(--transition-speed);
}
.logo {
font-weight: bold;
text-transform: uppercase;
margin-bottom: 1rem;
text-align: center;
color: var(--text-primary);
background-color: var(--background-primary);
letter-spacing: 0.3ch;
width: 100%;
}
@media only screen and (max-width: 600px) {
.navbar {
bottom: 0px;
width: 100vw;
height: 5rem;
}
.logo {
display: none;
}
.navbar-nav {
flex-direction: row;
}
.nav-link {
justify-content: center;
}
html body .hidden {
transition: none;
}
main {
margin: 0px;
padding: 0px;
}
}
@media only screen and (min-width: 600px) {
body {
zoom: 80%;
}
.navbar {
top: 0px;
width: 5rem;
height: 100%;
}
.navbar:hover {
width: 16rem;
}
.nav-link:hover {
filter: grayscale(0%) opacity(1);
background-color: var(--background-primary);
color: var(--text-primary);
}
.logo svg {
animation: spin-reverse 1s ease-in-out;
-webkit-animation: spin-reverse 1s ease-in-out;
-moz-animation: spin-reverse 1s ease-in-out;
-o-animation: spin-reverse 1s ease-in-out;
}
.navbar:hover .logo svg {
animation: spin 1s ease-in-out;
-webkit-animation: spin 1s ease-in-out;
-moz-animation: spin 1s ease-in-out;
-o-animation: spin 1s ease-in-out;
}
.navbar:hover .link-text {
display: inline;
}
}
</style>
Expected Result (Old static website):
Working static HTML website
Actual Result (Vue Project):
Actual non-working Vue project
Dev tools of vue project:
Dev tools screenshot of non-working vue project
And console of vue project:
Console of non-working vue project