问题描述
版本:
VueJS: 3.x
Chrome: Version 93.0.4577.63 (Official Build) (x86_64)
macOS: Big Sur 11.5.2
我的用例必须是常见的,我对它不能开箱即用感到有点惊讶。
我有以下简单的路线:
/patients/new
/patients/1
/about
我通过vueJSrouter-link
s:
<router-link to="/about">About</router-link> |
<router-link to="/patients/new">New Patient</router-link> |
<router-link to="/patients/1">Update Patient</router-link>
/patients/1
返回一个预先填充的HTML表单,其中包含ID为1
的患者的详细信息。
/patients/new
返回相同的具有空白条目的HTML表单。
直观地说,如果我先访问/patients/1
链接,然后再访问/patients/new
,我会认为HTML表单是空的;相反,如果我先访问/patients/new
,然后再访问/patients/1
,我会希望相应地预先填充HTML表单。
这不是发生的事情。相反,SPA不会重新创建/重新装载该HTML表单。
解决方案:许多文章建议在HTML表单中使用由:key
属性引用的反应变量。然后,无论我们访问哪个链接,只要我们更改了反应变量,就应该重新创建/重新挂载包含该HTML表单的vueJS组件。
我的方法是:provide
根组件上的一个反应变量,inject
它在呈现HTML表单的vueJS组件(即这里的Patient
组件)中。
我的根组件如下所示:
<script lang="ts">
import { defineComponent } from 'vue'
import Vue from 'vue'
export default defineComponent({
name: "App",
provide() {
return {
routePath: Vue.computed(() => this.$route.path)
}
}
});
</script>
其中反应变量为routePath
。然后,在Patient
组件中,我有以下内容:
export default defineComponent({
name: "Patient",
inject: ['routePath'],
...
});
使用:key
属性定义的HTML表单如下:
<template>
<form :key="routePath">
...
</form>
</template>
我认为这里的基本想法是合理的,但它不起作用,而且它确实看起来像是一种笨拙的方法。
所以,以下是我的问题:
这种方法合理吗? 为什么Vue.computed()
调用中断?以下是Chrome控制台的堆栈跟踪:
App.vue?3acc:9 Uncaught TypeError: Cannot read properties of undefined (reading 'computed')
at Proxy.provide (App.vue?3acc:9)
at qe (runtime-core.esm-bundler.js:2463)
at Pr (runtime-core.esm-bundler.js:6713)
at Lr (runtime-core.esm-bundler.js:6632)
at Tr (runtime-core.esm-bundler.js:6562)
at D (runtime-core.esm-bundler.js:4421)
at N (runtime-core.esm-bundler.js:4396)
at m (runtime-core.esm-bundler.js:3991)
at K (runtime-core.esm-bundler.js:5140)
at mount (runtime-core.esm-bundler.js:3477)
感谢您的调查。
推荐答案
在vueJS 3.x中似乎未解决此问题。详情请参见open issue。有一些变通的办法。例如,参见this github project。在我的情况下,我已决定更改工作流以避免上述问题。