Vue-Routerを使用してVueでURLクエリパラメータを設定する方法


114

入力フィールドを変更するときにVue-routerでクエリパラメータを設定しようとしています。他のページに移動したくないが、同じページのURLクエリパラメータを変更したいだけです。次のようにしています。

this.$router.replace({ query: { q1: "q1" } })

ただし、これによってページが更新され、y位置が0に設定されます。つまり、ページの上部にスクロールします。これは、URLクエリパラメータを設定する正しい方法ですか、それともより適切な方法ですか。


編集:

これが私のルーターコードです:

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 },
  ]
})

回答:


132

これがドキュメントの例です:

// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

参照:https : //router.vuejs.org/en/essentials/navigation.html

それらのドキュメントで言及されてrouter.replaceいるように、router.push

だから、あなたは問題のサンプルコードでそれを正しく持っているようです。しかし、私はあなたがどちらかnameまたはpathパラメータも含める必要があるかもしれないと思うので、ルータはナビゲートするための何らかのルートを持っています。なけれnamepath、それは非常に有意義見えません。

これは私の現在の理解です:

  • query ルーターではオプションです-コンポーネントがビューを構築するためのいくつかの追加情報
  • nameまたはpath必須です-に表示するコンポーネントを決定します<router-view>

それはあなたのサンプルコードに欠けているものかもしれません。

編集:コメント後の詳細

この場合、名前付きルートを使用してみましたか?動的ルートがあり、パラメーターとクエリを個別に指定する方が簡単です。

routes: [
    { name: 'user-view', path: '/user/:id', component: UserView },
    // other routes
]

そしてあなたのメソッドで:

this.$router.replace({ name: "user-view", params: {id:"123"}, query: {q1: "q1"} })

技術的には上記との間に違いはありませんthis.$router.replace({path: "/user/123", query:{q1: "q1"}})が、ルート文字列を作成するよりも、名前付きルートに動的パラメータを指定する方が簡単です。ただし、どちらの場合でも、クエリパラメータを考慮する必要があります。どちらの場合でも、クエリパラメータの処理方法に問題はありませんでした。

ルート内に入ると、動的パラメータをとしてthis.$route.params.id、クエリパラメータをとしてフェッチできますthis.$route.query.q1


パスも指定してみましたが、ページの上部へのスクロールが止まりませんでした。ルーターオプションを使用して質問を編集しましたが、変更が必要になる可能性があります。
Saurabh

クエリパラメータは、ドキュメントの適切な場所にスクロールすることを目的としていますか?アンカータグに関する他の質問と同様に?
Mani

いいえ、クエリパラメータをURLに追加したいだけです。ここでスクロールしたくありません。
Saurabh

ローカル設定でオプションをテストしたところ、クエリパラメータは正常に機能しました。私の更新された回答に示されているように、新しいルートに移動してクエリパラメータにアクセスできます。だから、問題は-スクロールさせたくないですか?または、問題はアプリ全体が再び更新されることですか?
Mani

同じページにいるので、入力を選択したときにURLに追加したいのですが、そうするとスクロールが発生します。スクロールが私の問題です。私は他のページに移動しようとしているのではなく、同じページにいて、URLクエリパラメータを追加/変更したいだけです。
Saurabh 2016年

15

ページを再読み込みしたり、domを更新したりせずにhistory.pushState、作業を実行できます。
これを行うには、コンポーネントまたは他の場所にこのメソッドを追加します。

addParamsToLocation(params) {
  history.pushState(
    {},
    null,
    this.$route.path +
      '?' +
      Object.keys(params)
        .map(key => {
          return (
            encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
          )
        })
        .join('&')
  )
}

したがって、コンポーネントの任意のaddParamsToLocation({foo: 'bar'})場所で、window.historyスタックのクエリパラメータを使用して、現在の場所をプッシュするように呼び出します。

新しい履歴エントリをプッシュせずにクエリパラメータを現在の場所に追加するには、history.replaceState代わりにを使用します。

Vue 2.6.10およびNuxt 2.8.1でテスト済み。

この方法には注意してください!
Vueルーターは、URLが変更されたことを認識しないため、pushStateの後のURLを反映しません。



4
this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })

1
私はこの答えが一番気に入りました。残念ながらこれが原因Error: Avoided redundant navigation to current location
Max Coplan

修正:this.$router.push({ query: Object.assign({...this.$route.query}, { new: 'param' }) })
最大コプラン

2
しかし、私がそれについて考えた今、あなたはただ行うことができますthis.$router.push({ query: {...this.$route.query,new: 'param'},) })
Max Coplan

3

一部のパラメーターを保持し、他のパラメーターを変更しようとしている場合は、Vueルータークエリの状態をコピーし、再利用しないでください。

参照されていないコピーを作成しているため、これは機能します。

  const query = Object.assign({}, this.$route.query);
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

以下では、Vueルーターが同じクエリを再利用していると考え、NavigationDuplicatedエラーが発生します。

  const query = this.$route.query;
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

もちろん、次のようにクエリオブジェクトを分解することもできますが、ページに対するすべてのクエリパラメータに注意する必要があります。そうしないと、結果のナビゲーションでそれらが失われる危険があります。

  const { page, limit, ...otherParams } = this.$route.query;
  await this.$router.push(Object.assign({
    page: page,
    limit: rowsPerPage
  }, otherParams));
);

上記の例はの例ですがpush()、これも機能しreplace()ます。

vue-router 3.1.6でテスト済み。


3

複数のクエリパラメータを追加する場合、これは私にとってうまくいきました(ここからhttps://forum.vuejs.org/t/vue-router-programmatically-append-to-querystring/3655/5)。

上記の答えは近いものでした…Object.assignを使用するとthis。$ route.queryが変更されますが、これは目的ではありません…Object.assignを実行するときは、最初の引数が{}であることを確認してください

this.$router.push({ query: Object.assign({}, this.$route.query, { newKey: 'newValue' }) });

2

複数のクエリパラメータを一度に設定/削除するには、グローバルミックスインの一部として以下のメソッドを使用します(thisvueコンポーネントを指します)。

    setQuery(query){
        let obj = Object.assign({}, this.$route.query);

        Object.keys(query).forEach(key => {
            let value = query[key];
            if(value){
                obj[key] = value
            } else {
                delete obj[key]
            }
        })
        this.$router.replace({
            ...this.$router.currentRoute,
            query: obj
        })
    },

    removeQuery(queryNameArray){
        let obj = {}
        queryNameArray.forEach(key => {
            obj[key] = null
        })
        this.setQuery(obj)
    },

1

通常は、履歴オブジェクトを使用します。また、ページをリロードしません。

例:

history.pushState({}, '', 
                `/pagepath/path?query=${this.myQueryParam}`);

0

これは、ページを更新せずにURLのクエリパラメータを更新する簡単な方法です。それがあなたのユースケースで機能することを確認してください。

const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.