Home > Software design >  Vue.js 3 Composition API vs. Options API
Vue.js 3 Composition API vs. Options API

Time:01-21

Can someone explain why this does not work with script setup, but without it works.
In the template I use v-for to iterate through the string[]:

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

Code with <script lang="ts">:
Working, the v-for finds elements and I see the rows.

<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)
            this.data.translatedLanguages
            console.log(this.data.translatedLanguages);
        });
    }
});
</script>

Script with <script setup lang="ts">:
Not working, I don't see any rows because v-for seems does not find the elements, but the data object is not empty.

<script lang="ts">
import axios, {isCancel, AxiosError} from 'axios';
import { onMounted, reactive, VueElement } 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 is this interface:

export interface LanguagesTranslated {
    translatedLanguages: string[];
}

CodePudding user response:

Your first example is using the Options API. When using the Options API, properties in the object returned by data() are made reactive automatically.

The setup() function and <script setup> are the two ways of using the Composition API. When using the Composition API, your acts more like normal JavaScript. To create a reactive variable, you have to explicitly create it using one of the Reactivity API functions: ref(), reactive(), or computed().

As your example with <script setup> is creating a plain variable, it is not reactive and the v-for does not re-evaluate when you reassign it.

Try this:

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

// Use `ref` here to create a Ref.
const data = ref<LanguagesTranslated>({ translatedLanguages: [] });

onMounted(() => {
    axios
        .get("https://translation.colreminder.com/test/data.php?request=langTranslated")
        .then(response => {
            console.log(response.request.response);
            // Use `data.value`, as `data` is a Ref.
            data.value = JSON.parse(response.request.response);
            console.log(data.value.translatedLanguages);
        });
});
</script>
  • Related