web-dev-qa-db-ja.com

コンポーネントをレンダリングする前にAPIからデータを取得する

ページをレンダリングする前に2つのAPIリクエストを送信します。

const Profile = {
    template: '#profile',
    attributes: null,
    photos: [],
    data: function () {
        return {attributes: Profile.attributes, photos: Profile.photos};
    },
    beforeRouteEnter: function (to, from, next) {
        function getProfile() {
            return axios.get('user/get-profile?access-token=1', {responseType: 'json'});
        }
        function getPhotos() {
            return axios.get('photos?access-token=1', {responseType: 'json'});
        }

        axios.all([getProfile(), getPhotos()])
            .then(axios.spread(function (profile, photos ) {
                console.log(profile, photos );
                next(vm => {
                    vm.setProfile(profile);
                    vm.setPhotos(photos);
                })
            }));
    },
    methods: {
        setProfile: function (response) {
            Profile.attributes = response.data;
            console.log(Profile.attributes);
        },
        setPhotos: function (response) {
            Profile.photos = response.data;
            console.log(response);
        },           
    }
};

問題は、setProfileおよびsetPhotosメソッドの前にレンダリングが発生することです。コンポーネントを正しくレンダリングする方法は?

8
Alex

Async/awaitで試してください。 beforeRouteEnteraxios.spreadを削除してcreateを追加しました。すべてのリクエストが行われた後にコンポーネントがロードされます。

const Profile = {
    template: '#profile',
    attributes: null,
    photos: [],
    data() {
        return {
            attributes: null,
            photos: null
        };
    },
    async created() {
        const getProfile = await axios.get('user/get-profile?access-token=1', {
            responseType: 'json'
        });
        const getPhotos = await axios.get('photos?access-token=1', {
            responseType: 'json'
        });

        this.setProfile(profile);
        this.setPhotos(photos);
    },
    methods: {
        setProfile(response) {
            this.attributes = response.data;
            console.log(this.attributes);
        },
        setPhotos(response) {
            this.photos = response.data;
            console.log(response);
        }
    }
};

より短い

const Profile = {
    template: '#profile',
    attributes: null,
    photos: [],
    data() {
        return {
            attributes: null,
            photos: null
        };
    },
    async created() {
        this.attributes = await axios.get('user/get-profile?access-token=1', {
            responseType: 'json'
        });
        this.photo = await axios.get('photos?access-token=1', {
            responseType: 'json'
        });
    }
};
8
Phil

次のように、axios.allの呼び出しから返されるPromiseを返すことができるはずです。

return axios.all([getProfile(), getPhotos()])
// .then() => ...

または、データオブジェクトにプロパティを追加し、これを使用して、すべてのPromiseが解決されるまでローダーを表示することもできます

const Profile = {
    template: '#profile',
    attributes: null,
    photos: [],
    data: function () {
        return {attributes: Profile.attributes, photos: Profile.photos, isLoading: true};
    },
    beforeRouteEnter: function (to, from, next) {
        function getProfile() {
            return axios.get('user/get-profile?access-token=1', {responseType: 'json'});
        }
        function getPhotos() {
            return axios.get('photos?access-token=1', {responseType: 'json'});
        }

        axios.all([getProfile(), getPhotos()])
            .then(axios.spread(function (profile, memes) {
                console.log(profile, memes);
                this.isLoading = false

                next(vm => {
                    vm.setProfile(profile);
                    vm.setPhotos(photos);
                })
            }));
    },
    methods: {
        setProfile: function (response) {
            Profile.attributes = response.data;
            console.log(Profile.attributes);
        },
        setPhotos: function (response) {
            Profile.photos = response.data;
            console.log(response);
        },           
    }
};

テンプレートコードは省略されていますが、isLoadingに基づいて表示するコンテンツを切り替えることができます。このルートをたどる場合は、ローダーの抽象化を作成するのがおそらく最善です。

また、すべてのデータを特定のコンポーネントの状態に結び付けるのではなく、vuexを確認することをお勧めします。

2
Purple Hexagon