Як встановити параметри URL-запитів у Vue за допомогою Vue-Router


114

Я намагаюся встановити параметри запитів за допомогою Vue-роутера при зміні полів введення, я не хочу переходити на якусь іншу сторінку, а просто хочу змінити параметри запитів 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параметр також, щоб маршрутизатор мав певний маршрут, до якого слід переходити. Без nameабо pathце не виглядає дуже значущим.

Це зараз моє розуміння:

  • query необов'язковий для маршрутизатора - деяка додаткова інформація для компонента для побудови представлення
  • nameабо pathє обов'язковим - він визначає, який компонент показати у вашому <router-view>.

Це може бути відсутнім у вашому зразку коду.

EDIT: Додаткові деталі після коментарів

Чи намагалися ви в цьому випадку використовувати названі маршрути ? У вас є динамічні маршрути, і простіше надати параметри та запити окремо:

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.


Я також спробував дати шлях, але це не перестало прокручуватися до верхньої частини сторінки, я також відредагував питання з параметрами маршрутизатора, можливо, там потрібні певні зміни.
Саураб

Чи призначений ваш параметр запиту для прокрутки до потрібного місця в документі? Як і ваше інше питання щодо якорних тегів ?
Mani

Ні, я просто хочу додати параметр запиту в URL, я не хочу тут прокрутки.
Саураб

Я просто перевірив параметри в локальній установці, параметри запитів працюють нормально. Я можу перейти до нового маршруту та отримати доступ до параметрів запитів, як показано в моїй оновленій відповіді. Отже, проблема полягає в тому, - ви не хочете, щоб він прокручувався? Або проблема в тому, що весь додаток знову оновлюється?
Mani

тож я перебуваю на одній сторінці, коли я вибираю якийсь вхід, я хочу додати їх у URL-адресу, але коли я це роблю, прокрутка відбувається. Прокрутка - це проблема для мене. Я не намагаюся перейти на іншу сторінку, я просто хочу бути на цій же сторінці і, здавалося б, додавати / змінювати параметри запитів URL-адрес.
Саураб

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 змінився, тому він не відображає URL після pushState.



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

1
Найкраще мені сподобалась ця відповідь. На жаль, це причиниError: Avoided redundant navigation to current location
Макс Коплан

Виправлення:this.$router.push({ query: Object.assign({...this.$route.query}, { new: 'param' }) })
Макс Коплан

2
Але тепер, коли я думаю про це, ви можете просто зробитиthis.$router.push({ query: {...this.$route.query,new: 'param'},) })
Макс Коплан,

3

Якщо ви намагаєтесь зберегти деякі параметри, змінюючи інші, не забудьте скопіювати стан запиту маршрутизатора vue і не використовувати його повторно.

Це працює, оскільки ви створюєте невідредаговану копію:

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

в той час як нижче, це призведе до того, що Vue Router вважає, що ви повторно використовуєте той же запит і призведе до 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-programmatic-append-to-querystring/3655/5 ).

відповідь вище була близькою ... хоча з Object.assign він буде вимкнути це. $ route.query, який не є тим, що ви хочете зробити ... переконайтеся, що перший аргумент є {} під час виконання Object.assign

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

2

Для встановлення / видалення декількох параметрів запитів одразу я закінчив методи, наведені нижче, як частина мого глобального поєднання ( thisвказує на компонент vue):

    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 });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.