应该在哪里放置组件获取逻辑?

时间:2018-04-05 14:53:42

标签: javascript vue.js vuejs2

对于vue组件Page,我从REST请求中检索其数据(或者道具?)titlecontent。我什么时候应该执行这个REST获取请求?逻辑应该放在哪里?

现在我尝试获取组件ready,但此函数永远不会执行:

<template>
    <b-container class="bv-example-row">
        <h1>{{title}}</h1>

        <b-row>
            <b-col>
                {{content}}
            </b-col>
        </b-row>
    </b-container>
</template>

<script>
import api from '../../api'

export default {
    data() {
        return {
            id: '',
            slug: '',
            title: '',
            content: ''
        };
    },

    ready() {
        console.log('foo');
        this.fetchData();
    },

    methods: {
        fetchData() {
            api.getPageBySlug('sample-page', page => {
                this.$set('title', page.title);
                this.$set('content', page.content);
            });
        }
    }
};
</script>

1 个答案:

答案 0 :(得分:3)

Vue.js 2中不存在ready()挂钩。

您可以将Ajax代码放在许多钩子中。更常见的是使用the following lifecycle hooks之一:

  • beforeCreate()
  • created()
  • beforeMount()
  • mounted()

那么应该指导您的决定?你必须考虑一些事情。

首先: Vue的初始化代码同步执行

这意味着,从技术上讲,您在任何这些钩子中运行的任何异步代码只会在>所有这些钩子结束后响应。见demo:

&#13;
&#13;
new Vue({
  el: '#app',
  beforeCreate() {
    setTimeout(() => { console.log('fastest asynchronous code ever (started at beforeCreate)') }, 0);
    console.log('beforeCreate hook executed');
  },
  created() {
    console.log('created hook executed');
  },
  beforeMount() {
    console.log('beforeMount hook executed');
  },
  mounted() {
    console.log('mounted hook executed');
  }
})
&#13;
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
  Check the console.
</div>
&#13;
&#13;
&#13;

换句话说,如果您在beforeCreate中进行Ajax调用,无论API有多快响应,那么响应将仅在{{1已被执行。


使用哪个钩子?


使用Vuex全局管理状态时

作为mentioned in comments,一种常见的方法是使用Vuex全局管理您的应用程序状态。在这种情况下,请求应在Vuex actions中启动。然后,您的组件将在任何生命周期挂钩(或方法)中调度操作。见下面的演示。

&#13;
&#13;
mounted()
&#13;
const store = new Vuex.Store({
strict: true,
  state: {
    people: []
  },
  mutations: {
    populate: function (state, newPeople) {
      state.people = newPeople
    }
  },
  actions: {
    fetchPeople ({ commit }) {
      axios.get('https://reqres.in/api/users').then(function (response) {
        commit('populate', response.data.data)
      }, function () {
        console.log('error')
      })
    }
  }
});

Vue.component('mycomp', {
  computed: Vuex.mapState(['people']),
  template: `
    <ul>
      <li v-for="p in people">
      {{ p.first_name }} {{ p.last_name }}
      </li>
  	</ul>
  `
});

new Vue({
  store,
  el: '#app',
  created() {
  	this.$store.dispatch('fetchPeople');
  },
  computed: Vuex.mapState(['people']),
})
&#13;
&#13;
&#13;