在渲染组件之前从api获取数据

时间:2017-09-11 12:20:12

标签: vue.js vue-component vue-router

我在呈现页面之前发送了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);
        },           
    }
};

问题是在setProfilesetPhotos方法之前渲染。如何正确渲染我的组件?

3 个答案:

答案 0 :(得分:4)

尝试使用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'
        });
    }
};

答案 1 :(得分:1)

你应该能够返回从调用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 :(得分:0)

也许这可以帮助某人:

试试Promise

let fetchData = new Promise((resolve, reject) => {
    axios.get(YOUR_API)
            .then(function (response) {
                resolve();
            })
            .catch(function () {
                reject('Fail To Load');
            });
});

fetchData.then(
    function(success) {
        YOUR_SUCCESS_LOGIC
    },
    function(error) {
        console.log(error);
    }
);