zl程序教程

您现在的位置是:首页 >  其它

当前栏目

使用$dispatch接连栽两个跟头!!

两个 Dispatch 使用
2023-09-11 14:20:22 时间

跟往常一样,没事写几行代码找找感觉,结果连续踩了两个坑,跟大家分享一下:

一号坑:execJSTypeError: Cannot read property '$dispatch' of null

实现代码:

<template>

  <div class="photo-selector-wrapper {{aniOpClass}}">

    <div class="photo-selector-btn" οnclick="pickPhoto">

      <text class="photo-selector-text">{{componentData.selectPhoto}}</text>

    </div>

    <div class="second-divider"></div>

    <div class="photo-selector-btn" οnclick="hide">

      <text class="photo-selector-text">{{componentData.cancel}}</text>

    </div>

  </div>

</template>

<script>

  import media from '@system.media'

  export default {

    hide() {

      this.$emit('hide')

    },

    pickPhoto: function () {

      media.pickImage({

        success: (ret) => {

          console.log("pickImage start :", ret.uri);

          this.$dispatch('getPhotoUri', ret.uri)

        },

        fail: (erromsg, errocode) => {

          console.log('media.pickImage ' + errocode + ': ' + erromsg)

        },

        cancel: () => {

          console.log('media.pickImage cancel')

        },

        complete: () => {

          console.log('media.pickImage complete')

        }

      })

      this.hide()

    },

  }

</script>

执行报错如下:

cke_19213.png

经过简单判断可以得出,是this在程序中发生了改变,导致dispatch在回调中时已经找不到,通过var that = this 深度复制,修改代码后,果然错误不一样了。。。

二号坑:Application error stack : TypeError: Cannot read property 'getPhotoUri' of undefined

实现代码如下:子窗口实现调用media获取照片,并通过dispatch冒泡,传递给父窗口

<template>

  <div class="photo-selector-wrapper {{aniOpClass}}">

    <div class="photo-selector-btn" οnclick="pickPhoto">

      <text class="photo-selector-text">{{componentData.selectPhoto}}</text>

    </div>

    <div class="second-divider"></div>

    <div class="photo-selector-btn" οnclick="hide">

      <text class="photo-selector-text">{{componentData.cancel}}</text>

    </div>

  </div>

</template>

<script>

  import media from '@system.media'

  export default {

    hide() {

      this.$emit('hide')

    },

pickPhoto: function () {

var that = this;

      media.pickImage({

        success: (ret) => {

          console.log("pickImage start :", ret.uri);

          that.$dispatch('getPhotoUri', ret.uri)

        },

        fail: (erromsg, errocode) => {

          console.log('media.pickImage ' + errocode + ': ' + erromsg)

        },

        cancel: () => {

          console.log('media.pickImage cancel')

        },

        complete: () => {

          console.log('media.pickImage complete')

        }

      })

      this.hide()

    },

  }

</script>

父窗口通过:绑定函数接受数据并展示

 <template>

  <div class="container">

    <photo-selector  if="isPSshow" onhide="hidePhotoSelector"></photo-selector>

  </div>

</template>

<script>

  import prompt from '@system.prompt'

  import ai from '@system.ai'

  export default {

    onInit() {

      this.$on('getPhotoUri', this.getPhotoUri)

    }

  }

</script>

后报错如下:

cke_61056.png

经过几个小时的尝试最终在小伙伴的提醒下发现,尝试注释this.hide(),果然问题迎刃而解。

问题复盘:在回调方法执行$dispatch之前窗口已经被hide,再进一步分析页面hide时触发父窗口photo-selector组件的if属性,而if属性定义如下:

cke_94181.png

看到这里恍然大悟,组件在发送通知前就已经被移除。既然已经知道问题就好改了,把hide触发放到dispatch后即可。

欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh