asyncComputed 异步计算属性

asyncComputed 异步计算属性

我们项目中最近使用了异步计算属性,个人感觉很好用,特此推荐给大家。

一、案例

假设这样一个场景:

一个列表数据 data 是通过接口返回,请求参数中有一个 id 的数据,这个 id 数据变化的话,需要重新请求接口获取数据。

按照普通方法来的话,需要按以下步骤实现。

  1. data 中定义一个 list 数据
  2. 需要在 methods 中定义一个 request 方法,请求接口赋值 list
  3. 在页面创建时调用 request 方法,获得首次数据
  4. 通过 watch 监听 id 数据,在变化时调用 request 方法(更新 list 数据)

使用异步计算属性的话,只需要以下代码:

  asyncComputed: {
    list () {
      return Vue.http.get('/get-list-by-id/' + this.id)
        .then(response => response.data)
    }
  }

接下来,详细介绍一下异步计算属性。

二、安装与使用

npm install --save vue-async-computed

当使用了 webpack 或者 browserify 等时,需要明确通过 Vue.use 实现安装。

import Vue from 'vue'
import AsyncComputed from 'vue-async-computed'

Vue.use(AsyncComputed)

和同步计算属性类似,异步计算属性有 get 方法,但是没有 set 方法,设置了也会被忽略。

  asyncComputed: {
    blogPostContent: {
      get () {
        return Vue.http.get('/post/' + this.postId)
          .then(response => response.data.postContent)
       }
    }
  }

三、默认值

异步计算属性还可以设置默认值。在首次加载数据之前使用。

  asyncComputed: {
    blogPostContent: {
      get () {
        return Vue.http.get('/post/' + this.postId)
          .then(response => response.data.postContent)
       },
       default: 'Loading...'
       // default 也可以使用函数,设置基于其他数据的默认值
       default () {
        return 'Loading post ' + this.postId
      }
    }
  }

默认值还可以全局设置。

Vue.use(AsyncComputed, {
  default: 'Global default value'
})

四、重新计算

有时候,异步计算属性的依赖项没有变化,但是需要重新计算。

当某个数据变化时的重新计算可以这么写。

new Vue({
  data: {
    postId: 1,
    timesPostHasBeenUpdated: 0
  },
  asyncComputed: {
    blogPostContent: {
      get () {
        return Vue.http.get('/post/' + this.postId)
          .then(response => response.data.postContent)
      },
      // timesPostHasBeenUpdated 变化时重新计算
      watch: ['timesPostHasBeenUpdated']
    }
  }
}

还可以通过点语法监听具体属性值。
watch: [‘a.b.c’, ‘d.e’] 可以监听 this.a.b.c 和 this.d.e.

另外还可以在某些情况下手动触发重新计算。

  asyncComputed: {
    blogPosts: {
      get () {
        return Vue.http.get('/posts')
          .then(response => response.data)
      },
    }
  },
  methods: {
    refresh() {
      // 手动触发
      this.$asyncComputed.blogPosts.update();
    }
  }

五、有条件的重新计算

使用 watch 会重新计算,但是不会考虑监听属性的值得具体情况。

这个时候可以使用 shouldUpdate 实现具体条件下的重新计算。

  asyncComputed: {
    blogPostContent: {
      get () {
        return Vue.http.get('/post/' + this.postId)
          .then(response => response.data.postContent)
      },
      // pageType 或者 postId 改变都会重新计算,但必须同时满足下面条件
      shouldUpdate () {
        return this.pageType !== 'index'
      }
    }
  }

六、lazy 属性

有时候不希望异步计算属性一直重新计算,可以使用 lazy:true 实现只在首次访问时计算。

  asyncComputed: {
    mightNotBeNeeded: {
      // mightNotBeNeeded 的值只会在首次计算
      lazy: true,
      get () {
        return Vue.http.get('/might-not-be-needed/' + this.id)
          .then(response => response.data.value)
      }
    }
  }

七、计算状态

每个异步计算属性,都会向 $asyncComputed 中添加一个对象(包含有关该对象当前计算状态的信息)。

该对象包含以下属性:

{
  // 之一:updating, success, error
  state: 'updating',
  // 布尔值,属性更新时为true
  updating: true,
  // 没有错误发生且当前值可用时,该属性不再更新
  success: false,
  // promise 出现 rejected
  error: false,
  // promise 出现 rejected 时的原始错误信息
  exception: null
}

用于展示更新/错误信息。

  asyncComputed: {
    posts() {
      return Vue.http.get('/posts')
        .then(response => response.data)
      }
    }
  }
  
// 每次 posts 数据更新时,以下信息都会展示
// 
(Re)loading posts

八、全局错误处理

默认情况下,在异步计算属性中发生 promise 的 reject 的情况下,vue-async-computed 将为你记录错误。

如果你想使用自定义日志记录函数,那么插件将接受 errorHandler 选项,该选项应该是你希望使用错误信息调用的函数。

默认情况下,它将仅以错误的堆栈跟踪作为参数进行调用,但是如果将 errorHandler 与 useRawError 设置为 true,函数将接收原始错误,即抛出错误的Vue实例的引用和错误的堆栈跟踪。

Vue.use(AsyncComputed, {
  errorHandler (stack) {
    console.log('Hey, an error!')
    console.log('---')
    console.log(stack)
  }
)

// useRawError
Vue.use(AsyncComputed, {
  useRawError: true,
  errorHandler (err, vm, stack) {
    console.log('An error occurred!')
    console.log('The error message was: ' + err.msg)
    console.log('And the stack trace was:')
    console.log(stack)
  }
)

git 地址:vue-async-computed

你可能感兴趣的:(vue笔记,vue)