The front-end technology: How method performs UI after the asynchronous call to action in the management of state vuex

First, the origin of the problem

In doing vue.js recent project, he met vuex state management action and vue.js method of communicating with each other interoperability issues. The scene as shown below:

Second, the first workaround

For example, when we initialized page, it is necessary from the server through an API interface to obtain data, data acquisition needs to display Loading status box before the success, after the completion of data acquisition, Loading status box needs to be hidden.

This is a relatively simple scenario, of course, is relatively simple to solve.

We can 通过state数据字段来实现, in state stores a loading field, and set the default value is false.

const store = new Vuex.Store({
  state: {
    loading: false }, // ...... }); 

Because of state.loading to operate, so we need to define a mutation method, used to update the loading state data.

const UPDATE_LOADING = 'updateLoading';

const store = new Vuex.Store({
  // ......, mutations: { updateLoading (state, loading) { state.loading = loading; } }, // ...... }); 

Then, we declare an action method, used to obtain data from the HTTP API.

const store = new Vuex.Store({
  // ......,
  actions: {
    fetchData ({ commit }) {
      commit(UPDATE_LOADING, true);
      axios.get('...', { params: {...} }) .then(res => { // TODO 解析HTTP响应数据,进行相关的业务逻辑处理 }) .catch(err => { // TODO 进行相关的错误与异常处理 }) .finally(() => { commit(UPDATE_LOADING, false); }); } }, // ...... }) 

In the page template, we will vuex by mapActions function mapping method is a method of action in the target vue.js.

import { mapActions } from 'vuex'

export default { // ... methods: { ...mapActions([ 'fetchData', // ... ]) } } 

Finally, the method calls mapActions fetchData can reflect body mounted in the life-cycle approach vue.js.

export default {
  // ...,
  mounted() {
    this.fetchData();
  },
  // ... } 

Third, the second solution

The first solution described above, can be modified by mutation status data state control data rendered on the UI. But if you want to get to the result data to the UI components it is not enough. In addition, if you want to call the action method after the execution is complete and then do something in the UI is not feasible.

Before we know, asynchronous data transfer method, data can be transmitted through the callback function parameters, so the second solution I mentioned is that 通过回调函数实现of.

const store = new Vuex.Store({
  // ......,
  actions: {
    fetchData ({ commit }, { params, callback }) {
      commit(UPDATE_LOADING, true);
      axios.get('...', { params }) .then(res => { callback(res); }) .catch(err => { // TODO 进行相关的错误与异常处理 }) .finally(() => { commit(UPDATE_LOADING, false); }); } }, // ...... }) 

Fourth, the third solution

While the above two methods can solve some problems, but the solution is not elegant, but the first method has significant limitations. For example, the method can not be the main interface callback perform subsequent operations, can not freely pass parameters. The second method uses a callback can call the method, you can also pass parameters, but the callback is invoked synchronously, code style is not very good. So, I am more we promote the use of the third method is to return a call to action in the Promise, in the main interface so you can get this promise objects, and perform subsequent chain of tasks can also be the result of action asynchronous tasks data transmitted to the main UI.

const store = new Vuex.Store({
  // ......,
  actions: {
    fetchData ({ commit }, { params }) {
      commit(UPDATE_LOADING, true);
      return axios.get('...', { params }) .then(res => { const { data } = res; return data; }) .finally(() => { commit(UPDATE_LOADING, false); }); } }, // ...... }) 

In the main UI, we can perform the following manner using the subsequent operation.

export default {
  // ...,
  mounted() {
    this.fetchData({ id: 1 }) .then(res => { // TODO 执行后续的任务 }) .catch(err => { // TODO 处理异常情况 }); }, // ... }

Guess you like

Origin www.cnblogs.com/popgis/p/11817443.html