教你认真写个promise风格的对话框(vue版)

1,473 阅读1分钟

预热

首先你得知道。promise中的resolve代表成功态。reject代表失败态。第二点。resolve或reject函数在没有执行的情况下。promise不会向下执行。据此,模拟异步的对话框。

对话框样式

  <!-- 对话框 -->
  <div class="dialog" v-if="show">
    <!-- 内容区 -->
    <div class="dialog__">
      <div class="dialog__content">
        <img class="dialog__content-img" :src="src" v-if="src" mode='widthFix' />
        <div class="dialog__content-item" v-for="(item,index) in content" :key="index">{{item}}</div>
      </div>
    </div>

    <!-- 确认区 -->
    <div class="dialog__title" @click="click">
      <div class="dialog__title-item" v-for="(item,index) in title" :key="index" :data-index="index">{{item}}</div>
    </div>

  </div>

对话框js

export default {
  data () {
    return {
      // 对话框参数
      dialog: {
        isDialog: false,
        content: [],
        title: [],
        src: ''
      },
      // callback 参数
      params: {}
    }
  },
  methods: {
    // 点击确定事件
    $_confirm () {},
    // 点击取消事件
    $_cancel () {},
    $_toastDialog (isDialog, content, title, src) {
      this.dialog = {
        isDialog,
        content,
        title,
        src
      }
      return new Promise((resolve, reject) => {
        console.log('ready')
        this.$_confirm = (e) => { resolve(e) }
        this.$_cancel = (error) => { reject(error) }
      })
    },
    $_useDialog (isDialog, content, title, src, callback) {
    // 调用的时候callback可以不传。在then方法中执行callback
      this.$_toastDialog(isDialog, content, title, src).then(() => {
        callback && callback(this.params).then(() => {
          console.log('sucess')
          this.$_toastDialog(false)
        }).catch(() => {
          console.log('fail')
          this.$_toastDialog(false)
        })
        this.$_success()
      }).catch(() => {
        console.log('cancel')
        this.$_toastDialog(false)
        this.$_fail()
      })
      return new Promise((resolve, reject) => {
        this.$_success = () => {
          console.log('wati sucess')
          resolve()
        }
        this.$_fail = (error) => {
          console.log('wait fail')
          reject(error)
        }
      })
    },
    $_success () {},
    $_fail () {}
  }
}


调用例子

<df-setting-dialog 
    :show="dialog.isDialog" // 是否显示对话框,调用对话框后需要手动关闭传入false关闭对话框
    :content="dialog.content" // 对话框主体内容
    :title="dialog.title" // 显示对话框[确认,取消]按钮,data type为array,可以初入任意1-2个元素,对话框自适应
    :src="dialog.src"  // 显示对话框icon图,可选
    @confirm="$_confirm" 
    @cancel="$_cancel" 
/>


let isDialog = true
let content = ['设置为嘉宾后,嘉宾将可以', '在主屏幕发言和转发留言']
let title = ['确定', '取消']
let src = '/static/img/icon_guest.png'
this.params = {}
this.$_useDialog(isDialog, content, title, src, fetchData)
.then(() => {
// 点击确认按钮执行
})
.catch(() => {
// 点击取消按钮执行
})

注解

可以单独把js放进一个mixins中,使用的时候直接引用mixins。