异常捕获

集成 Vuex

安装 vuex:

npm install -S vuex
1

创建 store.js,源码如下:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    error: null
  },
  mutations: {
    setError: (state, message) => {
      if (message) {
        state.error = { message }
      } else {
        state.error = null
      }
    }
  }
})

export default store
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

这里的 vuex 中存放了一个 error 状态,mutations 中包含了一个方法 setError,用于更新 error 状态,error 状态是一个对象,包含一个 message 属性,即错误提示

Global 组件

创建 Global 组件,源码如下:

<template>
  <div class="global">
    <div class="error" v-if="error">
      <div class="error-msg-wrapper">
        <div class="error-image">
          <ImageView
            src="https://www.youbaobao.xyz/resource/icon/crash.png"
          />
        </div>
        <div class="error-msg">{{error.message || '程序猿紧急抢修中...'}}</div>
        <div class="error-retry-wrapper">
          <div class="error-retry" @click="retry">重启小程序</div>
        </div>
      </div>
    </div>
    <slot v-if="!error"></slot>
  </div>
</template>

<script>
  import store from '../store'
  import { setError } from '../utils/error'
  import ImageView from './base/ImageView'

  export default {
    components: { ImageView },
    computed: {
      error() {
        return store.state.error
      }
    },
    methods: {
      retry() {
        // 跳转回到首页
        let path = getApp().globalData.appOptions.path
        if (!path.startsWith('/')) {
          path = `/${path}`
        }
        mpvue.reLaunch({ url: path })
        // 重置异常信息
        setError()
      }
    }
  }
</script>

<style lang="scss" scoped>
  @import '../style/base';

  .error {
    position: fixed;
    top: 0;
    width: 100%;
    height: 100%;
    @include center;

    .error-msg-wrapper {
      width: 100%;
      padding: 0 15px;
      box-sizing: border-box;

      .error-image {
        width: 100%;
        padding: 0 15px;
        box-sizing: border-box;
      }

      .error-msg {
        width: 100%;
        text-align: center;
        font-size: 16px;
        color: #666;
        margin-top: 20px;
      }

      .error-retry-wrapper {
        width: 100%;
        @include center;

        .error-retry {
          border: 1px solid #3696EF;
          border-radius: 50px;
          text-align: center;
          font-size: 13px;
          color: #3696EF;
          padding: 8px 40px;
          margin-top: 10px;
        }
      }
    }
  }
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

Global 是一个容器组件,它最主要的有以下两点:

  1. 获取 vuex 中的 error 状态,如果 error 状态不为 null,则显示 error 中的信息
  2. 如果 error 状态为 null,则显示 slot 插槽,这部分就是我们自己的组件内容了

优化现有组件

将现有组件外层套上 Global 组件即可,这里以 list 组件为例:

<template>
  <Global>
    <div class="list">
      <SearchTable :data="data"/>
    </div>
  </Global>
</template>
1
2
3
4
5
6
7
上次更新: 12/26/2019, 11:18:45 PM