[英]child component not updating when prop (boolean) is changed by parent component
[英]Child is not updated when boolean prop is changed
我有以下组件:
家长:
<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>
孩子:
<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>
在父组件中,当调用login
方法时, authenticated
变量变为true
。 由于authenticated
作为 prop 传递给 Child 组件,因此我希望 Child 在authenticated
更改时会被刷新。 但是,Child 不会刷新。
我认为问题可能是由于我根本没有在孩子的模板中使用经过authenticated
的事实引起的。 相反,我只在mounted
的钩子中使用它。 就我而言,我没有使用模板中的authenticated
。
我尝试了两种解决方案:
login
方法中调用this.$forceUpdate()
- 这根本不起作用(没有改变):key
添加到 Child,并在每次调用login
时更改密钥 - 这可行,但是,它有点 hacky。 我想了解如何正确地做到这一点。您不在模板中使用它很好,问题是您只检查子mounted
钩子中的authenticated
,该钩子只运行一次(当时是false
的)。
您应该使用watch
来跟踪对经过authenticated
的道具的更改,而不是mounted
:
watch: {
authenticated: {
handler(newValue, oldValue) {
this.setUi();
},
immediate: true // Run the watch when `authenticated` is first set, too
}
}
每次经过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"
});
}
}
}
你需要的是使用观察者。 实际上,您的代码只运行一次(安装 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.