route.params is not defined when passing data between components via route.push
P粉022285768
2023-09-01 19:17:09
<p>I want to pass data from <em>Homepage.vue</em> to <em>clickthru.vue</em>. </p>
<p>Click a record in the table (in Homepage.vue)
I want to route to a new component (clickthru.vue).
The goal is to pass two types of data in two different ways: </p>
<p><strong>First: </strong>I want to pass <em>cve_id</em> as route.query like this</p>
<pre class="brush:php;toolbar:false;">/clickthru?cve_id=CVE-xxxx-xxxx</pre>
<p><strong>Second: </strong> I also want to pass an object as a parameter to render/install on the html template of clickthru.vue.该对象看起来像这样:</p>
<pre class="brush:php;toolbar:false;">{ "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" ] } } } ] }</pre>
<p>In my <em>homepage.vue</em>, I iterate over the records/objects and display them in table format like this:
<strong>Homepage.vue</strong></p>
<pre class="brush:php;toolbar:false;"><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></pre>
<pre class="brush:php;toolbar:false;">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}
})}</pre>
<p><strong>clickthru.vue</strong></p>
<pre class="brush:php;toolbar:false;"><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
};
},</pre>
<p><strong>main.js</strong></p>
<pre class="brush:php;toolbar:false;">const routes = [
{
path: '/clickthru',
name: 'clickthru',
component: clickthru,
props: true
}
]</pre>
<p>As shown below, when <em>$route</em> is logged, the query is successfully recognized, however, the params are empty.</p>
<pre class="brush:php;toolbar:false;">{ "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" }</pre>
<p>我希望能够传递 cve_obj 而不是 url/path 的一部分
任何关于如何通过参数、元或任何其他方式做到这一点的提示都值得赞赏</p>
As I mentioned in the comments, passing objects as query parameters is not a popular way, so there are two ways to do it -
method 1-
Pass only the
cve_id
to the new route and when installing the new route's page, use this query parametercve_id
to get thecve_object
from the backend. This approach is useful and recommended because you always get updated data from the backend.If you follow this approach, there are a few changes that need to be made -
cve_id
to your new route -clickthru.vue
installed hook, initialize the API call to get thecve_data
-Method 2-
When you receive a record in
HomePage.vue
(the one you are looping over), save this data to your Vuex state. Now, same as method one, just pass thecve_id
to the new route and get it from the Vuex state when the new route's page is installed, rather than from an additional API call.If you follow this approach, the process will be like this -
cve_id
in your route query, so you can use it to get the relevantcve_object
from the state. So after installingclickthru.vue
do the following -This way you will have your records in that state, so you can use the query
cve_id
on any page to find any single record.Notice-
I only give the idea of getting and setting data from state. If you want to take the second approach, just read Vuex and follow the documentation. You can also check out the complete guide here How to setup Vuex in a Vue application.