'Vue route query parameters are not updated in the browser URL

I have a Vue component named ComponentSearch, It is used to search.

<template>
  <div class="cs">
    <div>
      <el-input
        placeholder="search"
        prefix-icon="el-icon-search"
        v-model="keyword"
        @change="search">
      </el-input>
    </div>
  </div>
</template>
<script>
export default {
  name:'ComponentSearch',
  data() {
    return {
      keyword: ''
    }
  },
  methods: {
    search() {
      if (this.$route.path !== '/component/search') {
        // this means jumping over from other pages via the search component, not within the search page
        this.$router.push({
          path: '/component/search',
          query: {
            keyword: this.keyword
          }
        })
      } else {
        // this means that searching through the search page
        this.$router.replace({
          query: {
            keyword: this.keyword
          }
        })
      }
    }
  }
}
</script>

Here is my search page.

<template>
  <div id="search">
    <-- this is the search component -->
    <ComponentSearch></ComponentSearch>
    <div id="container">
      <-- display the data from this.list -->
    </div>
  </div>
</template>
<script>
import ComponentSearch from '@/components/ComponentSearch.vue'
export default {
  components: {
    ComponentSearch
  },
  data() {
    return {
      list: []
    }
  },
  methods: {
    /**
      * request data from the backend based on keywords
      * @param {String} keyword Search keywords
      * @param {Number} index Current page number, default 1
      * @param {Number} size Size per page, default 10
      */
    getComponentListByKeyword(keyword, index = 1, size = 10) {

    }

  },
  // access to http://localhost:3000/component/search from other routes
  // from.$route.path !== '/component/search'
  beforeRouteEnter(to, from, next) {
    console.log('before route enter...');
    console.log(to);
    console.log(from);
    let keyword = to.query.keyword
    if (keyword) {
      // access search page from other pages via the search component, keyword is assigned
      next(vm => {
        vm.getComponentListByKeyword(keyword)
      })
    } else {
      // enter the search page http://localhost:8080/component/search directly from the browser by typing the url
      next()
    }
  },
  // search page routing update
  beforeRouteUpdate(to, from) {
    console.log('before route update...');
    console.log(to);
    console.log(from);
    this.getComponentListByKeyword(to.query.keyword)
  }
}
</script>

Here's how I do it.

I entered the search parameter x from the page http://localhost:8080/component through the search component and it worked fine and jumped to the search page.

http://localhost:8080/component is any page different from the search page, its url may be

http://localhost:8080/a,

http://localhost:8080/b,

or http://localhost:8080/c,

but It can never be http://localhost:8080/component/search.

These pages all contain a search component, ComponentSearch, and their structure is probably something like this

<template>
  <div id="uniqueID">
    <ComponentSearch></ComponentSearch>
    <div>
      <-- other html tags-->
    <div>
  </div>
</template>
<script>
import ComponentSearch from "@/components/ComponentSearch.vue"
export default {
  components: {
    ComponentSearch
  },
  data() {
    return { }
  }
</script>

The browser url now shows http://localhost:8080/component/search?keyword=x

Here are some console output messages.

//before route enter...
// from
{
  fullPath: "/component"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "Component"
  params: {}
  path: "/component"
  query: {}
}
// to
{
  fullPath: "/component/search?keyword=x"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "ComponentSearch"
  params: {}
  path: "/component/search"
  query: {keyword: 'x'}
}

Then I entered the keyword y through the search component on the search page and it worked fine.

But now the browser url still shows http://localhost:8080/component/search?keyword=x

While the console outputs

//before route update...
// from
{
  fullPath: "/component/search?keyword=x"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "ComponentSearch"
  params: {}
  path: "/component/search"
  query: {keyword: 'x'}
}
// to
{
  fullPath: "/component/search?keyword=y"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "ComponentSearch"
  params: {}
  path: "/component/search"
  query: {keyword: 'y'}
}

Question, why does the browser url not replace the value of the parameter keyword x with y.

When I type http://localhost:8080/component/search directly into the browser and then query the data through the search component, it works fine but the browser url still shows http://localhost:8080/component/search, without splicing in the ?keyword=

Console output when entering URL http://localhost:8080/component/search directly from the browser:

//before route enter...
// from
{
  fullPath: "/"
  hash: ""
  matched: [{…}]
  meta: {}
  name: null
  params: {}
  path: "/"
  query: {}
}
// to
{
  fullPath: "/component/search"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "ComponentSearch"
  params: {}
  path: "/component/search"
  query: {}
}

After typing the URL directly and querying with the keyword z, the console output:

//before route update...
// from
{
  fullPath: "/component/search"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "ComponentSearch"
  params: {}
  path: "/component/search"
  query: {}
}
// to
{
  fullPath: "/component/search?keyword=z"
  hash: ""
  matched: [{…}]
  meta: {}
  name: "ComponentSearch"
  params: {}
  path: "/component/search"
  query: {keyword: 'z'}
}

The browser URL still shows http://localhost:8080/component/search, which does not splice ?keyword=z to the browser URL.

But they are able to query the data normally, it's just that the URL on the browser never changes.

Also, I have set the corresponding page in the routing file.

I have also tried using $route.params.xxx, which has the same error as $route.query.xxx.

  {
    // path: '/component/search/:keyword',
    path: '/component/search',
    name: 'ComponentSearch',
    component: () => import('../views/component/search.vue'),
  },


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source