通过router-link访问该链接并通过相同的URL重新加载该链接有什么区别? -Vue-Vue路由器应用

时间:2020-09-14 17:27:37

标签: javascript vue.js vuejs2 vue-router

大家好,

祝你有美好的一天,

我有一个项目,用于将URL与组件上的选择同步。

我将查询对象传递给VueRouter。

VueRouter对该对象进行字符串化并将其用作URL

之后,我可以通过this.$route.query对象获得该对象(Vuerouter会将该URL解析为普通对象)

这是CodeSandbox上的最低版本

enter image description here

我将这些对象传递给Vue路由器: { destinations: ['Hanoi'] } { destinations: ['Hanoi','Da Nang'] } { destinations: ['Ho Chi Minh City'], travelStyle:['Discovery','Adventure'] }

App.vue

<template>
  <div id="app">
    <div class="tour">
      <h2>Which tour?</h2>
      <router-link :to="{ path: 'tours', query: { destinations: ['Hanoi'] } }">Hanoi</router-link>
      <br>
      <router-link
        :to="{ path: 'tours', query: { destinations: ['Hanoi','Da Nang'] } }"
      >Hanoi - Da Nang</router-link>
      <br>
      <router-link
        :to="{ path: 'tours', query: { destinations: ['Ho Chi Minh City'] } }"
      >Ho Chi Minh City</router-link>
      <br>
      <br>
      <span>Route Query: {{this.$route.query}}</span>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

问题是,如果我使用VueRouter的默认parseQuery/StringifyQuery,则URL会很长

tours?destinations=Ho%20Chi%20Minh%20City&travelStyle=Discovery&travelStyle=Adventure

此对象: { destinations: ['Ho Chi Minh City'], travelStyle:['Discovery','Adventure'] }

我按照本主题Custom querystring parser中的说明进行操作,并将qs添加为自定义查询字符串解析器。

使用外部程序包可以让我根据需要控制URL,

此处位于路由器文件中-codesandbox中的完整运行项目

// ...

const router = new VueRouter({
    mode: "history",
    base: "/",
    routes,

    stringifyQuery: (query) => {
        qs.stringify(query, {
            encode: false,
            indices: false,
            arrayFormat: "comma",
            addQueryPrefix: true,
        });
    },

    parseQuery: (query) => {
        console.log("queryString", query);
        const a = qs.parse(query, {
            comma: true,
        });
        console.log("after parse:", a);
        return a;
    },

});

现在,在数组中使用逗号时,URL相当短。

tours?destinations=Hanoi tours?destinations=Hanoi,Da%20Nang tours?destinations=Ho%20Chi%20Minh%20City&travelStyle=Discovery,Adventure

但是另一个问题出现了:Stringify with comma format should add square brackets to parameter name to identity array with single value

因为使用逗号分隔数组中的每个元素,所以我们不知道destinations=Hanoi的意思是{ "destinations": [ "Hanoi" ] }{ "destinations": "Hanoi" }

**当我单击指向路由器链接到URL tours?destinations=Hanoi时,我得到了{ "destinations": [ "Hanoi" ] }(正确)

enter image description here

但是如果我重新加载该URL,我会得到{ "destinations": "Hanoi" }(错误)**

enter image description here

他们从that issues开始说,我们可以在数组的键的末尾添加带有单个值的方括号,以获取所需的内容。

des[]=hanoi > { des: [ 'hanoi' ] }

des=hanoi,hai phong > { des: [ 'hanoi', 'hai phong' ] }

这是我在repl.it上的测试文件


const  qs = require('qs');


const stringifyQuery = (query) => {
   Object.keys(query).forEach((item) => {

      if(Array.isArray(query[item])&&query[item].length===1) {

          query[item+'[]'] = query[item]; 
          delete query[item];
      }
  });


  return qs.stringify(query, {
      encode: false,
      indices: false,
      arrayFormat: 'comma',

  });
};

let parseQuery = (query) =>
    qs.parse(query, {
      comma: true,
    });


const a = {des: ['hanoi']};

const b = {des: ['hanoi','hai phong']};


console.log(stringifyQuery(a)); // des[]=hanoi
console.log(stringifyQuery(b)); // des=hanoi,hai phong
console.log(parseQuery(stringifyQuery(a))); // { des: [ 'hanoi' ] }
console.log(parseQuery(stringifyQuery(b))); // { des: [ 'hanoi', 'hai phong' ] }

一切正常!

但是当我在vue-router上使用它时,就不会了。

再一次,在单击到路由器链接和重新加载相同的URL之间,将显示不同的结果!

对于此URL tours?destinations[]=Hanoi

如果我通过路由器链接单击,它仍然得到{ "destinations[]": [ "Hanoi" ] }而不是"destinations": [ "Hanoi" ]

enter image description here

但是,如果我重新加载页面,则会得到正确的页面:{ "destinations": [ "Hanoi" ] }

enter image description here

我试图弄清楚发生了什么,但是作为一个新手,这对我来说是很感动的

有人在这个问题上有什么主意或关键词吗?

非常感谢您抽出宝贵的时间阅读我冗长的问题,

对我来说意义重大,我真的很感激!

1 个答案:

答案 0 :(得分:0)

我得到了答案,

在我的自定义StringifyQuery中,我对查询对象进行了变异,以在其中添加方括号键(destinations[]: Hanoi)

然后,路由器仍然使用该对象并在下一条路径中显示

这就是为什么当我console.log this.$route.query显示编辑后的查询(destinations[]: Hanoi)

时的原因

要解决此问题,我必须避免更改查询对象,仅此而已

CodeSandbox中的完整代码

stringifyQuery: (query) => {
        const queryClone = { ...query };

        Object.keys(queryClone).forEach((item) => {
            if (
                Array.isArray(queryClone[item]) &&
                queryClone[item].length === 1 &&
                !item.includes("[]")
            ) {
                queryClone[`${item}[]`] = queryClone[item];
                delete queryClone[item];
            }
        });

        return qs.stringify(queryClone, {
            encode: false,
            indices: false,
            arrayFormat: "comma",
            addQueryPrefix: true,
        });
    },

我的课程:切勿与外部对象混淆,我们必须对其进行克隆(基于上下文的深浅或阴影)并在克隆版本中对其进行编辑