Использование этого крючка жизненного цикла, созданного из API композиции

У меня проблема с машинописным текстом в Vue 3.

  1. Получайте данные из Itunes каждый раз, когда опора 'query' изменяется. (формат: [{}, {}, {}, ...]
  2. Вызов функции для фильтрации неиспользуемой информации из выборки

Когда я вызываю функцию (эта функция будет фильтровать объекты для упрощения кода) в выборке, она выдает ошибку:

Property 'filterData' does not exist on type 'void'.

Мой код:

<template>
    <div>
    </div>
</template>

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

interface Song {
    id: number;
    name: string;
    nameT: string;
    cover?: string;
    preview: string;
}

interface SongFromITunes {
    artistId: number;
    artistName: string;
    trackName: string;
    previewUrl: string;
    artworkUrl100?: string;
}

export default defineComponent({
    data() {
        return {
            list: [] as Array<Song>
        };
    },
    props: {
        query: String
    },
    methods: {
        filterData({
            artistId: id,
            artistName: name,
            trackName: nameT,
            artworkUrl100: cover,
            previewUrl: preview
        }: SongFromITunes): Song {
            return { id, name, nameT, cover, preview };
        }
    },
    setup(props) {
        onUpdated(() => {
            const { query } = props;
            if (query != null) {
                fetch(
                    `https://itunes.apple.com/search?term=${encodeURI(
                        query
                    )}&limit=10&entity=musicTrack`
                )
                    .then((resolve) => resolve.json())
                    .then((data) => data.results.map((item: SongFromITunes) => this.filterData(item));
            }
        });
    }
});
</script>

<style scoped></style>

person Matej Bednar    schedule 02.10.2020    source источник


Ответы (2)


Я нашел ваш вопрос действительно интересным.

Из документов ясно, что this не может быть используется внутри setup(), поскольку экземпляр Vue еще не существует.

Но в случае хуков жизненного цикла вы передаете обратный вызов, который позже должен быть прикреплен к новому экземпляру Vue.

Документы: Эти функции регистрации ловушек жизненного цикла могут только использоваться синхронно в течение setup(), поскольку они полагаются на внутреннее глобальное состояние для определения местонахождения текущего активного экземпляра (экземпляра компонента, setup() которого вызывается прямо сейчас).

Итак, кажется, правильным способом было бы было бы легко, если бы Vue просто использовал bind и привязал обратный вызов к экземпляру. Однако, похоже, это не так ...

Решение для вас - переместить filterData из methods в setup()

    setup(props) {
        let filterData = function({
            artistId: id,
            artistName: name,
            trackName: nameT,
            artworkUrl100: cover,
            previewUrl: preview
        }: SongFromITunes): Song {
            return { id, name, nameT, cover, preview };
        }

        onUpdated(() => {
            const { query } = props;
            if (query != null) {
                fetch(
                    `https://itunes.apple.com/search?term=${encodeURI(
                        query
                    )}&limit=10&entity=musicTrack`
                )
                    .then((resolve) => resolve.json())
                    .then((data) => data.results.map((item: SongFromITunes) => filterData(item));
            }
        });

        return { filterData }
    }

Обновлять

Мне было действительно интересно узнать о причинах этого, потому что я чувствую, что хуки по своей сути привязаны к экземпляру, и, вероятно, многие люди будут ожидать, что this доступен в обратных вызовах. Я спросил о разногласиях Vue и получил следующее объяснение (спасибо Vaage # 9161):

Если мы привяжем хуки жизненного цикла в настройке к экземпляру, это только вызовет путаницу и вызовет антипаттерны. Вы делаете выбор, api опций или api композиции. Если вы выберете состав api, то на this ничего интересного для вас нет. Все содержится в закрытии setup. Если мы добавим его, машинный вывод будет труднее реализовать, и люди начнут использовать параметры api в сочетании с ним.

Сообщение дня

Не смешивайте API композиции и API параметров

person Michal Levý    schedule 02.10.2020
comment
Сообщение дня: Точно решите, что использовать в проекте, и придерживайтесь его! - person Thomas; 05.10.2020

this недоступен из функции настройки, потому что компонент еще не создан. Вам также необходимо определить filterData внутри настройки.

Вот соответствующая документация

person camwhite    schedule 02.10.2020