I need to update the hash of the url, without actually triggering the vue-router to go to that route. Something in the likes of:
router.replace('my/new/path', {silent:true})
This would update the url to .../#/my/new/path
, but the router itself would not route to that path.
Is there an elegant way to achieve this?
To navigate to a different URL, use router. push . This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.
Another solution explained in vue-router doc. Simply use the watch system applied to the $route native attribute. You'll be able to detect new route even if they use the same component and fetch the data in consequence.
Opening the link in a new tab To open the link in a new tab, we need to add the target attribute with a value _blank to the <router-link> component.
To reload a route with Vue Route, we can call the this. $router.go() method. If it has no arguments, then it'll reload the current route. This way, it'll notice when the path changes and it'll trigger a reload of the component with new data.
Without reloading the page or refreshing the DOM, history.pushState
can do the job.
For example: add this method in your component or elsewhere to do that:
addHashToLocation(params) {
history.pushState(
{},
null,
this.$route.path + '#' + encodeURIComponent(params)
)
}
Then anywhere in your component you can call addHashToLocation('/my/new/path')
to push query params to the window.history
stack.
To add query parameters to current location without pushing a new history entry, use history.replaceState
instead.
Should work with Vue 2.6.10 and Nuxt 2.8.1. Be careful with this method, as Vue Router does not know that the URL has changed.
The Vue router is either on or off, so you cannot "make it not detect certain urls". That said, Vue does re-use components if it doesn't need to destroy them and allows you to alias urls. This allows you to have the urls from your iframe application as aliases in your route, and keep the same component alive during that time, preventing your iframe from getting reloaded.
// router.js
import Comp1 from "./components/Comp1";
import Comp2 from "./components/Comp2";
export default [
{
path: "/route1",
component: Comp1,
alias: ["/route2", "/route3", "/route4"]
},
{
path: "/otherroute",
component: Comp2
}
];
// main.js
import Vue from "vue";
import App from "./App";
import VueRouter from "vue-router";
import routes from "./router";
Vue.config.productionTip = false;
Vue.use(VueRouter);
const router = new VueRouter({
routes
});
/* eslint-disable no-new */
new Vue({
el: "#app",
router,
components: { App },
template: "<App/>"
});
In this example, route1
, route2
, route3
and route4
will all be treated as if route1
has to be loaded, causing your component Comp1
to stay alive.
if what you are trying to do is update the url to show the page state (perhaps something like ?search=something
) then you can do a trick like this. the key idea is using a toggle this.respondToRouteChanges
to ignore changes when the url is updated by your code.
when updating the route (eg. in a vue method in your component)
this.respondToRouteChanges = false;
this.$router.replace({query: { search: this.search })
.finally(() => {
this.respondToRouteChanges = true;
});
and in the component code that would normally watch/handle changes to the route
setSearch() {
if (!this.respondToRouteChanges){
// console.log('ignoring since route changes ignored')
return;
}
if (this.search !== this.querySearch)
this.search = this.querySearch;
},
watch: {
// watch for changes in the url
'querySearch': 'setSearch',
note that respondToRouteChanges
is just a boolean defined as data()
in the component
data() {
return {
respondToRouteChanges: true,
...
querySearch
is just a computed value which returns the route
querySearch() {
return this.$route.query.search || '';
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With