问题
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?
回答1:
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.
回答2:
Without reloading the page or refreshing the dom, history.pushState
can do the job.
Add this method in your component or elsewhere to do that:
addHashToLocation(params) {
history.pushState(
{},
null,
this.$route.path + '#' + encodeURIComponent(params)
)
}
So anywhere in your component, call addHashToLocation('/my/new/path')
to push the current location with query params in the window.history stack.
To add query params 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!
Vue Router don't know that url has changed, so it doesn't reflect url after pushState.
回答3:
I found how to Silently update url
, but route anyway is triggered (but this maybe is not a problem - dependents on situation).
In my case user may create a profile, for example via URL http://localhost:8080/#/user/create/
, provide some profile info and once "Save" is clicked user is redirected to his/her created profile with URL for example http://localhost:8080/#/FaFYhTW9gShk/
, where the user may continue editing the profile form.
How do I do that?
user/create/
page (ProfileCreate) andFaFYhTW9gShk/
page (ProfileDetails) use the sameProfileUser
component.
// router.js
const routes = [
{
path: '/user/create',
component: Profile,
children: [
{
path: '',
name: 'ProfileCreate',
component: ProfileUser
}
]
}
{ path: '/:profileUrl',
component: Profile,
children: [
{
path: '',
name: 'ProfileDetails',
component: ProfileUser
}
]
}
]
- In
router.beforeEach
I check whether I need to load data from the back end, or I need simply to change URL?
// router.js
router.beforeEach((to, from, next) => {
if (!('isProfileLoaded' in to.params)) {
// load profile from backend and update Vuex
}
next()
})
- When "Save" button is clicked, in
action
I send data to backend + callrouter.push
// action.js
import router from '@/router'
// Here I send data to backend
// Some code
// Update-URL-Trick
router.push({
name: 'ProfileDetails',
params: { profileUrl: profileUrl isProfileLoaded: true }
})
As far as isProfileLoaded
is provided, Vue re-uses profile's data from Vuex + router silently
updates URL re-using the same ProfileUser
component.
来源:https://stackoverflow.com/questions/51337255/silently-update-url-without-triggering-route-in-vue-router