Pass data to vue instance to all components vuejs rails - vue.js

I have this Vue instance as
document.addEventListener('DOMContentLoaded', () => {
if(document.getElementById("app")){
const node = document.getElementById('app');
const props = JSON.parse(node.getAttribute('current_user'));
const app = new Vue({
el: '#app',
router,
template: '<App />',
components: { App }
}).$mount('#app');
}
});
The data is in const props which contains user details such as email and password, it's in JSON form.
I have another component registered as
import CurrentUser from "../components/shared/CurrentUser";
Vue.component("v-current-user", CurrentUser);
And its been called in header. such as
<template>
<header class="app-header navbar">
<button class="navbar-toggler sidebar-toggler d-lg-none mr-auto" type="button" data-toggle="sidebar-show">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">
<img class="navbar-brand-full" src="/images/evercam-logo-2.png" alt="Evercam Logo">
<img class="navbar-brand-minimized" src="/images/Favicon-300.png" width="30" height="30" alt="Evercam Logo">
</a>
<button class="navbar-toggler sidebar-toggler d-md-down-none" type="button" data-toggle="sidebar-lg-show">
<span class="navbar-toggler-icon"></span>
</button>
<v-current-user />
</header>
</template>
All I want to do is to pass this props in such a way that any child component will receive it as well as I can send it to <v-current-user /> and can get the values in that component where I am using this current user
<template>
<ul class="nav navbar-nav ml-auto">
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<v-gravatar email="junaid#evercam.io" class="img-avatar" :size="40" />
</a>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="/users/sign_out">
<i class="fa fa-lock"></i> Logout
</a>
</div>
</li>
</ul>
</template>
in <v-gravatar> for email.
Sorry fo ambiguous questions I am a total newbie to Vuejs right now

Related

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

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?

Navigation bar (Mobile view) doesn't close after click - Vuejs

When I click nav link on navbar it does not collapse.
Vue version 2.6.10.
<template>
<div class="nav-wrapper">
<nav>
<ul>
<li v-for="(route, index) in routings" :key="index">
<router-link :to="route.url">{{route.name}}</router-link>
</li>
<li>
Blog
</li>
<li class="visible-xs">
<Button v-if="!isLoggedIn" :label="loginButtonLabel" :isFilled="true" :action="goToLogin"/>
<UserWidget v-else :email="setFirstName" :title="'administrator'" :isUserMenu="true" :action="gotoDashboard"/>
</li>
</ul>
</nav>
</div>
</template>
This is the navbar what i talk about
This is the header part of the code. When click on the hamburger icon class 'mobile-menu-wrapper visible-xs' this will change to 'mobile-menu-wrapper visible-xs expanded'. There for I think it will be change to previous class its solve the matter. Please advise me to find the issue.
<template>
<div class="header-wrapper">
<div class="header-container container">
<Logo/>
<Nav class="hidden-xs" :routings="routings"/>
<Button v-if="!isLoggedIn" class="hidden-xs" :label="isLoggedIn ? 'Console' : 'Login / Sign-up'" :isFilled="true" :action="goToLogin"/>
<UserWidget class="hidden-xs" v-if="isLoggedIn" :email="setFirstName" :title="'administrator'" :isUserMenu="true" :action="gotoDashboard"/>
<div class="mobile-menu-icon-wrapper visible-xs" #click="getMobileMenu">
<i v-if="isMenuExpanded" class="mobile-menu-icon close-icon"></i>
<i v-if="!isMenuExpanded" class="mobile-menu-icon expand-icons"></i>
</div>
<div class="mobile-menu-wrapper visible-xs" :class="{'expanded': isMenuExpanded}">
<div class="menu-overlay" #click="getMobileMenu"></div>
<Nav :routings="routings" :eventBus="eventBus" :adminDetails="adminDetails" :isLoggedIn="isLoggedIn"/>
<div class="mobile-menu-icon-wrapper" #click="getMobileMenu">
<i v-if="isMenuExpanded" class="mobile-menu-icon close-icon"></i>
</div>
</div>
</div>
</div>
</template>
Try to add an onclick event in your router link to close the navigation bar, I don't see the code that you're using to open/close the nav, but you can emit an event like this:
Let's listen for the event closeNav in the parent component, by adding #closeNav in the Nav component:
<template>
<div class="header-wrapper">
<div class="header-container container">
<Logo/>
<Nav class="hidden-xs" :routings="routings"/>
<Button v-if="!isLoggedIn" class="hidden-xs" :label="isLoggedIn ? 'Console' : 'Login / Sign-up'" :isFilled="true" :action="goToLogin"/>
<UserWidget class="hidden-xs" v-if="isLoggedIn" :email="setFirstName" :title="'administrator'" :isUserMenu="true" :action="gotoDashboard"/>
<div class="mobile-menu-icon-wrapper visible-xs" #click="getMobileMenu">
<i v-if="isMenuExpanded" class="mobile-menu-icon close-icon"></i>
<i v-if="!isMenuExpanded" class="mobile-menu-icon expand-icons"></i>
</div>
<div class="mobile-menu-wrapper visible-xs" :class="{'expanded': isMenuExpanded}">
<div class="menu-overlay" #click="getMobileMenu"></div>
<!-- here is part of the magic -->
<!-- alternative one, update isMenuExpanded directly -->
<Nav :routings="routings" :eventBus="eventBus" :adminDetails="adminDetails" :isLoggedIn="isLoggedIn" #closeNav="isMenuExpanded = false"/>
<!-- alternative two, update isMenuExpanded using the closeNavBar method -->
<!--<Nav :routings="routings" :eventBus="eventBus" :adminDetails="adminDetails" :isLoggedIn="isLoggedIn" #closeNav="closeNavBar"/> -->
<div class="mobile-menu-icon-wrapper" #click="getMobileMenu">
<i v-if="isMenuExpanded" class="mobile-menu-icon close-icon"></i>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
...
methods: {
// alternative using method
closeNavBar() {
this.isMenuExpanded = false;
}
}
...
}
</script>
The navbar component will emit the event once the user clicks on any router-link (you can add the event in any other link or button)
<template>
<div class="nav-wrapper">
<nav>
<ul>
<li v-for="(route, index) in routings" :key="index">
<!-- emit the event to close the navBar -->
<!-- emit directly in the tag -->
<router-link :to="route.url" #click="$emit('closeNav')">{{route.name}}</router-link>
<!-- emit by using a method -->
<!--<router-link :to="route.url" #click="closeNavBarFromChild">{{route.name}}</router-link>-->
</li>
<li>
Blog
</li>
<li class="visible-xs">
<Button v-if="!isLoggedIn" :label="loginButtonLabel" :isFilled="true" :action="goToLogin"/>
<UserWidget v-else :email="setFirstName" :title="'administrator'" :isUserMenu="true" :action="gotoDashboard"/>
</li>
</ul>
</nav>
</div>
</template>
<script>
...
methods: {
closeNavBarFromChild() {
this.$emit('closeNav') // Emit the event that the parent is listening
}
}
...
</script>
I wrote two ways to use events, but they have the same effect.

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.

Vue #click.native not working?

I have navigation component like this:
<template>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="">Website Builder</a>
</div>
<div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li>
Create
</li>
<li>
How
</li>
<li>
About
</li>
<li>
Videos
</li>
</ul>
</div>
</div>
</nav>
</template>
and my js:
Vue.component('navigation', Navigation)
Vue.component('create', Create)
Vue.component('how', How)
Vue.component('about', About)
Vue.component('youtube', Youtube)
new Vue({
el: '#app',
data: {
currentView: 'create'
}
and html:
<div id="app">
<navigation></navigation>
<keep-alive>
<transition name="slide-fade" mode="out-in">
<component :is="currentView"></component>
</transition>
</keep-alive>
</div>
However when I click on navigation, it doesn't change therefore I am assuming it's not working properly. if I put navigation away from component and stick it in div id=app it works fine, why is this happening?
The .native modifier is not necessary on native elements - it can only be used on component elements. Remove it.
It seems you want to change data in the root component. Your current code changes data in the navigation component.
Two ways to do this:
1) The clean way:
In the navigation component, we emit an event with the new value to the parent:
<a href="#" #click="$emit('current-view', 'youtube')">
in the parent (here, the root) component, we receive the event and set the value:
<navigation #current-view="currentView = $event"></navigation>
2) The hacky way:
<a href="#" #click="$root.currentView='youtube'">