首页 > 解决方案 > 通过 router-link 访问链接并通过相同的 URL 重新加载它有什么区别?- Vue - Vue 路由器应用程序

问题描述

大家好,

祝你今天过得愉快,

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

我将查询对象传递给 VueRouter。

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

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

这是CodeSandbox上的最小版本

在此处输入图像描述

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

应用程序.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>

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

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

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

我按照本主题自定义查询字符串解析器中的说明添加qs作为自定义查询字符串解析器。

并且使用外部包允许我根据需要控制 URL,

这是路由器文件内部 - 在代码沙箱中完整运行的项目

// ...

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 commaformat 应该将方括号添加到参数名称到具有单个值的标识数组

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

tours?destinations=Hanoi**当我点击路由器链接到我得到的 URL { "destinations": [ "Hanoi" ] }(正确)

在此处输入图像描述

但是如果我重新加载那个我得到的 URL { "destinations": "Hanoi" }(错误)**

在此处输入图像描述

那个问题开始,他们说我们可以在一个数组的键末尾添加括号,以获得我们想要的结果。

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 之间显示不同的结果!

对于这个网址tours?destinations[]=Hanoi

如果我点击路由器链接,它仍然会 { "destinations[]": [ "Hanoi" ] }得到"destinations": [ "Hanoi" ]

在此处输入图像描述

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

在此处输入图像描述

我试图弄清楚发生了什么,但这对我这个新手来说很感人,

有人对这个问题有任何想法或关键字吗?

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

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

标签: javascriptvue.jsvuejs2vue-router

解决方案


我得到了答案,

在我的自定义 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,
        });
    },

我的教训:永远不要弄乱外部对象,我们必须克隆它(基于上下文的深度或阴影)并在克隆版本中对其进行编辑


推荐阅读