[javascript] Vue-Router를 사용하여 Vue에서 URL 쿼리 매개 변수를 설정하는 방법

입력 필드를 변경할 때 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 },
  ]
})



답변

다음은 문서의 예입니다.

// 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>.

샘플 코드에서 누락 된 것일 수 있습니다.

편집 : 주석 후 추가 세부 정보

이 경우 명명 된 경로 를 사용해 보셨습니까 ? 동적 경로가 있으며 매개 변수와 쿼리를 별도로 제공하는 것이 더 쉽습니다.

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.


답변

페이지를 다시로드 하거나 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 Router는 URL이 변경되었음을 알지 못하므로 pushState 이후에 URL을 반영하지 않습니다.


답변

실제로 다음과 같이 쿼리를 푸시 할 수 있습니다. this.$router.push({query: {plan: 'private'}})

기반 : https://github.com/vuejs/vue-router/issues/1631


답변

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


답변

일부 매개 변수는 유지하고 다른 매개 변수는 변경하려는 경우 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으로 테스트되었습니다.


답변

여러 쿼리 매개 변수를 추가하는 경우 이것이 저에게 효과적이었습니다 (여기 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' }) });


답변

한 번에 여러 쿼리 매개 변수를 설정 / 제거하려면 글로벌 믹스 인 ( 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)
    },