You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 Script Setup中v-for不渲染数据问题求助(对比Options API)

为什么Script Setup中v-for无法渲染数据,而Options API可以正常工作?

模板中使用v-for遍历string[]:

<div v-for="lang in data.translatedLanguages" class="translationTableBodyRow">
      <div class="translationTableBodyCell">xx</div>
      <div class="translationTableBodyCell">{{ lang }}</div>
      <div class="translationTableBodyCell">10 %</div>
      <div class="translationTableBodyCell">Edit</div>
</div>

可正常工作的Options API代码

<script  lang="ts">
import axios, {isCancel, AxiosError} from 'axios';
import { defineComponent } from 'vue'

export default defineComponent({
    data() {
        return {
            data: { translatedLanguages: [] }
        }
    },
    mounted() {
        axios.get("https://translation.colreminder.com/test/data.php?request=langTranslated").then(response => {
            console.log(response.request.response);
            this.data = JSON.parse(response.request.response)
            console.log(this.data.translatedLanguages);
        });
    }
});
</script>

无法渲染数据的Script Setup代码

<script lang="ts" setup>
import axios, {isCancel, AxiosError} from 'axios';
import { onMounted, reactive } from 'vue';
import type { LanguagesTranslated } from './main';

var data: LanguagesTranslated = { translatedLanguages: [] };

onMounted(() => {
    axios.get("https://translation.colreminder.com/test/data.php?request=langTranslated").then(response => {
        console.log(response.request.response);
        data = JSON.parse(response.request.response);
        console.log(data.translatedLanguages);
    });
});
</script>

LanguagesTranslated接口定义

export interface LanguagesTranslated {
    translatedLanguages: string[];
}

问题原因

Script Setup中直接用var data声明的普通对象不具备响应式能力。Vue的响应式系统依赖reactive/ref来追踪数据变化,只有被包装成响应式的数据更新时,模板才会触发重新渲染。

而Options API里data()返回的对象会被Vue自动处理成响应式对象,所以修改this.data时模板能感知到变化并更新;但Script Setup中的普通变量无法触发响应式更新,哪怕你后续替换了整个对象引用,模板也不会同步渲染新数据。

修复方案

方案1:用reactive创建响应式对象,更新属性而非替换对象

<script lang="ts" setup>
import axios from 'axios';
import { onMounted, reactive } from 'vue';
import type { LanguagesTranslated } from './main';

// 用reactive包装成响应式对象
const data = reactive<LanguagesTranslated>({ translatedLanguages: [] });

onMounted(() => {
    axios.get("https://translation.colreminder.com/test/data.php?request=langTranslated").then(response => {
        const resData = JSON.parse(response.request.response) as LanguagesTranslated;
        // 直接更新对象属性,保留响应式引用
        data.translatedLanguages = resData.translatedLanguages;
    });
});
</script>

方案2:用ref创建响应式引用,允许替换整个对象

<script lang="ts" setup>
import axios from 'axios';
import { onMounted, ref } from 'vue';
import type { LanguagesTranslated } from './main';

// 用ref创建响应式引用
const data = ref<LanguagesTranslated>({ translatedLanguages: [] });

onMounted(() => {
    axios.get("https://translation.colreminder.com/test/data.php?request=langTranslated").then(response => {
        // 替换ref的value属性
        data.value = JSON.parse(response.request.response) as LanguagesTranslated;
    });
});
</script>

注意:使用ref时,模板中需要改为data.value.translatedLanguages,或者可以通过toRefs解构简化模板写法。

内容的提问来源于stack exchange,提问作者chrisonline

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:31:13