路由传值的几种方式
- query 传值(通过 URL 参数传递)
- 原理
- 当在 Web 应用中进行页面跳转并需要传递数据时,query 传值方式利用了 URL 的查询字符串部分。URL 的基本结构包括协议(如 http:// 或 https://)、主机名、路径以及可选的查询字符串。查询字符串以 “?” 开头,后面跟着一系列的键值对,键值对之间用 “&” 分隔,例如 “?key1=value1&key2=value2”。这种方式本质上是将数据作为 URL 的一部分进行传递,浏览器在请求目标页面时,会将整个带有查询字符串的 URL 发送给服务器或者在单页面应用(SPA)中由前端路由进行解析。
- 从技术实现角度看,浏览器的 HTTP 请求机制或者前端路由库会解析这个 URL,将查询字符串部分提取出来,并把键值对转换为可以在目标页面使用的数据结构。以 JavaScript 为例,在浏览器环境中,可以通过
window.location.search
获取查询字符串部分,然后通过一些简单的字符串处理或者使用专门的库(如qs
库)来解析出参数值。
- 使用方法(以 Vue Router 为例)
- 发送端(源页面)
- Vue Router 提供了
$router.push
方法来进行编程式路由跳转。在这个方法中,可以通过设置query
对象来添加查询参数。例如,假设在一个 Vue 组件中有一个按钮,点击按钮后跳转到名为UserDetail
的路由并传递userID
参数:
- Vue Router 提供了
- 发送端(源页面)
- 原理
// 假设这是一个Vue组件中的方法
methods: {
goToUserDetail() {
this.$router.push({
path: '/UserDetail',
query: {
userID: 123
}
});
}
}
- 在这里,
path
属性指定了要跳转的路由路径,query
属性是一个对象,其中的键值对就是要传递的查询参数。这个方法会触发路由的跳转,并且浏览器的 URL 会变为类似于 “/UserDetail?userID=123” 的形式。 - 接收端(目标页面)
- 在目标页面的 Vue 组件中,可以通过
$route.query
对象来获取传递过来的参数。$route
是 Vue Router 注入到每个组件中的路由对象,query
是其中一个属性,它包含了所有通过查询字符串传递过来的参数。例如:
- 在目标页面的 Vue 组件中,可以通过
export default {
mounted() {
// 获取传递过来的userID参数
let userID = this.$route.query.userID;
console.log(userID);
}
}
- 当组件挂载(
mounted
生命周期钩子)时,就可以获取到传递过来的参数,并进行相应的操作,如根据userID
从服务器获取用户详细信息并在页面上展示。 - 优点
- 简单易用:对于初学者来说,这种方式是最容易理解和上手的。它的语法简单,只需要在路由跳转时添加一个
query
对象即可传递参数。无论是简单的数值、字符串还是多个参数组合,都可以很方便地传递。 - 利于分享和书签功能:由于参数是直接在 URL 中显示的,用户可以很方便地复制链接并分享给其他人。接收者通过查看 URL 就能知道传递了哪些参数,并且如果将这个 URL 添加为书签,下次访问时依然能够正确地传递参数并加载相应的内容。这对于一些需要分享特定状态的页面(如商品详情页、文章详情页)非常有用。
- 与服务器端渲染(SSR)兼容性好:在服务器端渲染的应用中,查询字符串是一种常见的传递参数方式。服务器可以根据 URL 中的查询字符串来获取参数,生成相应的 HTML 页面并返回给客户端。这种方式使得前后端在参数传递上保持一致,便于开发和维护。
- 简单易用:对于初学者来说,这种方式是最容易理解和上手的。它的语法简单,只需要在路由跳转时添加一个
- 缺点
- 安全性问题:因为参数直接暴露在 URL 中,任何人都可以看到。所以不适合传递敏感信息,如用户密码、信用卡信息、加密密钥等。如果这些信息被恶意获取,可能会导致安全漏洞。
- URL 冗长和维护性差:当需要传递复杂的数据结构或者多个参数时,URL 会变得很长,不仅影响美观,还可能会超出浏览器或者服务器对 URL 长度的限制。而且,过多的参数会使 URL 难以阅读和维护,对于后期的调试和修改也会带来不便。
- params 传值(通过路由参数传递)
- 原理
- params 传值方式是将参数嵌入到路由路径本身。在定义路由时,会在路径中设置参数占位符,这些占位符表示在路由匹配时需要动态替换的部分。例如,一个路由定义为 “/user/:userID”,其中 “:userID” 就是一个参数占位符。当进行路由跳转时,实际的参数值会替换这个占位符,形成一个完整的、具体的路由路径,如 “/user/123”。
- 从路由匹配的角度看,前端路由库(如 Vue Router)会根据定义的路由路径模式来匹配当前的 URL。当一个 URL 符合某个带有参数的路由定义时,路由库会提取出参数的值,并将其提供给目标组件使用。这种方式使得参数成为了路由路径的内在组成部分,而不是像查询字符串那样是附加的部分。
- 使用方法(以 Vue Router 为例)
- 发送端(源页面)
- 同样使用
$router.push
方法进行路由跳转,但传递参数的方式略有不同。对于 params 传值,直接将参数值添加到路由路径中。例如:
- 同样使用
- 发送端(源页面)
- 原理
// 假设路由定义为'/user/:userID',传递userID参数
this.$router.push('/user/123');
- 这里的 “123” 就是要传递的
userID
参数值,它直接替换了路由定义中的 “:userID” 占位符。需要注意的是,这种方式要求在定义路由时就明确参数的位置和名称,并且在跳转时按照正确的顺序和格式提供参数。 - 接收端(目标页面)
- 在目标页面的组件中,通过
$route.params
对象来获取参数。例如:
- 在目标页面的组件中,通过
export default {
mounted() {
// 获取传递过来的userID参数
let userID = this.$route.params.userID;
console.log(userID);
}
}
$route.params
是一个对象,其中的属性名与路由定义中的参数占位符名称相对应,属性值就是传递过来的参数值。通过这种方式,组件可以获取到参数并进行相应的处理。- 优点
- 语义性强:这种方式使得路由路径更具语义性,符合 RESTful 风格的设计理念。参数作为路径的一部分,看起来更像是资源的一个标识或者属性。例如,“/user/123” 看起来就像是在访问用户资源中 ID 为 123 的用户,更加直观自然,有助于提高代码的可读性和可维护性。
- 简洁性:对于一些固定结构的参数传递,如根据某个实体的唯一标识来访问详情页面,params 传值方式非常简洁明了。不需要像查询字符串那样添加额外的 “?” 和键值对的格式,使路由路径更加简洁。
- 缺点
- 灵活性差:由于参数是路由路径的一部分,所以在路由定义时就需要确定参数的位置和名称。如果在后期需要添加或修改参数,可能需要对路由的定义进行修改,这可能会影响到多个相关的组件和路由跳转逻辑。
- 不便于手动修改和动态参数传递:与 query 传值相比,用户很难手动修改 params 参数(因为参数是路径的一部分,修改可能导致路由无法匹配)。而且这种方式不太适合传递可选的、动态变化的参数。例如,如果一个参数可能有也可能没有,使用 params 传值就需要在路由定义和跳转逻辑上进行额外的处理来适应这种情况。
- state 传值(通过历史记录状态传递)
- 原理
- state 传值利用了浏览器历史记录的状态对象。浏览器的历史记录(
window.history
)除了记录访问过的页面 URL 外,还可以存储一个状态对象。这个状态对象不会在 URL 中显示,是一种在 JavaScript 层面进行数据传递的方式。当使用history.pushState
或history.replaceState
方法进行路由跳转时,可以将数据存储在这个状态对象中。 - 从数据存储和访问的角度看,这些方法会改变浏览器的历史记录状态,将新的状态对象添加到历史记录栈中或者替换当前的状态对象。当用户通过浏览器的前进、后退按钮或者在 JavaScript 中访问历史记录时,可以获取到这个状态对象。这种方式提供了一种隐藏数据的机制,使得数据的传递更加隐蔽。
- state 传值利用了浏览器历史记录的状态对象。浏览器的历史记录(
- 使用方法(以 HTML5 History API 为例)
- 发送端(源页面)
- 使用
history.pushState
方法来进行路由跳转并传递参数。首先需要创建一个包含要传递数据的状态对象,然后将这个对象作为参数传递给pushState
方法。例如:
- 使用
- 发送端(源页面)
- 原理
// 创建一个状态对象,包含要传递的数据
let state = {
userInfo: {
name: 'John',
age: 30
}
};
// 进行路由跳转,同时传递状态数据
history.pushState(state, '', '/targetPage');
- 在这里,第一个参数是要传递的状态对象,第二个参数是一个标题(目前大多数浏览器忽略这个标题),第三个参数是要跳转的目标页面路径。通过这种方式,数据就被存储在历史记录的状态中,并且浏览器会跳转到目标页面。
- 接收端(目标页面)
- 可以通过监听
popstate
事件来获取传递过来的数据。popstate
事件在浏览器的历史记录发生变化时触发,例如用户点击了前进或后退按钮。在事件处理函数中,可以通过event.state
来获取存储在历史记录状态中的数据。例如:
- 可以通过监听
window.addEventListener('popstate', function (event) {
// 获取传递过来的userInfo数据
let userInfo = event.state.userInfo;
console.log(userInfo);
});
- 这样,当历史记录状态发生变化时,就可以获取到之前传递的数据并进行相应的操作。需要注意的是,在页面加载时,不会自动触发
popstate
事件,所以如果需要在页面加载时就获取数据,可能需要额外的处理(如检查历史记录状态是否已经有数据)。 - 优点
- 安全性高:由于数据不会显示在 URL 中,所以可以安全地传递敏感信息,如用户的登录状态、权限信息、隐私数据等。这对于一些需要保护用户数据安全的应用场景非常重要,例如金融应用、企业内部系统等。
- 数据结构灵活:可以传递复杂的数据结构,不受 URL 长度和格式的限制。无论是对象、数组还是其他复杂的数据类型,都可以直接存储在状态对象中进行传递。这使得在传递大量数据或者复杂的数据关系时更加方便。
- 缺点
- 兼容性问题:这种方式依赖于 HTML5 History API,在一些旧版本的浏览器(如 IE9 及以下)中可能不支持。在开发应用时,需要考虑到浏览器的兼容性问题,可能需要提供备用的参数传递方式或者进行浏览器版本检测和适配。
- 数据持久性和复杂性:数据的传递和获取相对复杂,需要对历史记录的状态管理有一定的了解。而且,在页面刷新后,状态数据可能会丢失(除非采取额外的措施来保存数据,如使用本地存储或者将数据发送到服务器进行保存)。这对于一些需要在页面刷新后仍然保留数据的应用场景来说是一个挑战。
原文地址:https://blog.csdn.net/aaaa_1111111/article/details/144407447
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!