Vue.js 3, vue-router, #click event reloads whole page - javascript

Im new to Vue and i want while on mobile navigation when I click menuItem I run function toggleMenu(open/close Menu), but then whole page reload, who to prevent that?
This is my link:
<router-link to="/" #click="toggleMenu">
<div class="nav-item">Home</div>
</router-link>
I tried adding #click.prevent and it prevents reload but not sending me to path.
EDIT:
So i make it works thanks to Boussadjra Brahim answer, but I did it with CompositionAPI and i used useRouter() hook from vue-router
Template:
<router-link
to="/"
#click.prevent="toggleMenu">
Home </router-link>
setup():
const router = useRouter();
function toggleMenu(){
router.push('/');
}

Add prevent modifier as you did then inside the toggleMenu add this.$router.push("/"); :
<router-link to="/" #click.prevent="toggleMenu">
<div class="nav-item">Home</div>
</router-link>
LIVE DEMO

Related

Next/Link keeps reload in components

It is said that in next js we don't need to install react-router-dom because the path of our pages depend on the pages folder. Well, it actually works when I create button to move to another pages. But when I create components folder and create navbar component, it doesn't work properly as it was. The next/link keeps reloading when it moves to another pages.
import Link from "next/link";
export default function Navbar() {
return (
<nav className="bg-black flex justify-between p-5 text-white">
<h1 className="font-bold text-sky-400">
<Link href="/">Furniture App</Link>
</h1>
<div>
<Link href="about">About</Link>
<Link href="promos">Promos</Link>
</div>
</nav>
);
}
Do I have to create components in pages folder in order to make Next/Link works without reload the browser?

Test click events on router-link of vuejs using jest

<ul>
<router-link to="/" tag="li" active-class="active" exact><a >Home</a></router-link>
<router-link to="/contact" tag="li" exact><a>contact</a></router-link>
<router-link to="/other" tag="li" exact><a>other</a></router-link>
<ul/>
Test.spec.js
(i am trying to trigger the click event and check the other component is loaded or not)
await wrapper.findAll('a').at(2).trigger('click')
await wrapper.vm.$nextTick()
expect(wrapper.contains('This is other Page')).toBe(true)
but the test is failing
You dont need to do test about router-link, the behavior of this you dont care, becouse; the behavior that you need is only know that the is rendered. No more.
You can do test like this
const wrapper: any = shallowMount(YourComponent, {
stubs: ['router-link', 'router-view']
});
expect(wrapper.html()).toContain('to="/contact"');
Other thing that you can doing is verify that the prop "to" recived exactly the string "/contact"
For me, is enough .toContain(...)
PD: sorry for my english.

How to bind a variable prop to a v-for slot

I'm trying to have a list component, which renders a list of router-links with a scoped slot for each of the router-link. The to-prop of the router-link should be configurable by the parent.
The parent component should be able to configure the to-prop of the router link, without having to implement the router-link itself. Or if it has to implement the router-link itself, the list component should be able to pass classes to every router-link.
I've created a codepen showing the problem that I want to solve. Of course if you have any questions about it or if anything's unclear let me know.
https://codepen.io/Buffalom/pen/KKPmJPx
This is a summary of what I'm trying to achieve:
<router-link v-for="item in items" to="/" class="abc">
<!-- :to should be configurable by the parent -->
<slot :item="item"></slot>
</router-link>
I expect the parent to be able to render a list with a given array of items but configure each router-links to-prop itself.
Update
The ideal way I'd like to take would be something like this in the parent component:
<List :items="items" :to="`/1/${item.name}`">
...
As the item in the to-prop each item in items would be used on the v-for router-link in the list component itself. Kind of like a reverse scoped-slot...^^
Is this what you're looking for? You just need to make to a dynamic prop.
<router-link v-for="item in items" :to="item.url" class="abc">
<!-- :to should be configurable by the parent -->
<slot :item="item"></slot>
</router-link>
Update
If you don't have the url, look into vue-router named routes. Taken from the doc and adapted lightly:
const router = new VueRouter({
routes: [
{
path: '/1/:itemName',
name: 'item',
component: MyItemPage
}
]
})
<router-link
v-for="item in items"
:to="{ name: 'item', params: { itemName: item.name }}"
class="abc"
>
<slot :item="item"></slot>
</router-link>

Understanding basics of reach router

I am trying to understand basics of reach router and have doubts on following code
import React from "react";
import { render } from "react-dom";
import Logo from "./Logo";
import { Router, Link } from "#reach/router";
let Home = () => (
<div>
<h1>Home</h1>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="/dashboard">Dashboard</Link>
</nav>
</div>
)
let Dash = () => <div>Dash</div>
render(<Router>
<Home path="/" />
<Dash path="dashboard" />
</Router>, document.getElementById("root"));
I know that this Router works as Switch from router 4, i.e., renders only one path inside router.
Now when I start the app initially I am inside Home, e.g. here
<div>
<h1>Home</h1>
<nav>
<Link to="/">Home</Link> |{" "}
<Link to="/dashboard">Dashboard</Link>
</nav>
</div>
At this moment it is my belief that Dashboard component hasn't been rendered anywhere. However, if I type dashboard in URL or click the above link it correctly takes me to Dashboard component.
My question is how does algorithm of resolving to Dashboard works in this case?
Does it "restart" the app and see that there was a component registered for "dashboard" route initially?
My point is because when I am at home location there is nothing on the page anymore that indicates that Dashboard component is registered under dashboard route, or I am wrong?
<Router>'s internal implementation uses history.listen() (https://github.com/reach/router/blob/master/src/index.js#L103) which in turn listens to native popstate events (https://developer.mozilla.org/en-US/docs/Web/Events/popstate). You can see it in action here.
It looks like your intuitions are indeed right. <Router> component is history-aware by listening to history changes. It re-renders routes as a result of internal setState calls.
I can recommend going though the source code if you'd like to know even more about implementation details.

React bootstrap navbar not appropriate linking to other pages

I currently have an app with a few different pages, the routing works fine if I use the Link to component in the initial page, however from the navbar I get the message:
Cannot GET /page1
And I also noticed that the link on the top of the browser goes to: http://localhost:3000/page1 as opposed to http://localhost:3000/#/cities (like it would if I use Link to).
My current navbar code is this:
export class NavigationBar extends Component {
render(){
return(
<Navbar>
<Navbar.Header>
<Navbar.Brand>
Navbar
</Navbar.Brand>
</Navbar.Header>
<Nav>
<NavItem eventKey={1} href="/page1">Page1</NavItem>
<NavItem eventKey={2} href="/page2">Page2</NavItem>
</Nav>
</Navbar>);
}
}
If I just wrap the text up with Link to, it just works when we click on the text, which isn't what I want. What can I do so that the NavItem will behave like Link to but still look fine?
Thanks
I completely forgot that I need to wrap up each of my NavItem components with the LinkContainer from react-router-bootstrap.
That took care of everything.

Categories