[英]Child is not updated when boolean prop is changed
I have the following components:我有以下组件:
Parent:家长:
<template>
<Child path="instance.json"
v-bind:authenticated="authenticated"
v-bind:authenticator="authenticator"
/>
</template>
<script>
import { getAuthenticator } from '../auth';
export default {
data() {
return {
authenticated: false,
authenticator: null
};
},
beforeMount: async function () {
this.authenticator = getAuthenticator()
this.checkAccess();
},
methods: {
checkAccess() {
this.authenticated = this.authenticator.isAuthenticated();
},
async login() {
this.checkAccess();
await this.authenticator.signIn();
this.checkAccess();
}
}
};
</script>
Child:孩子:
<template>
<div id="swagger-ui"></div>
</template>
<script>
import swagger from "swagger-ui-dist";
import "swagger-ui-dist/swagger-ui.css";
export default {
props: ["path", "authenticated", "authenticator"],
mounted: async function() {
if (this.authenticated) {
let token = (await this.authenticator.getToken()).accessToken;
const ui = swagger.SwaggerUIBundle({
url: this.path,
dom_id: "#swagger-ui",
onComplete: function() {
ui.preauthorizeApiKey("token", token);
}
});
} else {
const ui = swagger.SwaggerUIBundle({
url: this.path,
dom_id: "#swagger-ui"
});
}
}
};
</script>
In the parent component, when the login
method is called, the authenticated
variable changes to true
.在父组件中,当调用
login
方法时, authenticated
变量变为true
。 Since authenticated
is passed as a prop to the Child component, I'd expect the Child to be refreshed whenever authenticated
is changed.由于
authenticated
作为 prop 传递给 Child 组件,因此我希望 Child 在authenticated
更改时会被刷新。 However, the Child does not refresh.但是,Child 不会刷新。
I think that the problem might be caused by the fact that I am not using authenticated
in the template of the child at all.我认为问题可能是由于我根本没有在孩子的模板中使用经过
authenticated
的事实引起的。 Instead, I'm using it only in the mounted
hook.相反,我只在
mounted
的钩子中使用它。 In my case, I have no use for authenticated
in the template.就我而言,我没有使用模板中的
authenticated
。
I tried two solutions:我尝试了两种解决方案:
this.$forceUpdate()
in the login
method of Parent - that didn't work at all (nothing changed)login
方法中调用this.$forceUpdate()
- 这根本不起作用(没有改变):key
to the Child, and changing the key each time the login
is called - this works, however, it's a bit hacky.:key
添加到 Child,并在每次调用login
时更改密钥 - 这可行,但是,它有点 hacky。 I'd like to understand how to do that properly.It's fine that you're not using it in the template, the issue is that you only check authenticated
in the child's mounted
hook, which only runs once (and is false
at that time).您不在模板中使用它很好,问题是您只检查子
mounted
钩子中的authenticated
,该钩子只运行一次(当时是false
的)。
You should use a watch
to track changes to the authenticated
prop instead of mounted
:您应该使用
watch
来跟踪对经过authenticated
的道具的更改,而不是mounted
:
watch: {
authenticated: {
handler(newValue, oldValue) {
this.setUi();
},
immediate: true // Run the watch when `authenticated` is first set, too
}
}
That will call a setUi
method every time authenticated
changes:每次经过
authenticated
的更改都会调用setUi
方法:
methods: {
async setUi() {
if (this.authenticated) {
let token = (await this.authenticator.getToken()).accessToken;
const ui = swagger.SwaggerUIBundle({
url: this.path,
dom_id: "#swagger-ui",
onComplete: function() {
ui.preauthorizeApiKey("token", token);
}
});
} else {
const ui = swagger.SwaggerUIBundle({
url: this.path,
dom_id: "#swagger-ui"
});
}
}
}
what you need is to use a watcher.你需要的是使用观察者。 Actually, your code is only run once (when de component is mounted), not at each prop change.
实际上,您的代码只运行一次(安装 de 组件时),而不是在每次 prop 更改时运行。
<template>
<div id="swagger-ui"></div>
</template>
<script>
import swagger from 'swagger-ui-dist';
import 'swagger-ui-dist/swagger-ui.css';
export default {
props: {
path: {
type: String,
default: '',
},
authenticated: {
type: Boolean,
default: false,
},
authenticator: {
type: Object,
default: () => {},
},
},
watch: {
async authenticated(newValue) {
await this.updateSwagger(newValue);
},
},
async mounted() {
await this.updateSwagger(this.authenticated);
}
methods: {
async updateSwagger(authenticated) {
if (authenticated) {
const token = (await this.authenticator.getToken()).accessToken;
const ui = swagger.SwaggerUIBundle({
url: this.path,
dom_id: '#swagger-ui',
onComplete: function () {
ui.preauthorizeApiKey('token', token);
},
});
} else {
const ui = swagger.SwaggerUIBundle({
url: this.path,
dom_id: '#swagger-ui',
});
}
},
},
};
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.