How to add smooth scroll on a navigation link using Vue js between different pages? - vue.js

I have a HomeNavbar.vue component that has my Navbar links (I'm using Vue-Router).
HomeNavbar.vue:
<template>
<div>
<b-container fluid>
<b-row>
<b-col>
<nav class="navbar navbar-expand-lg">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<a class="navbar-brand logo" href="/"></a>
<ul class="navbar-nav ml-auto mt-2 mt-lg-0">
<li class="nav-item">
<router-link to="/" class="nav-link">Home</router-link>
</li>
<li class="nav-item">
<router-link to="/about" class="nav-link">About</router-link>
</li>
<li class="nav-item">
<ScrollToLink
href="#features"
class="nav-link"
>Features
</ScrollToLink>
</li>
<!-- <li class="nav-item">-->
<!-- <router-link to="/pricing" class="nav-link">Pricing</router-link>-->
<!-- </li>-->
<li class="nav-item">
<router-link to="/faqs" class="nav-link">FAQ's</router-link>
</li>
<li class="nav-item">
<router-link to="/contact" class="nav-link">Contact</router-link>
</li>
</ul>
</div>
<!-- <a class="nav-link" id="searchBox"><i class="fa fa-search"></i></a>-->
</nav>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import ScrollToLink from '../components/ScrollToLink';
export default {
name: "HomeNavbar",
components: {
ScrollToLink
}
}
</script>
As you can see I created a simple component for smooth scrolling called ScrollToLink.vue,
that is being used in the code above.
ScrollToLink.vue:
<template>
<a :href="href" #click.prevent="scroll">
<slot></slot>
</a>
</template>
<script>
export default {
name: "ScrollToLink",
props: ['href'],
methods: {
scroll() {
document.querySelector(this.href)
.scrollIntoView({ behavior: 'smooth' });
}
}
}
</script>
<style scoped>
</style>
The code works well when I'm on the Home page, which contains the features section with the id="#features" where it will scroll down to.
But if I click on About page, and then click on Features button it points to http://highrjobsadminlte.test/about#features, instead of this http://highrjobsadminlte.test/#features.
How can I get it to link back to /#features via the Home page?

Related

How can i change theme (dark / light ) in VueJS

I have a problem in VueJS. I coding a website and i want to add a sun icon. I want to change theme when click icon. You knows; if theme is dark do light and the exact opposite. I think emit() is not work. But I am not sure.
This is codes:
Navbar.vue
<script setup>
import { RouterLink, RouterView } from 'vue-router'
defineEmits(['toggle'])
</script>
<template>
<div>
<nav class="navbar navbar-expand-lg" id="navbar">
<div class="container-fluid">
<a href="/" class="navbar-brand">
<span>osman<span>beyhan</span></span>
</a>
<div class="iconsTwo">
<i class="bi bi-sun-fill d-block d-lg-none" id="icon" #click="this.$emit('toggle')"></i>
<i class="bi bi-list navbar-toggler" data-bs-toggle="offcanvas" href="#offcanvasMenu" aria-controls="offcanvasMenu"></i>
</div>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasMenu" aria-labelledby="offcanvasMenuLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasMenuLabel">
<a href="/">
<span>osman<span>beyhan</span></span>
</a>
</h5>
<i class="bi bi-x-lg btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></i>
</div>
<div class="offcanvas-body">
<ul class="navbar-nav">
<li class="nav-item">
<a class="" href="/about">About Me</a>
</li>
<li class="nav-item">
<a class="" href="/projects">Projects</a>
</li>
<li class="nav-item">
<a class="" href="/contact">Contact</a>
</li>
</ul>
<hr id="line">
<ul class="nav-item d-flex d-md-flex" id="icons">
<li>
<a class="" target="_blank" href="https://www.instagram.com/osmn_byhn/?hl=tr">
<i class="fa-brands fa-instagram"></i>
</a>
</li>
<li>
<a class="" target="_blank" href="https://github.com/osmn-byhn">
<i class="fa-brands fa-github"></i>
</a>
</li>
<li>
<a class="" target="_blank" href=" https://wa.me/905350217844">
<i class="fa-brands fa-whatsapp"></i>
</a>
</li>
<li>
<a class="" target="_blank" href="https://www.linkedin.com/in/osman-beyhan-12304b23a/">
<i class="fa-brands fa-linkedin"></i>
</a>
</li>
<br>
<li id="ayrac" class="d-none d-lg-block"> | </li>
<li>
<i class="bi bi-sun-fill d-none d-lg-block mysun" id="icon"></i>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
</template>
<style lang="scss" scoped>
#import '/public/Navbar.scss';
#import '/public/Theme.scss';
</style>
App.vue
<script setup>
import { RouterLink, RouterView } from 'vue-router'
import Navbar from './components/Navbar.vue'
import { ref } from 'vue'
var mode = ref('dark')
function toggle() {
if (mode === "dark") {
mode = "light"
console.log(mode)
} else {
mode = "dark"
console.log(mode)
}
}
</script>
<template>
<div class="app" :class="mode">
<Navbar :mode="mode" #toggle="toggle" />
<RouterView />
</div>
</template>
<style scoped lang="scss">
#import '../public/App.scss';
#import '../public/Theme.scss';
</style>
When i click sun icon; function is works but theme don't change:
enter image description here
Please help me!
In the script setup syntax, you shouldn't use $this when emitting something, instead you should handle it like this:
<script setup>
// more logic ...
const emit = defineEmits(["toggle"]);
</script>
<template>
<div>
<button #click="emit('toggle', someData)">toggle theme</button>
</div>
</template>
Then in the parent component:
<script setup>
const handleData = (param) => {
console.log("data passed was ", param);
}
</script>
<template>
<MyComponent #toggle="handleData()">
...
</MyComponent>
</template>
But also, you could just add the dark class to the body, and while it's outside the vue app instance, you could just handle the logic directly in the Navbar component and adding the class in vanilla javascript:
<!-- Navbar component, without emit -->
<script setup>
const toggle = () => {
if(document.body.classList.contains("dark")){
document.body.classList.remove("dark");
}else{
document.body.classList.add("dark");
}
}
</script>

How to change a css style each page in vue-cli

This is App.vue File
<template>
<div id="app">
<main-header/>
<router-view/>
<main-footer/>
</div>
</template>
<script>
import MainHeader from './components/layouts/MainHeader'
import MainFooter from './components/layouts/MainFooter'
export default {
name: 'App',
components: {
'main-header': MainHeader,
'main-footer': MainFooter
}
}
</script>
Header.vue file is
<ul class="nav nav-pills" id="mainNav">
<li class="dropdown">
<a class="active" href="/">
Home
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test1">
test1
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test2">
test2
</a>
</li>
</ul>
I want to activate "active class" differently for each page.
I don't know how to do
if I click a "test2", active class have to maintain only with the tag with "test2"
How can I resolve this issue?
You can consider using Vue-router with active-class prop
<ul class="nav nav-pills" id="mainNav">
<router-link to="/" tag="li" class="dropdown" active-class="active">Home</router-link>
<router-link to="/test1" tag="li" class="dropdown-item dropdown-toggle" active-class="active">Test1</router-link>
<router-link to="/test2" tag="li" class="dropdown-item dropdown-toggle" active-class="active">Test2</router-link>
</ul>
Another naive solution is checking window.location.href, but it's not simple to cover all possible cases.
<ul class="nav nav-pills" id="mainNav">
<li class="dropdown">
<a class="active" href="/">
Home
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test1" :class="getClass('/test1')">
test1
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test2" :class="getClass('/test2')">
test2
</a>
</li>
</ul>
<script>
export default {
methods: {
getClass(url) {
if (window.location.href.includes(url)) {
return "active"
}
return ""
}
}
}
</script>

passing data between components not working

i have been struggling for hours on this one, i am a newbie in vuejs basically i have a modal based on tabs and i want to show some data into the modal-content of my modal, the place where click event of open modal occurs is in another vue file and the place where i want to populate the modal content is in another vue,here's my code
main blade file
#section('main-content')
<div class="full-page-taps">
<div class="page-head p-4 mb-lg-4">
<h3>Directory</h3>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<employee-search :inplaceholder="'Search Techs'"></employee-search>
</div>
</div>
<employee-card-section :indata="{{ $employees }}"></employee-card-section>
</div>
<modal name="employee-modal"
:width="'94%'"
:height="'94%'"
>
<employee-modal-content v-on:custom="customHandler"></employee-modal-content>
</modal>
</div>
#endsection
employeecard.vue
methods: {
openEmployee() {
// if(this.viewEmployees) {
this.$modal.show('employee-modal');
// this.$emit("passdata",this.employee.id);
this.$emit('chalja');
// this.$emit('custom', 'somedata');
// this.$eventHub.$emit("passdata");
// })
// }
}
},
employee-modal-content.vue
<template>
<div>
<div class="secondary-header no-margin">
<h2>UNEEB</h2>
</div>
<div class="customer-panel">
<input type="hidden" id="eid" value="" />
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#profile" role="tab">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#bio" role="tab">Bio</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#audit" role="tab">Audit</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="profile" role="tabpanel">
</div>
<div class="tab-pane" id="bio" role="tabpanel">
</div>
<div class="tab-pane" id="audit" role="tabpanel">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods:{
customHandler : function(e){
console.log(e);
console.log("works");
}
},
mounted(){
this.$eventHub.$on('chalja', ()=> {
alert("agya");
});
}
}
</script>
i basically want to pass in the ID from employeecard.vue to directory-modal-content.vue. i have tried many solutions but none worked for me, any help?
Should be so:
1.Pass your id as dynamic prop of component
<employee-modal-content :id="employee.id"></employee-modal-content>
2.In your child component u have to use props to receive the id variable
<template>
<div>
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
methods:{
//...
}
}
</script>

Hide Navigation Links in VueJs When Clicked

I tried everything to make the navigation links hide when I clicked but it didn't worked. Here my Header.vue file.
<template>
<nav class="navbar is-dark is-fixed-top">
<div class="container">
<div class="navbar-brand">
<router-link to="/" class="navbar-item">
<img src="../../assets/logo.png" width="">
</router-link>
<a role="button"
:class="{ 'is-active': ShowMenu }"
class="navbar-burger burger"
#click="toggleMenu()"
aria-label="menu"
aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div :class="{ 'is-active': ShowMenu }"
class="navbar-menu">
<div class="navbar-start">
<router-link to="/" class="navbar-item">Home</router-link>
<router-link to="/about" class="navbar-item">About</router-link>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="field is-grouped">
<p class="control">
<router-link to="/login" class="button is-dark">
<span><i class="fa fa-lock"></i> Login</span>
</router-link>
</p>
<p class="control">
<router-link to="/register" class="button is-light">
<span><i class="fa fa-user"></i> Register</span>
</router-link>
</p>
</div>
</div>
</div>
</div>
</div>
</nav>
Here's the JS codes. Navigation are working when a click the links but the only problem I have is that it didn't automatically hide.
export default {
name: "Header",
data() {
return {
ShowMenu: false,
NavigationItems: true,
NavigationItems: false
}
},
methods: {
toggleMenu: function() {
this.ShowMenu = !this.ShowMenu
},
toggleNavItem: function() {
false
}
}
}
Try
<a v-if='!ShowMenu' role="button" ...
instead of using CSS
You shouldn't use v-if it will "kill" the element in the dom, but if you only want to toggle it use v-show width !ShowMenu like Steven explained.
And if you want to use a CSS class: do you have a class called is-active and is the default behavior of .burger display: none;? If you want to stay on this solution please provide us your CSS.

Aurelia nav-bar VM Not Working

I followed the examples for setting up a nav-bar.html and a nav-bar.js in the Aurelia tutorial. Later, I wanted to add some functionality to the nav-bar.js VM but found that non of it's properties or methods are ever called.
I'm trying to use Aurelia Auth filtering on my top navigation, but even when omitting the auth functionality, nothing in top-nav-bar.js is ever called.
Code below:
top-nav-bar.js
import {bindable} from 'aurelia-framework';
import {inject} from 'aurelia-framework';
import {AuthService} from 'aurelia-auth';
//import {AuthFilterValueConverter} from './authFilter';
//import {Router} from 'aurelia-router';
#inject(AuthService )
export class TopNavBar {
_isAuthenticated=false;
#bindable router = null;
constructor(auth){
console.log('called nav bar constructor'); //NEVER CALLED
this.auth = auth;
}
//#computedFrom(this.auth)
get isAuthenticated(){
return this.auth.isAuthenticated(); //NEVER CALLED
}
}
top-nav-bar.html
<template>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<!-- <require from="paulvanbladel/aurelia-auth"></require> -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">
<i class="fa fa-home"></i>
<span>${router.title}</span>
</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li repeat.for="row of router.navigation | authFilter: isAuthenticated" class="${row.isActive ? 'active' : ''}">
<a data-toggle="collapse" data-target="#bs-example-navbar-collapse-1.in" href.bind="row.href">${row.title}</a>
</li>
</ul>
<ul if.bind="!isAuthenticated" class="nav navbar-nav navbar-right">
<li>Login</li>
</ul>
<ul if.bind="isAuthenticated" class="nav navbar-nav navbar-right">
<li>Profile</li>
<li>Logout</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="loader" if.bind="router.isNavigating">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</li>
</ul>
</div>
</nav>
</template>
app.html
<template>
<require from="./top-nav-bar.html"></require>
<require from="bootstrap/css/bootstrap.css"></require>
<top-nav-bar router.bind="router"></top-nav-bar>
<div class="page-host">
<router-view></router-view>
</div>
</template>
If you have aurelia VM with js and html you need to import it to the view like (without *.html):
<require from="./top-nav-bar"></require>
Sometimes you do not have VM for the view, in that case you import just the html, like you do:
<require from="./top-nav-bar.html"></require>