Vue RouterLink not working inside a component - vue.js

I have a very simple vue 3 project. In created a Layout component that has the navigation links which looks like this
<script setup>
import { useRouter } from "vue-router";
</script>
<template>
<div>
<div class="hidden md:flex md:w-64 md:flex-col md:fixed md:inset-y-0">
<div
class="flex-1 flex flex-col min-h-0 border-r border-gray-200 bg-white"
>
<div class="flex-1 flex flex-col pt-5 pb-4 overflow-y-auto">
<div class="flex items-center flex-shrink-0 px-4">
<h1 class="text-3xl font-extrabold text-gray-900">MiniSend</h1>
</div>
<nav class="mt-5 flex-1 px-4 bg-white space-y-2">
<ul>
<li class="mb-4">
<RouterLink to="/dashboard" class="text-gray-700">
Dashboard</RouterLink
>
</li>
<li class="mb-4">
<RouterLink to="/settings" class="text-gray-700">
Settings</RouterLink
>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md:pl-64 flex flex-col flex-1">
<main class="flex-1">
<div class="py-6">
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<h1 class="text-2xl font-semibold text-gray-900">
<slot name="pageTitle"></slot>
</h1>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<div class="py-4">
<slot></slot>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
In my Dashboard view I imported the Layout component as seen below
<script setup>
import Layout from "../components/Layout.vue";
</script>
<template>
<Layout>
// ...content
</Layout>
</template>
When the Dashboard view is served, I can see the links but I cannot click the links. I copied the same link code into the Dashboard view file and I was able to click and get routed to the right page.
Why are the links not working inside the component but work inside the view?

Related

Render image data from directus

[UPDATE: SOLVED]
I am new to directus, I have problem in rendering image data from directus cloud api to my vue project.
How can I render UUID directus image? This is the json image
json image
and this is my vue app code
<script setup>
import Button from './Button.vue'
const { story } = defineProps(['story'])
//console.log(story.img)
</script>
<template>
<div class="card-wrapper shadow-lg shadow-slate-400 m-2 p-2 w-40 md:w-60 rounded-md flex flex-col justify-between">
<div class="content text-white">
<h2 class="text-2xl font-bold">{{ story.title }}</h2>
<!-- <h4 class="headline1 text-md font-semibold">{{ story.headline }}</h4> -->
<p>{{ story.article_body }}</p>
</div>
<div class="cat-ava flex justify-center items-center">
<img :src="`//https://my.directus-api.app/assets/${story.img}`" :alt="`${story.title} image`">
</div>
<div class="btn-wrapper flex justify-center">
<Button name="Read More..." />
</div>
</div>
</template>
this is the result:
result
the title and article body is working but not for the image.
this is what I expected:
expected result
UPDATE
this is how I solved:
the code from vue before:
<img :src="`//https://my.directus-api.app/assets/${story.img}`" :alt="`${story.title} image`">
this is after I fixed it:
<img :src="`https://my.directus-api.app/assets/${story.img}?some_random_token`" :alt="`${story.title} image`">

flex flex-row not working in array values mapped in VUE

I have created an array of items and mapped them in Vue but I can't make them to flex-row using Tailwind CSS maybe there is something I don't know about in tailwind css flex-row feature
<div class="bg-white mt-5 rounded-tr-md rounded-tl-md">
<!-- Filter menus -->
<div
v-for="filter in filterTypes"
:key="filter.type"
class="flex flex-row items-center px-5 py-4"
>
<div class="">{{ filter.type }}</div>
</div>
<!-- Transactions According to Pages-->
<div></div>
</div>
You should place flex to the parent element, and there's no need to flex-row since flex direction is row by default :
<div class=" bg-white mt-5 rounded-tr-md rounded-tl-md">
<!-- Filter menus -->
<div class="flex items-center">
<div
v-for="filter in filterTypes"
:key="filter.type"
class=" px-5 py-4"
>
<div class="">{{ filter.type }}</div>
</div>
</div>
<!-- Transactions According to Pages-->
<div></div>
</div>

Header component is not registered first time properly

I want to showing profile on click for logged in user, when i click to that, my profile page is rendered, but header content is not loaded properly, i checked in console, it shown me an error, did you register component properly. but if i refresh or reload page, header content is showing and console error also cleared that showing did you register component properly.
please help me where i mistaken.
header.vue
<template>
<div>
<div class="top-header">
<div class="container">
<div class="row">
<div class="col-md-6">
<p>Free shipping on all orders over $100</p>
</div>
<div class="col-md-6">
<div class="links" v-if="!this.$page.auth.user">
<inertia-link :href="route('login.page')"> Log in </inertia-link>
<InertiaLink :href="route('RegistrationForm')">Register</InertiaLink>
</div>
<div class="id-link" v-else>
<div class="profile-content" #click="OpenProfile"> <b-link href="#"> Welcome {{this.$page.auth.user.name}} </b-link> </div>
<div class="profile" v-if="expanded">
<b-img src="/images/profile.jpg" alt="image"></b-img>
<ul>
<li> <b-button variant="primary"> <inertia-link :href="route('User-Profile')" method="get"> Profile </inertia-link> </b-button> </li>
<li> <b-button variant="primary"> <inertia-link :href="route('logout')" method="post"> Logout </inertia-link> </b-button> </li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<header>
<div class="container">
<div class="row">
<div class="col-md-3">
<div class="logo">
<img src="images/logo.png">
</div>
</div>
<div class="col-md-9">
<div class="navbar">
<ul>
<li> <InertiaLink :href="route('home')">Home</InertiaLink> </li>
<li>Fruits</li>
<li>Vegetables</li>
<li>Single</li>
<li> <inertia-link :href="route('Contact-Us')">Contact US</inertia-link> </li>
</ul>
</div>
</div>
</div>
</div>
</header>
</div>
</template>
<script>
import Dropdown from '#/Shared/Dropdown'
import Icon from '#/Shared/Icon'
import Profile from './Profile.vue'
export default {
components: {Dropdown,Icon,Profile},
data() {
return{
expanded:false,
profile:false,
}
},
methods:{
OpenProfile(){
if(this.expanded==false){
this.expanded=true;
}
else{
this.expanded=false;
}
},
}
}
</script>
profile.vue
<template>
<div class="contact-page">
<div>
<header-content> </header-content>
</div>
<div class="table-content">
<b-container>
<div class="table-heading">
<h1>User Profile</h1>
</div>
<b-row>
<b-col cols="3">
<div class="login-id">
<div class="id-img">
<b-img src="images/profile.jpg"></b-img>
</div>
<h2>{{this.$page.auth.user.name}}</h2>
</div>
</b-col>
<b-col cols="9">
<div class="table-area">
<div class="out-layer">
<div class="head">
<h4>User Information</h4>
</div>
<b-link>
<div class="pencil">
<b-img src="images/edit.png"></b-img>
</div>
</b-link>
</div>
<div class="user">
<b-row no-gutters>
<b-col cols="6"><span class="text">NAME</span></b-col>
<b-col cols="6"><span class="link">{{this.$page.auth.user.name}}</span></b-col>
</b-row>
</div>
</div>
</b-col>
</b-row>
</b-container>
</div>
<div>
<footer-content> </footer-content>
</div>
</div>
</template>
<script>
import HeaderContent from './Header.vue';
import FooterContent from './Footer.vue';
export default {
components: {HeaderContent,FooterContent},
data(){
return {
}
},
}
</script>
I see an error in profile.vue, you don't have to use this inside <template>.
Are other components you call in profile.vue registered correctly?
Try to remove some portions of code to debug which tags throw the error.

scroll between Nav and components Vue

I have created a vue single page this way:
My app.vue
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div id="app">
<Navegacion/>
<Cabecera/>
<Contenido/>
<Aside/>
<Footer/>
</div>
</template>
My navigation.vue
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div class="flex flex-row blanco">
<div class="item-uno">
<nav class="flex flex-row items-center">
<a #click="desplazar" href="#">Quienes somos</a>
<a #click="desplazar" href="#">Cómo funciona</a>
<a #click="desplazar" href="#">Servicios a empresas</a>
<a #click="desplazar" href="#">Compromiso</a>
</nav>
</div>
<div class="item-dos flex justify-center">
<img id="logo" src="../assets/logo.svg" alt="logo apeteat">
</div>
<div class="item-uno flex justify-center items-center">
<a class="btn blue">Nuevo pedido</a>
<div class="flex flex-row items-center">
<i class="fas fa-shopping-bag"></i>
<p>0,00 €</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Navegacion',
props: {
},
methods: {
desplazar: function() {
window.scrollTo(0,200);
}
}
}
</script>
I want to make scroll to the correspondent component when clicking on a navigation link.
I have installed npm scroll-to, and I have tried to add a function methd desplazar but it's not working.
Thanks in advance for your help.
window.scrollTo() is javascript window method, you don't need to install anything to use it.
It works in your code but href="#" always throw you at the top of the page so it's cancelling window.scrollTo().
You need to remove href="#" from your links.
To scroll to component first you need to add ref to it like this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div id="app">
<Navegacion ref="Navegacion" />
<Cabecera ref="Cabecera" />
<Contenido ref="Contenido" />
<Aside ref="Aside" />
<Footer ref="Footer" />
</div>
</template>
and your function should looks like this
scrollToNavegacion() {
window.scrollTo(0, this.$refs.Navegacion.$el.offsetTop);
}

How to call VueJS component from another component

I'm new to VueJS, i have different pages which i organized in 'components'. Now, different pages have different layouts, for example, some pages will not include the header and the footer (which are also individual components).
This is the code for a component that is supposed to include the header
<template>
<Header />
<div class="container main-content">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-8">
<h3 style="font-weight: bold;color: #000;">What will you like to do?</h3>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/dashboards" class="">
<i class="fa fa-user fa-4x"></i>
<p>View Dashboards</p>
</router-link>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/home" class="">
<i class="fa fa-cogs fa-4x"></i>
<p>Manage Settings</p>
</router-link>
</div>
</div>
</div>
<div class="col-lg-2"></div>
</div>
</div>
</template>
<script>
import Header from './Header.vue'
export default{
name: 'Loyalty',
components:{
'Header': Header
}
}
</script>
And this is my Header.vue
<template>
<div>
<div class="head">
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<span class="pull-left" style="padding-left: 10px;">
<router-link to="/home" class="header-text page-link"><span class="fa fa-arrow-left"></span> Home</router-link>
</span>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6 custom-hidden-sm">
<span class="pull-right" style="padding-right: 10px;">
<span class="header-text">Waje Loyalty</span>
</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
name: 'Header',
data(){
return{
page_name: this.$router.currentRoute.name
}
}
}
</script>
When i compile, i get the error:
- Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
How can i solve this?
The issue is caused by the two root elements in your Loyalty.vue template: <Header /> and <div class="container main-content">.
VueJS component templates can contain one and only one root node.
To solve this, wrap the content of your Loyalty.vue template with a root div.
<template>
<!-- root div -->
<div>
<Header />
<div class="container main-content">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-8">
<h3 style="font-weight: bold;color: #000;">What will you like to do?</h3>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/dashboards" class="">
<i class="fa fa-user fa-4x"></i>
<p>View Dashboards</p>
</router-link>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/home" class="">
<i class="fa fa-cogs fa-4x"></i>
<p>Manage Settings</p>
</router-link>
</div>
</div>
</div>
<div class="col-lg-2"></div>
</div>
</div>
</div>
</template>