路由未定义.通过route.push在组件之间传递数据时的参数



我想从主页传递数据。Vueto aclickthrough . Vue.

点击表格中的一条记录时(在首页.vue中)我想被路由到一个新的组件(clickthru.vue)。目标是以两种不同的方式传递两种数据:

:我想传递cve_id作为路由。查询如下所示

/clickthru?cve_id=CVE-xxxx-xxxx

第二:我还想传递一个对象作为参数,以渲染/挂载在clickthrough .vue的html模板上。对象看起来像这样:

{ "cve": "CVE-2022-45869", "severity": "Medium", "packages": [ { "package": "kernel", "version": "5.15.80.1", "owner": "joslobo", "detection_date": "12-03-2022", "BranchStatus": { "1.0": { "sourceBranch": "NULL", "status": "NULL", "detectedOn": "NULL", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "NULL", "qid": [ "NULL" ] }, "2.0": { "sourceBranch": "2.0", "status": "Unpatched", "detectedOn": "12-03-2022", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "11574", "qid": [ "Not Assigned" ] } } }, { "package": "kernel", "version": "5.10.155.1", "owner": "joslobo", "detection_date": "12-03-2022", "BranchStatus": { "1.0": { "sourceBranch": "1.0", "status": "Unpatched", "detectedOn": "12-03-2022", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "11573", "qid": [ "Not Assigned" ] }, "2.0": { "sourceBranch": "NULL", "status": "NULL", "detectedOn": "NULL", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "NULL", "qid": [ "NULL" ] } } } ] }

在我的主页。vue,我遍历记录/对象并以表格式显示,如下所示:Homepage.vue

<tbody>
<template v-for="(cve) in backend_res">
<template v-for="(pack_key, index) in Object.keys(cve.packages)">
<tr>
<td>
<span v-if="index == 0" @click.prevent="onAboutClick(cve.cve, cve.packages)">
{{cve.cve}}
</span>
</td>
</tr>
</template>
</template>
</tbody>
methods: {
onAboutClick(cve_id, cve_obj) {
console.log('----> cve_id = ', cve_id)
console.log('----> cve_obj = ', cve_obj) // cve_obj is successfully printed at this point
this.$router.push(
{
name: 'clickthru',
query: {'cve_id': cve_id},
params: {'cve_obj': cve_obj}
})}

clickthru.vue

<script>
export default {
props: ['cve_id', 'cve_obj'],
data() {
return {
cve_id: this.$route.query.cve_id,
cve_obj: this.$route.params.cve_obj, // cve_obj is undefined 
};
},

main.js

const routes = [
{
path: '/clickthru',
name: 'clickthru',
component: clickthru,
props: true
}
]

如下所示,当记录$route时,查询被成功识别,但是params为空。

{ "fullPath": "/clickthru?cve_id=CVE-2022-45869", "hash": "", "query": { "cve_id": "CVE-2022-45869" }, "name": "clickthru", "path": "/clickthru", "params": {}, "matched": [ { "path": "/clickthru", "name": "clickthru", "meta": {}, "props": { "default": false }, "children": [], "instances": { "default": null }, "leaveGuards": { "Set(0)": [] }, "updateGuards": { "Set(0)": [] }, "enterCallbacks": {}, "components": { "default": { "props": [ "cve_id", "cve_obj" ], "__hmrId": "91ec59e3", "__file": "E:/ASTROLABE_FE/CBL-Mariner-CVE-Website/src/components/clickthru.vue" } } } ], "meta": {}, "href": "/clickthru?cve_id=CVE-2022-45869" }

我希望能够传递cve_obj,而不需要它是url/路径的一部分任何关于如何通过参数,meta或任何其他方式做到这一点的提示都是赞赏的

正如我在评论中提到的,将对象作为查询参数传递不是一种受欢迎的方式,因此有两种方法可以做到这一点-

方法1 -
仅将cve_id传递给新路由,当新路由的页面挂载时,使用此查询参数cve_id从后端获取cve_object。这种方法非常有用,并且推荐使用,因为您将始终拥有来自后端的更新数据。

如果您遵循这种方法,那么需要进行一些更改-

  1. 主页。只传递cve_id到你的新路由-
methods: {
onAboutClick(cve_id) {
this.$router.push({
name: "clickthru",
query: { cve_id: cve_id },
});
},
},
  1. clickthru.vue挂载的钩子上,初始化API调用以获得该id的cve_data-
mounted() {
// Make an API call to fetch the respected id's data
}

方法2 -
当您收到HomePage.vue中的记录(您正在循环)时,将此数据保存到您的Vuex状态。现在,和方法一一样,只传递cve_id到你的新路由,当新路由的页面被挂载时,从Vuex状态获取受尊重的数据,而不是从额外的API调用中获取。

如果你遵循这种方法,那么过程将是这样的-

  1. 当你在主页中得到后端响应时。vue,将其转储为如下状态-
const store = new Vuex.Store({
state: {
records: []
},
mutations: {
SET_RECORDS (state, backend_response) {
// mutate state
state.records = backend_response;
}
}
})
  1. 与方法一相同,您在路由查询中有cve_id,因此使用它从状态中获取受尊重的cve_object。因此,在clickthru.vue挂载上,执行以下操作-
<script>
export default {
data() {
return {
cve_object: null,
};
},
mounted() {
this.cve_object = this.$store.state.records.find(
(item) => item.id == this.$route.query.cve_id,
);
},
};
</script>

通过这种方式,您将拥有处于状态的记录,因此您可以在任何页面上使用查询cve_id找到任何单个记录。

注意:
我只给出了从状态中获取和设置数据的想法。如果您想采用第二种方法,只需阅读Vuex并遵循文档。你也可以在这里查看如何在Vue应用程序中设置Vuex的完整指南。

因为您的目标是在route.push的帮助下将数据发送到新页面后,我忽略了您的代码的某些部分(例如使用您在Homepage.vue中使用的表或v-for)。这是我的代码,我想可以帮助你:

Homepage.vue:

<template>
<div @click="onAboutClick(cveData.cve, cveData.packages)">
some text
</div>
</template>
<script>
export default {
data() {
return {
cveData: { "cve": "CVE-2022-45869", "severity": "Medium", "packages": [ { "package": "kernel", "version": "5.15.80.1", "owner": "joslobo", "detection_date": "12-03-2022", "BranchStatus": { "1.0": { "sourceBranch": "NULL", "status": "NULL", "detectedOn": "NULL", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "NULL", "qid": [ "NULL" ] }, "2.0": { "sourceBranch": "2.0", "status": "Unpatched", "detectedOn": "12-03-2022", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "11574", "qid": [ "Not Assigned" ] } } }, { "package": "kernel", "version": "5.10.155.1", "owner": "joslobo", "detection_date": "12-03-2022", "BranchStatus": { "1.0": { "sourceBranch": "1.0", "status": "Unpatched", "detectedOn": "12-03-2022", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "11573", "qid": [ "Not Assigned" ] }, "2.0": { "sourceBranch": "NULL", "status": "NULL", "detectedOn": "NULL", "patchedOn": "NULL", "firstPatchedPackageRelease": "NULL", "fixReleaseDate": "NULL", "aid": "NULL", "qid": [ "NULL" ] } } } ] }
}
},
methods: {
onAboutClick: function (cve_id, cve_obj) {
console.log('----> cve_id = ', cve_id)
console.log('----> cve_obj = ', cve_obj) // cve_obj is successfully printed at this point
let objData = JSON.stringify(cve_obj);
this.$router.push(
{
name: 'clickthru',
query: {'cve_id': cve_id},
params: {'cve_obj': objData}
}
)
} // end of function
}
}
</script>

clickthru.vue:

<template>
<div>
this is "clickthru" compo
</div>
<section>
{{ cve_id }}
</section>
<section v-for="item in cve_obj">
<div v-for="subItem in item">
{{ subItem }}
</div>
</section>
</template>
<script>
export default {
name: "clickthru",
beforeRouteEnter (to, from, next) {
next(vm => {
console.log(from);
if (from.name == "about") {
/* you must enter the name of your home component instead of "about", I used about page so I entered "about". You can find necessary info by seeing "console.log(from)" in your console. */
vm.cve_obj = JSON.parse(vm.$route.params.cve_obj);
/* We set the data to "localStorage" to retrieve it when the page refreshed on mounted hook. */
localStorage.setItem("cveDataStore" , vm.$route.params.cve_obj);
}
})
},

data() {
return {
cve_id: this.$route.query.cve_id,
cve_obj: JSON.parse('[{"message": "wrong info"}]')
};
},
mounted() {
if (this.cve_obj !== JSON.parse('[{"message": "wrong info"}]')) {
if (localStorage.getItem("cveDataStore")) {
this.cve_obj = JSON.parse(localStorage.getItem("cveDataStore"));
}
}
}
}
</script>

我使用了" beforeouteenter& quot;钩子在clickthru.vue组件,因为根据这个GitHub页面直接传递参数可能会导致一些错误或警告,当页面重新加载。所以我们可以将数据存储在localStorage中,以便在重新加载页面后向用户显示。

根据vue-router文档:

指定参数时,请确保提供字符串或数字(或用于可重复参数的这些数组)。任何其他类型(如未定义、false等)将自动字符串化.

由于您的cve_obj数据类型为"对象",为了确保不会发生问题,我在Homepage.vue中使用JSON.stringify将其转换为字符串。然后在clickthru.vue组件中,我借助计算属性将其转换回对象和JSON.parse方法。

如果您使用这段代码,您将不需要在main.js中使用props: true,因为您不使用props

最新更新