javascript - Hur man ställer in URL-frågeparametrar i Vue med Vue-Router
Jag försöker sätta query-parametrar med Vue-router när jag ändrar i inmatningsfält, jag vill inte navigera till en annan sida utan vill bara ändra URL:ens query-parametrar på samma sida, jag gör så här:
this.$router.replace({ query: { q1: "q1" } })
Men detta uppdaterar också sidan och sätter y-positionen till 0, det vill säga scrollar till toppen av sidan. Är detta rätt sätt att ställa in URL:s queryparametrar eller finns det ett bättre sätt att göra det?
Redigerad :
Här är min routerkod:
export default new Router({
mode: 'history',
scrollBehavior: (to, from, savedPosition) => {
if (to.hash) {
return {selector: to.hash}
} else {
return {x: 0, y: 0}
}
},
routes: [
.......
{ path: '/user/:id', component: UserView },
]
})
Svar #1
Här är exemplet i dokumenten:
// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
Ref: https://router.vuejs.org/guide/essentials/navigation.html
Som nämnts i de dokumenten fungerar router.replace som router.push
Så, det verkar som att du har det rätt i din exempel kod i fråga. Men jag tror att du kan behöva inkludera antingen name eller path-parametern också, så att routern har någon rutt att navigera till. Utan en name eller path ser det inte särskilt meningsfullt ut.
Det här är min nuvarande förståelse nu:
queryär valfritt för routern - lite ytterligare information för komponenten att konstruera vynnameellerpathär obligatoriskt - det bestämmer vilken komponent som ska visas i din<router-view>.
Det kan vara den sak som saknas i din exempelkod.
REDIGERA: Ytterligare detaljer efter kommentarer
Har du försökt använda namngivna rutter i detta fall? Du har dynamiska rutter, och det är enklare att ange parametrar och frågor separat:
routes: [
{ name: 'user-view', path: '/user/:id', component: UserView },
// other routes
]
och sedan i dina metoder:
this.$router.replace({ name: "user-view", params: {id:"123"}, query: {q1: "q1"} })
Tekniskt sett finns det ingen skillnad mellan ovanstående och this.$router.replace({path: "/user/123", query:{q1: "q1"}}), men det är lättare att tillhandahålla dynamiska parametrar på namngivna rutter än att komponera ruttsträngen. I båda fallen bör query-parametrar beaktas. I båda fallen kunde jag inte hitta något fel i hur query-parametrarna hanteras.
Efter att du är inne i routen kan du hämta dina dynamiska parametrar som this.$route.params.id och dina frågeparametrar som this.$route.query.q1.
Svar #2
Utan att ladda om sidan eller uppdatera DOM, kan history.pushState göra jobbet.
Lägg till denna metod i din komponent eller någon annanstans för att göra det:
addParamsToLocation(params) {
history.pushState(
{},
null,
this.$route.path +
'?' +
Object.keys(params)
.map(key => {
return (
encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
)
})
.join('&')
)
}
Så var som helst i din komponent, kalla addParamsToLocation({foo: 'bar'}) för att trycka den nuvarande platsen med frågeparametrar i window.history-stacken.
För att lägga till frågeparametrar till den aktuella platsen utan att skapa en ny historikpost, använd history.replaceState istället.
Testat med Vue 2.6.10 och Nuxt 2.8.1.
Var försiktig med den här metoden!
Vue Router vet inte att URL:en har ändrats, så den uppdaterar inte URL:en efter pushState.
Svar #3
Okej, så jag har försökt lägga till en parameter till min befintliga URL som redan har parametrar i en vecka nu lol, original-URL: http://localhost:3000/somelink?param1=test1 jag har försökt med:
this.$router.push({path: this.$route.path, query: {param2: test2} });
denna kod skulle bara ta bort param1 och blir http://localhost:3000/somelink?param2=test2
för att lösa detta problem använde jag fullPath
this.$router.push({path: this.$route.fullPath, query: {param2: test2} });
nu har jag framgångsrikt lagt till parametrar över gamla parametrar och resultatet är
http://localhost:3000/somelink?param1=test1¶m2=test2Svar #4
Faktiskt kan du skicka en förfrågan så här: this.$router.push({query: {plan: 'private'}})
Baserat på: https://github.com/vuejs/vue-router/issues/1631
Svar #5
Om du försöker behålla vissa parametrar, samtidigt som du ändrar andra, se till att kopiera tillståndet för vue-router-queryn och inte återanvända det.
Detta fungerar, eftersom du gör en orefererad kopia:
const query = Object.assign({}, this.$route.query);
query.page = page;
query.limit = rowsPerPage;
await this.$router.push({ query });
medan nedan kommer att få Vue Router att tro att du återanvänder samma fråga och leda till NavigationDuplicated-felet:
const query = this.$route.query;
query.page = page;
query.limit = rowsPerPage;
await this.$router.push({ query });
Självklart kan du bryta ner query-objektet, till exempel på följande sätt, men du måste vara medveten om alla query-parametrar på din sida, annars riskerar du att förlora dem i den resulterande navigeringen.
const { page, limit, ...otherParams } = this.$route.query;
await this.$router.push(Object.assign({
page: page,
limit: rowsPerPage
}, otherParams));
);
Observera, medan exemplet ovan är för push(), fungerar detta också med replace().
Testad med vue-router 3.1.6.
Svar #6
Här är min enkla lösning för att uppdatera frågeparametrarna i URL:en utan att uppdatera sidan. Se till att det fungerar för ditt användningsfall.
const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
