web-dev-qa-db-fra.com

VueJS: la variable n'est pas définie à l'intérieur calculée uniquement

J'essaie de faire une saisie semi-automatique asynchrone avec Vue, Nuxt, Axios et Buefy. Cela fonctionne essentiellement, mais j'ai besoin d'avoir des chaînes différentes lorsque l'utilisateur commence à taper et qu'il n'y a encore rien à afficher, et quand il n'y a rien trouvé pour une telle demande.

Je vérifie une variable calculée si la valeur d'entrée n'est pas vide et axios renvoie un tableau vide à gérer si l'adresse de la demande ne peut pas être trouvée. Mais cela provoque une erreur

Impossible de lire la propriété 'longueur' de non défini

La chose étrange est que la variable address est utilisée avec succès dans d'autres parties de mon composant.

Mon fichier vue ci-dessous:

<template lang="pug">
b-field(label="Your address?")
    b-autocomplete(
    rounded,
    v-model="address",
    :data="data",
    placeholder="Start typing",
    icon="magnify",
    @input="getAsyncData",
    @select="option => selected = option",
    :loading="isFetching"
    )
        template(slot="empty") {{ dummyText }}
</template>

<script>
import axios from 'axios'
import debounce from 'lodash/debounce'

export default {
    data() {
        return {
            data: [],
            address: '',
            selected: null,
            isFetching: false,
            nothingFound: false,
            test: false
        }
    },

    computed: {
        dummyText: () => {
            if (this.address.length > 0 && this.nothingFound) { // This will return error
                return 'There is no such address'
            } else {
                return 'Keep typing'
            }
        }
    },

    methods: {
        getAsyncData: debounce(function () {
            this.isFetching = true

            axios.post('https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address', {
                "query": this.address,
                "count": 8
            }, {
                headers: {
                    'Authorization': 'Token sometoken',
                    'Content-Type': 'application/json',
                    'Accept': 'application/json',
                }
            })
                .then(response => {
                    this.isFetching = false
                    this.data = Object.values(response.data.suggestions)
                    if (response.data.suggestions.length===0) this.nothingFound = true
                    console.log(this.address.length) // This will work
                })
                .catch(error => {
                    this.isFetching = false
                    console.log(error);
                })
        }, 300)
    }
}
</script>

Il ne s'agit pas de SSR, j'ai essayé d'initier le composant à l'intérieur du crochet monté. Je pense que je manque quelque chose d'évident, mais j'ai déjà passé des heures à essayer de résoudre ce problème sans succès

8
Elijah Ellanski

N'utilisez pas la fonction de flèche ()=>{} Pour computed, cela provoquera le mauvais contexte (pas courant Vue Vue)).

Passez à function () {} alors cela devrait fonctionner correctement.

Et pour methods, watch, vous devez suivre les mêmes règles.

computed: {
    dummyText: function () { // change to function () {}
        if (this.address.length > 0 && this.nothingFound) { // This will return error
            return 'There is no such address'
        } else {
            return 'Keep typing'
        }
    }
},
23
Sphinx

Vous pouvez également utiliser le raccourci es2015 pour une fonction de méthode:

computed: {
    dummyText() {
        return this.address.length > 0 && this.nothingFound ? 'There is no such address' : 'Keep typing';
    }
}
3
Artem Gorlachev