简体   繁体   English

通过 Vue Router 传递自定义 JS 对象

[英]Pass Custom JS Object through Vue Router

HELP!帮助! I have been banging my head against the wall for hours on this...几个小时以来,我一直在用头撞墙……

Technologies Being Used :正在使用的技术

  • Vue (v3.0.0) Vue (v3.0.0)
  • Vue-Router (v4.0.0-0) Vue 路由器 (v4.0.0-0)
  • Bootstrap (v5.1.1)引导程序 (v5.1.1)

The Goal目标
I have two pages (Home.vue, MetaUpdate.vue) and one component (Document.vue).我有两个页面(Home.vue、MetaUpdate.vue)和一个组件(Document.vue)。 Home contains several Document components. Home 包含几个 Document 组件。 Upon clicking the "Update" div/button in one of the Document components, we should route to the MetaUpdate page.单击 Document 组件之一中的“更新”div/按钮后,我们应该路由到 MetaUpdate 页面。 The MetaUpdate page needs to hold the whole Doc JS object which is defined below, passed down from the Document component through the router. MetaUpdate 页面需要保存下面定义的整个 Doc JS 对象,从 Document 组件通过路由器传递下来。

The Problem :问题
For some reason, when I pass my custom object as a prop through the router, it's like it doesn't know how to interpret the object and it passes it as the string "[object Object]".出于某种原因,当我通过路由器将我的自定义对象作为道具传递时,它就像不知道如何解释该对象并将其作为字符串“[object Object]”传递。 However, if I pass the custom object as a prop from the parent component to the child component, it interprets it correctly.但是,如果我将自定义对象作为 prop 从父组件传递给子组件,它会正确解释它。 So, how do I actually send props through the router?那么,我实际上如何通过路由器发送道具? It should be noted that I was originally passing two Strings through the router successfully , so I do not understand why when I changed it to pass a custom object, everything broke.需要注意的是,我最初是通过路由器成功传递了两个字符串,所以我不明白为什么当我将其更改为传递自定义对象时,一切都失败了。

JavaScript Object JavaScript 对象

class Doc {
    constructor(docID, title, status) {
        this.docID = docID;
        this.title = title;
        this.status = status;
    }
}

router.js路由器.js

import { createRouter, createWebHashHistory } from 'vue-router'

import Home from '../views/Home.vue'
import MetaUpdate from '../views/MetaUpdate.vue'

import {Doc} from '../controllers/data'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/metaupdate/:doc',
    name: 'MetaUpdate',
    component: MetaUpdate
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes,
})

export default router

Home.vue主页.vue
There is more in the file, but this is all that is necessary for the purpose of answering this question.文件中还有更多内容,但这就是回答这个问题所需的全部内容。

<template>
<div class="col col-12 col-lg-6 in-progress">
    <div class="doc-status">In Progress</div>
        <template v-for="(doc, index) in inProgress" :key="index">
            <Document :doc="doc"></Document>
        </template>
    </div>
</div>
</template>

<script>
import Document from "../components/Document.vue";
import {Doc} from '../controllers/data'
var inProgress = [];
var pending = []
var completed = [];

export default {
    data: function() {
        return {
            inProgress,
            pending,
            completed
        }
    },
    components: {
        Document
    }
}

/***** Temporary Push of Docs *****/
for(let i = 0; i < 5; i++){
    let docA = new Doc(i, 'Progress Document', 'in-progress');
    let docB = new Doc(i, 'Pending Document', 'pending');
    let docC = new Doc(i, 'Completed Document', 'completed');

    inProgress.push(docA);
    pending.push(docB);
    completed.push(docC);
}
/***** Temporary Push of Docs *****/
</script>

Document.vue文档.vue

<template>
    <div class="doc">
        <div class="doc-title">{{ doc.title }}</div>
        <router-link to="/docviewer" v-if="isInProgress" class="doc-item submit">Submit</router-link>
        <router-link to="/docviewer" class="doc-item preview">Preview</router-link>
        <router-link 
            :to="{  name: 'MetaUpdate',
                    params: {doc: this.doc} }" v-if="isUpdateOrDelete" class="doc-item update">Update
        </router-link>
        <router-link to="/docviewer" v-if="isUpdateOrDelete" class="doc-item delete">Delete</router-link>
    </div>
</template>

<script>
import {Doc} from '../controllers/data'

export default {
    props: {
        doc: {
            type: Doc,
            required: true
        }
    },
    computed: {
        isInProgress() {
            return this.doc.status === 'in-progress';
        },
        isUpdateOrDelete() {
            return this.doc.status === 'in-progress' || this.doc.status === 'pending';
        }
    }
}
</script>

MetaUpdate.vue元更新.vue
There is more in the file, but this is all that is necessary for the purpose of answering this question.文件中还有更多内容,但这就是回答这个问题所需的全部内容。

<template>
    <div class="tabs">{{ $route.params.doc.title }}</div>
</template>

<script>
import { Doc } from '../controllers/data'

export default {
    props: {
        doc: {
            type: Doc,
            required: true
        }
    }
}
</script>

You cannot pass an object as a route param.您不能将对象作为路由参数传递。 Route params are strings because the params form part of the URL;路由参数是字符串,因为参数是 URL 的一部分; if you pass a param that isn't a string then it will be converted to a string.如果您传递的参数不是字符串,那么它将被转换为字符串。 What did you expect the URL would be after navigation with the :doc param set to an object?您期望在导航后将:doc参数设置为对象的 URL 是什么?

Instead you should set the doc ID as the param and then the route component that receives that param would lookup the doc object using the ID somehow.相反,您应该将文档 ID 设置为参数,然后接收该参数的路由组件将使用 ID 以某种方式查找文档对象。 How you do this is up to you, perhaps:你如何做到这一点取决于你,也许:

  • Have all docs stored in a global array shared amongst all components (you could use Vuex to do this).将所有文档存储在所有组件共享的全局数组中(您可以使用 Vuex 来执行此操作)。
  • The parent component could pass down to the <router-view> the doc array and then the route component can look up the document by ID in this array.父组件可以向下传递给<router-view> doc 数组,然后路由组件可以通过该数组中的 ID 查找文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM