vue3不能使用history.pushState修改url参数踩坑

目录
  • 前言
  • 问题
  • 追根溯源
  • 解决

前言

在重构我的 vue-use-sync-url(辅助将数据和 url 参数进行同步的工具库)时,遇到了一个使用 window.history.pushState 来修改地址栏的 url 参数的 bug,准确来说是 vue-router 的 bug,下面就来讲讲具体是怎么回事。

问题

场景如下,有一个输入框里面输入了内容,点击搜索按钮使用 window.history.pushState 将数据同步到 url 参数上。然后再点击 go about 按钮跳转到别的页面,关键的来了,这时候你点击浏览器左上角的回退按钮回到刚才的页面,url 上的 keywords 参数变没了! 这里上个测试链接 codesandbox

<script setup>
import { ref } from "vue";
const keywords = ref("123")
const handleClick = () => {
  window.history.pushState({}, "", `${window.location.pathname}?keywords=${keywords.value}`)
}
</script>
<template>
  <input v-model="keywords" />
  <button @click="handleClick">搜索</button>
  <router-link to="/about">go about</router-link>
</template>

追根溯源

一开始想是不是我写的有问题?测试了 vue2-routerreact-router 都没有这个问题,所以我就将问题锁定在了 vue3-router 了。因为 router-link 和直接执行了 router.push 操作是一样的,所以我就去找 push 操作所在的源码位置,最终在 packages/router/src/history/html5.ts 中找到了如下代码。

可以看到在这个 push 函数中,在第 288 行,执行了一次 replace 的操作,而在第 297 行才是真正的 push 操作。我将第 288 行注释之后,上面的 demo 就跑通了,但是直觉告诉我它这里这么做是有原因的,但是想弄明白估计得将整个库的源码看完,没有这个精力。直接提了个 issue,在它的 github issue 中我发现了好几个由于这个第 288 行代码产生的问题,例如 #1416#1526#1529。维护者在我的 issue 中是这么回答的。

结合他在其它 issue 中的回答,大概是如下这么个意思。直接使用 history api,路由器是不知道的,应该避免使用,最好使用 router.push 来进行更改。还说到第 288 行对于更新当前历史记录条目是必要的,以便能够通过导航守卫取消ui 发起的导航。它允许知道导航的方向和在历史堆栈中的相对位置。不幸的是,目前还没有其他方法可以做到这一点。

我补充道,在 vue2react 中没有这个问题,你不觉得这是个 bug 吗?他说在 vue2 中使用 hisotry api 可能会产生你没有遇到过的问题,vue-routervue3 中比 vue2 拥有更多的功能等等。

解决

没办法,维护者不觉得这是个 bug,最后只能妥协使用 router.push 来解决,并将 vue-router 的依赖添加到 peerDependencies 中。在一些场景下,如果想封装一个库在各个框架中共同使用就不行了,在这里必须使用 router.push 才可以,我觉得还是不太好的。

以上就是vue3不能使用history.pushState修改url参数踩坑的详细内容,更多关于vue3修改url参数踩坑的资料请关注我们其它相关文章!

(0)

相关推荐

  • Storybook 7.0 Beta Vue3踩坑解决记录

    目录 故事背景 坑一: 坑二: 坑三: 总结 故事背景 基于 Vue + Vite + TS 结合 pnpm 的一个 monorepo 项目的组件库文档编写,起初个人是比较倾向于直接使用全家桶系列的 VitePress.无奈公司中其他库文档均使用 Storybook,并且已经升级到最新版本. 好吧,到这里就基本知道了自己要做什么了. 由于之前也没有接触过这个玩意儿,就去看着官网一步步操作去了.坑也就在这里了,谁知道版本上去了,文档却没有做出相应的调整.然后就有了后续一系列的问题.Storyboo

  • 示例解析java设计模式七大原则接口隔离原则及优化

    目录 1.什么是接口隔离原则? 2.对应代码 3.改进代码 4.接口隔离原则总结 1.什么是接口隔离原则? 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口范围上. 2.对应代码 上面这张图呢,就违反了接口隔离原则.它对应的代码如下: package com.szh.principle.segregation; /** * */ interface Interface1 { void operation1(); void operation2(); void oper

  • 编程开发中99%的研发者都踩过的误区

    目录 01 02 03 04 05 06 07 08 意识不到误区的存在最为离谱: 01 生活中,职场上,游戏里,都少不了正面对喷过:意识太差: 在个人的认知中意识即思维,意识太差即思维中存在的误区比较多: 每个人或多或少都存在思维上的误区: 思维影响行为: 行为效应会带来很多显而易见的问题: 问题多了自然就是各种鸡飞狗跳: 思维误区作为成长的第一大阻力,认清误区并尽快走出,直接决定成长的速度: 误区最妖娆的地方,在于会让人有自我认同的决心,坚定的相信自己思维的正确性: 想要快速的走出误区,就要

  • Android界面一键变灰开发深色适配模式编程示例

    目录 深色主题工具类 background_color公用背景色 values/colors.xml 的代码 values-night/colors.xml 的代码 Android 界面一键变灰 java kotlin 深色主题工具类 package com.example.kotlindemo.utils import android.content.Context import android.content.res.Configuration import androidx.appcomp

  • iOS schem与Universal Link 调试时踩坑解决记录

    目录 简介 AppDelegate和SceneDelegate 问题:在iOS13以上冷启动的时候不会走代理函数! 如果你用了Scheme方式: iOS13之前会走这个代理函数 iOS13之后会走 如果你用了Universal Link方式: iOS13之前会走这个代理函数 iOS13之后会走 总结 简介 scheme和Universal Link是在iOS中两种可以在网页中点击回跳到自己预定的APP的两种方式.至于这两种方式需要怎么配置,这里就不做详细的介绍了.网上的文章一搜一大堆.今天主要是

  • vue3不能使用history.pushState修改url参数踩坑

    目录 前言 问题 追根溯源 解决 前言 在重构我的 vue-use-sync-url(辅助将数据和 url 参数进行同步的工具库)时,遇到了一个使用 window.history.pushState 来修改地址栏的 url 参数的 bug,准确来说是 vue-router 的 bug,下面就来讲讲具体是怎么回事. 问题 场景如下,有一个输入框里面输入了内容,点击搜索按钮使用 window.history.pushState 将数据同步到 url 参数上.然后再点击 go about 按钮跳转到别

  • Spring数据库连接池url参数踩坑及解决

    目录 Spring数据库连接池url参数踩坑 遇到的问题 报错情况 解决 修改数据库连接池的url后,还是连接原先的url 问题 例如 Spring数据库连接池url参数踩坑 遇到的问题 报错情况 解决 & ' 字符在xml需要转义为 ' & ' 修改数据库连接池的url后,还是连接原先的url 问题 当修改连接池url之后,访问的还是原来的数据库. 例如 原来: url=jdbc:mysql://192.168.250.227:3306/myshop?characterEncoding=

  • vue2.x background:url()的踩坑记录

    目录 background:url()的踩坑记录 backgroundImage路径问题 处理方法 background:url()的踩坑记录 开发模式下vue中background: url(‘../../assets/img/xxxxx’)直接写在行间样式不生效,即不能直接在标签中style属性中写, 必须写在非行间样式才会生效. 如果要写在行间样式中,需要对资源进行导入,比如ES规范的import或者CommomJS规范的require backgroundImage路径问题 项目中图片都

  • JS 修改URL参数(实现代码)

    复制代码 代码如下: function changeURLPar(url, ref, value) {    var str = "";    if (url.indexOf('?') != -1)        str = url.substr(url.indexOf('?') + 1);    else        return url + "?" + ref + "=" + value;    var returnurl = "

  • 如何通过zuul添加或修改请求参数

    zuul添加或修改请求参数 一.为什么要用到这个 在基于 springcloud 构建的微服务系统中,通常使用网关zuul来进行一些用户验证等过滤的操作,比如 用户在 header 或者 url 参数中存放了 token ,网关层需要 用该 token 查出用户 的 userId ,并存放于 request 中,以便后续微服务可以直接使用而避免再去用 token 查询. 二.基础知识 在 zuul 中最大的用法的除了路由之外,就是过滤器了,自定义过滤器需实现接口 ZuulFilter ,在 ru

  • 使用ajax和history.pushState无刷新改变页面URL示例

    表现 如果你使用chrome或者firefox等浏览器访问本博客.github.com.plus.google.com等网站时,细心的你会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发生了了改变.并且能够很好的支持浏览器前进和后退. 是什么有这么强大的功能呢? HTML5里引用了新的API,history.pushState和history.replaceState,就是通过这个接口做到无刷新改变页面URL的. 与传统的AJAX的区别 传统的ajax有如下的问题: 1.可以无刷新

  • python url 参数修改方法

    基于python 3.5,python 2.7 与python3.4 的urllib不同,是urlparse >>> from urllib import parse >>> url = 'http://www.baidu.com/s?wd=codeif.com&spt=1' >>> bits = list(parse.urlparse(url)) >>> bits ['http', 'www.baidu.com', '/s'

  • Vue Router修改query参数url参数没有变化问题及解决

    目录 Router修改query参数url参数没有变化问题 正常情况下 就可以修改了 vueRouter不切换url只修改query报错 解决方案 Router修改query参数url参数没有变化问题 正常情况下 this.$router.push({ query:{} }) this.$router.replace({ query:{} }) 就可以修改了 但是当已有query对象里面修改其中一个值,就会发现虽然this.$route.query发生改变但是浏览器的url上的参数并没有发生变化

  • js修改地址栏URL参数解决url参数问题

    现在做网页,经常会碰到处理地址栏参数的问题,但一直是凭感觉做,之后漏洞百出也不知道从哪改起,因此,就专门做了一个修改地址栏参数的方法,这一下,就再也不用愁啦,哈哈! 以下就是我编的方法,使用很简单的哦: 复制代码 代码如下: function changeURLPar(destiny, par, par_value) { var pattern = par+'=([^&]*)'; var replaceText = par+'='+par_value; if (destiny.match(pat

  • vue如何动态修改$router参数

    目录 vue动态修改$router参数 动态修改router路由所带参数 vue动态修改$router参数 // 创建一个包含当前 URL 参数的对象 export const getURLParameters = (url) =>   (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(     (a, v) => (       (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf

随机推荐