Vue.js 2 - Bootstrap 4 - vue.js

I am trying to understand how t use the standard Bootstrap 4 css with a vue.js app..
I set up a simple test project using vue-cli webpack , and copied a standard Bootstrap navbar in a header component.
It displays BUT no links are visible ....
added into package.json
"bootstrap": "4.0.0-beta.3",
added into main.js
import 'bootstrap/dist/css/bootstrap.css'
App.vue
<template>
<div id="app">
<myheader></myheader>
<div class="container">
<router-view></router-view>
</div>
</div>
</template>
<script>
import myheader from '#/components/Header'
export default {
name: 'app',
components: { myheader }
}
</script>
<style>
</style>
Header.vue
<template>
<header id="myheader">
<div class="container">
<nav class="navbar navbar-light bg-faded rounded ">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#containerNavbar" aria-controls="containerNavbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="containerNavbar">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>z
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown04" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown04">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-md-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
</div>
</header>
</template>
<script>
import router from '#/router/index'
export default {
name: 'myheader',
router
}
</script>
<style>
</style>
**UPDATE**
I added jQuery and popper.js with npm
and updated my webpack.dev.config
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery'
})
]
I also updated my .eslintrc
globals: {
"$": true,
"jQuery": true
},
Now the Bootstrap navbar collapse runs correctly , but still no horizontal links...

Some of Bootstrap v4 requires a DOM API wrapping library like jQuery to function:
Many of our components require the use of JavaScript to function.
Specifically, they require jQuery, Popper.js, and our own JavaScript
plugins. Place the following s near the end of your pages,
right before the closing tag, to enable them. jQuery must come
first, then Popper.js, and then our JavaScript plugins.
We use jQuery’s slim build, but the full version is also supported.
This is also the case with Bootstrap v3:
Please note that all JavaScript plugins require jQuery to be included,
as shown in the starter template. Consult our bower.json to see which
versions of jQuery are supported.
Although a lot of Bootstrap can get used without any JavaScript, some components like dropdowns, alert dismissing, and other cross-cutting widgets need the extra power that JavaScript provides. You can probably get away without it if you are just using the grid system.
However, if you would rather not explicitly depend on jQuery, you could try Vue Bootstrap which is a Vue plugin that provides most of the Bootstrap components and wraps the things that jQuery is necessary for in a Vue oriented way.

As Bootsrap4 is still in beta (3) I am using in my test the wrong standard classes, I rather should use :
nav class="navbar navbar-dark bg-dark navbar-expand-md">
up and running now ....

Related

Vue 3 Bootstrap 5 Navbar not toggling back to minimized

Im using bootstrap 5 on vue 3 like by doing the below
npm install bootstrap
and importing it in main.js like
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
import "bootstrap/dist/js/bootstrap.js"
and now in my components I have a nav
<nav class="navbar navbar-dark bg-dark navbar-expand-lg">
<div class="container container-fluid">
<a class="navbar-brand" href="/">Title</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navContent" aria-controls="navContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/products">Products</a>
</li>
<li v-if="isAuth" class="nav-item float-end ms-md-auto">
<a class="nav-link active" v-on:click="showLogoutDialog">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
And now the issue is that - I can toggle it to show the menu but cant toggle back. On looking into the inspect tool, I can see that the collapsing class gets applied but immediately disappears.
Thanks for any help in advance and please let me know if anything else is needed.
Eh.. solved it. So the issue is that if bootstrap gets included twice - the classes might not apply properly. So I had to remove the boostrap.js import. Now it works fine.
I also got facing the same problems. please run your project editing code with double quotes to single quotes.
Your code:
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
import "bootstrap/dist/js/bootstrap.js"
my testing code:
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.js'
import "bootstrap" **** Remove this line and run the server again and check

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.

Trying to understand a better way to code my drop-down menus in vue

I am making the jump from jQuery/WordPress to Vue and I am really loving it so far but very basic things can confuse the hell out of me. I am working on a project and I'm trying to do the coding work myself (not copy/paste code into my app) so I can force myself to learn it. I have been working on a dropdown menu system and got it working, but I know it's sloppy.
I was having trouble passing variables down to the methods section, so I couldn't seem to make my functions dynamic. So I had to repeat a lot of code to get it to work. I know there is a better way of doing this, I just don't understand what Vue wants from me. I kept getting 'variable is defined but not used' errors when I tried to pass information. I don't have the broken code anymore so I can't show that off, but I do have my working code.
I am hoping someone can critique my shit code and help me understand a more sleek way of doing this.
<template>
<div>
<div id="nav">
<nav>
<ul>
<li>
<a class="navButton" #click.prevent="mapsDrop">Maps <i class="fas fa-layer-group"></i></a>
<transition name="slide-fade">
<div class="dropDown" v-show="isMapsOpen">
Drop Down Menu
</div>
</transition>
</li>
<li>
<a class="navButton" #click.prevent="createDrop">Create <i class="fas fa-plus-circle"></i></a>
<transition name="slide-fade">
<div class="dropDown" v-show="isCreateOpen">
Drop Down Menu
</div>
</transition>
</li>
<li>
<a class="circle" #click.prevent="notificationsDrop"><i class="fas fa-bell"></i></a>
<transition name="slide-fade">
<div class="dropDown" v-show="isNotificationsOpen">
Notofications
</div>
</transition>
</li>
</ul>
</nav>
</div>
</div>
</template>
<script>
export default {
data() {
return{
isMapsOpen: false,
isCreateOpen: false,
isNotificationsOpen: false
}
},
methods: {
toggle() {
mutations.toggleNav();
},
mapsDrop() {
this.isMapsOpen = !this.isMapsOpen
if(this.isNotificationsOpen){
this.isNotificationsOpen = !this.isNotificationsOpen
}
if(this.isCreateOpen){
this.isCreateOpen = !this.isCreateOpen
}
},
createDrop() {
this.isCreateOpen = !this.isCreateOpen
if(this.isNotificationsOpen){
this.isNotificationsOpen = !this.isNotificationsOpen
}
if(this.isMapsOpen){
this.isMapsOpen = !this.isMapsOpen
}
},
notificationsDrop() {
this.isNotificationsOpen = !this.isNotificationsOpen
if(this.isCreateOpen){
this.isCreateOpen = !this.isCreateOpen
}
if(this.isMapsOpen){
this.isMapsOpen = !this.isMapsOpen
}
}
}
};
</script>
I'll repeat, this all works. I couldn't figure out how to get it to run in snippet mode, and I've stripped out some of the other parts so you don't have to dig through it.. I shouldn't have to create functions for each of my menus, right?
Thanks in advance.
Try having one data value and toggling with just that:
new Vue({
el: "#app",
data() {
return{
toggle: ""
}
},
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div id="nav">
<nav>
<ul>
<li>
<a class="navButton" #click.prevent="toggle = 'maps'">Maps <i class="fas fa-layer-group"></i></a>
<transition name="slide-fade">
<div class="dropDown" v-if="toggle === 'maps'">
Drop Down Menu
</div>
</transition>
</li>
<li>
<a class="navButton" #click.prevent="toggle = 'create'">Create <i class="fas fa-plus-circle"></i></a>
<transition name="slide-fade">
<div class="dropDown" v-if="toggle === 'create'">
Drop Down Menu
</div>
</transition>
</li>
<li>
<a class="circle" #click.prevent="toggle = 'notifications'"><i class="fas fa-bell"></i></a>
<transition name="slide-fade">
<div class="dropDown" v-if="toggle === 'notifications'">
Notifications
</div>
</transition>
</li>
</ul>
</nav>
</div>
</div>
Insert a unique value for each dropdown and then use v-if to determine if it contains the correct value.

Aurelia - Asp.net Core SPA project has error on navmenu only - uncrementCounter is not a function

I have Aurelia - ASP.NET core 2 template project.. You can download it from GITHUB and run it to verify the error.
I had made significant changes until I found an error in the navmenu.html not recognising a function.
I went back to the template and did a quick test and found the same error in the base template.
I registered this question on my original solution with the same problem but have now realised its to do with the actual Aurelia template I got. So I have uploaded the entire project to github so someone can see the whole thing.
To get this error all I am doing is creating a function on the navmenu and referencing that on a button using "click.deligate". Here is the navmenu.html:
<template bindable="router">
<require from="./navmenu.css"></require>
<div class="main-nav">
<div class="navbar navbar-inverse">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<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="#/home">Jobsledger.API</a>
</div>
<div class="clearfix"></div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li repeat.for = "row of router.navigation" class="${ row.isActive ? 'link-active' : '' }" >
<a href.bind = "row.href">
<span class="glyphicon glyphicon-${ row.settings.icon }"></span> ${ row.title }
</a>
</li>
</ul>
</div>
</div>
</div>
<div>
<h1>Counter</h1>
<p>This is a simple example of an Aurelia component.</p>
<p>Current count: <strong>${currentCount}</strong></p>
<button click.delegate="incrementCounter()">Increment</button>
</div>
Here is the viewmodel.ts file
import { autoinject } from "aurelia-framework";
#autoinject
export class Navmenu {
//loggedInService: LoggedInService;
public currentCount = 0;
public incrementCounter() {
this.currentCount++;
}
}
The error is:
aurelia-binding.js:1905 Uncaught Error: incrementCounter is not a function
at getFunction (aurelia-binding.js:1905)
at CallScope.evaluate (aurelia-binding.js:1508)
at Listener.callSource (aurelia-binding.js:5082)
at Listener.handleEvent (aurelia-binding.js:5091)
at HTMLDocument.handleDelegatedEvent (aurelia-binding.js:3223)
As I say there is a working asp.net core solution that has the spa in it and can be downloaded from github.
It would be great if someone could assist me here as this is currently a show stopper for me.
You are requiring your navmenu as a template only, e.g. <require from="../navmenu/navmenu.html"></require>. In order to use your view with your javascript please see this guide about custom elements.

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'">