Vue中v-data-table无法调用getName()函数修改表格值的问题及解决方法
getName() Function Execution in Vuetify's v-data-table Let's break down why your current approach isn't working and fix it step by step:
The Core Problem
Your getName() function uses an asynchronous axios.get() call, but you're returning this.name immediately—before the API request finishes. This means you're either returning an empty/old value, or undefined entirely. On top of that, calling a function directly in the v-data-table template will re-run it every time the component re-renders, leading to duplicate unnecessary API calls.
Solution 1: Pre-fetch User Names (Recommended)
The cleanest approach is to fetch all required user names when you load your studies data, then attach the name directly to each study object. This avoids async issues in the template and reduces API calls.
Step 1: Modify Your Data Fetching
Assuming you fetch studies in your component's lifecycle (like mounted), update it to batch-fetch user names:
data() { return { studies: [], search: '', headers: [ { text: 'Title', value: 'title', sortable: true }, { text: 'Name', value: 'userName', sortable: false }, { text: 'Created', value: 'createdAt', sortable: false } ] }; }, async mounted() { // 1. Fetch your studies first const studiesResponse = await this.$axios.get('/your-studies-endpoint'); this.studies = studiesResponse.data; // 2. Batch-fetch user names and attach them to each study await Promise.all(this.studies.map(async (study) => { const userResponse = await this.$axios.get(`http://localhost:3000/users/${study.user}`); study.userName = userResponse.data.name; })); }
Step 2: Update the Template
Now you can render the pre-fetched userName directly, no need for the getName() call in the template:
<v-data-table :headers="headers" :items="studies" :search="search" @click:row="detail"> <template slot="items" slot-scope="props"> <td>{{ props.item.title }}</td> <td>{{ props.item.userName }}</td> <td>{{ props.item.createdAt }}</td> </template> </v-data-table>
Solution 2: Use a Reusable Component with Caching
If you need to fetch user names on-demand (instead of batch-fetching), create a small component that handles the async request and caches results to avoid duplicate calls:
Step 1: Create a UserDisplayName Component
<!-- components/UserDisplayName.vue --> <template> <span>{{ displayName || 'Loading...' }}</span> </template> <script> export default { props: ['userId'], data() { return { displayName: '', // Cache to avoid re-fetching the same user userCache: {} }; }, async mounted() { if (this.userCache[this.userId]) { this.displayName = this.userCache[this.userId]; return; } const response = await this.$axios.get(`http://localhost:3000/users/${this.userId}`); this.displayName = response.data.name; this.userCache[this.userId] = response.data.name; } }; </script>
Step 2: Use the Component in Your Table
<v-data-table :headers="headers" :items="studies" :search="search" @click:row="detail"> <template slot="items" slot-scope="props"> <td>{{ props.item.title }}</td> <td><user-display-name :user-id="props.item.user"></user-display-name></td> <td>{{ props.item.createdAt }}</td> </template> </v-data-table>
Why Your Original Code Failed
- Async Timing: The
axios.get()request takes time to complete, butreturn this.nameruns immediately—so you're returning a value that hasn't been updated yet. - Re-render Calls: Every time your component re-renders (e.g., when
searchchanges),getName()runs again, spamming your API with duplicate requests.
内容的提问来源于stack exchange,提问作者jiwon

