TypeScript结合Vue时无法更新基类属性的问题
Hey there! Let's figure out why your UI isn't updating even though the isSelected property in your base class is changing, and how to fix this issue.
Root Cause: Base Class Properties Aren't Tracked by Vue's Reactivity System
Vue's UI updates rely on its reactivity system, which only tracks properties that are part of the component's reactive context (like data, props, or properties wrapped with reactive/ref). If your base class is a plain JavaScript class, its isSelected property won't be automatically monitored by Vue—even when you modify it via the select method, Vue has no way to know the value changed, so it won't trigger a UI re-render.
Common Fixes to Try
1. Wrap Base Class State with Vue's Reactive API
Modify your base class to use Vue's reactive (for object state) or ref (for primitive values) to ensure properties are tracked:
// Base class import { reactive } from 'vue'; class BaseItem { constructor() { // Wrap state in reactive to make it observable this.state = reactive({ isSelected: false }); } select() { // Update the reactive state property this.state.isSelected = !this.state.isSelected; } }
Then in your derived component's template, bind to the reactive state:
<template> <div @click="select"> {{ state.isSelected ? 'Selected' : 'Not Selected' }} </div> </template>
2. Declare Base Class Properties in the Derived Component's data
If you prefer to keep the base class as a plain JS class, explicitly include the isSelected property in your derived component's data function. This adds it to Vue's reactivity tracking:
<template> <div @click="select"> {{ isSelected ? 'Selected' : 'Not Selected' }} </div> </template> <script> import BaseItem from './BaseItem'; export default { extends: BaseItem, data() { return { // Initialize the property here to make it reactive isSelected: false }; } }; </script>
Note: Make sure your base class's select method modifies this.isSelected (which now refers to the reactive property in the component's data).
3. Verify Method Context is Correct
Double-check that the select method is bound to the correct component instance. If you're using the method directly in the template (@click="select"), Vue automatically binds the component's this context, so this is usually fine. But if you're passing the method somewhere else, you might need to bind it explicitly:
<script> export default { extends: BaseItem, mounted() { // Example: Ensure context is bound if passing to another function someExternalFunction(this.select.bind(this)); } }; </script>
Why Vue DevTools Shows the Property Changed
Vue DevTools can inspect all properties on the component instance, even non-reactive ones. So even though isSelected changes, since it's not part of Vue's reactive system, the UI won't update to reflect the change.
内容的提问来源于stack exchange,提问作者Can PERK

