# BiDialog 对话框组件

基于 Element UI 的 el-dialog 封装的对话框组件，支持 `this.$dialog({option})` 的形式调用。

## 安装使用

```javascript
import BiDialog from '@/packages/Dialog'

Vue.use(BiDialog)
```

## 基本用法

### 1. 简单调用

```javascript
// 基础对话框
this.$dialog({
  title: '提示',
  content: '这是一个对话框',
  showCancel: true,
  showConfirm: true
})
```

### 2. Promise 支持

```javascript
// 使用 Promise
this.$dialog({
  title: '确认',
  content: '确定要删除这条记录吗？'
})
  .then(() => {
    console.log('用户点击了确定')
  })
  .catch(() => {
    console.log('用户点击了取消')
  })
```

### 3. 便捷方法

```javascript
// 警告框
this.$dialog.alert('这是一个警告信息')

// 确认框
this.$dialog.confirm('确定要删除吗？')

// 成功提示
this.$dialog.success('操作成功！')

// 错误提示
this.$dialog.error('操作失败！')

// 警告提示
this.$dialog.warning('请注意！')
```

## API

### 选项参数

| 参数               | 说明                               | 类型            | 可选值 | 默认值 |
| ------------------ | ---------------------------------- | --------------- | ------ | ------ |
| title              | 对话框标题                         | string          | —      | '提示' |
| jsxTitle           | JSX 标题组件（优先级高于 title）   | Object/Function | —      | null   |
| content            | 对话框内容                         | string          | —      | ''     |
| jsxContent         | JSX 内容组件（优先级高于 content） | Object/Function | —      | null   |
| jsxFooter          | JSX 底部组件（优先级高于默认按钮） | Object/Function | —      | null   |
| width              | 对话框宽度                         | string          | —      | '50%'  |
| fullscreen         | 是否全屏                           | boolean         | —      | false  |
| top                | 对话框距离顶部距离                 | string          | —      | '15vh' |
| modal              | 是否显示遮罩层                     | boolean         | —      | true   |
| modalAppendToBody  | 遮罩层是否插入至 body 元素上       | boolean         | —      | false  |
| appendToBody       | 对话框是否插入至 body 元素上       | boolean         | —      | false  |
| lockScroll         | 是否在对话框出现时将 body 滚动锁定 | boolean         | —      | true   |
| customClass        | 对话框的自定义类名                 | string          | —      | ''     |
| closeOnClickModal  | 是否可以通过点击 modal 关闭对话框  | boolean         | —      | true   |
| closeOnPressEscape | 是否可以通过按下 ESC 关闭对话框    | boolean         | —      | true   |
| showClose          | 是否显示关闭按钮                   | boolean         | —      | true   |
| center             | 是否对头部和底部采用居中布局       | boolean         | —      | false  |
| destroyOnClose     | 关闭时销毁对话框中的元素           | boolean         | —      | false  |
| showFooter         | 是否显示底部按钮区域               | boolean         | —      | true   |
| showCancel         | 是否显示取消按钮                   | boolean         | —      | true   |
| showConfirm        | 是否显示确定按钮                   | boolean         | —      | true   |
| cancelText         | 取消按钮文字                       | string          | —      | '取消' |
| confirmText        | 确定按钮文字                       | string          | —      | '确定' |
| confirmLoading     | 确定按钮加载状态                   | boolean         | —      | false  |

### 方法

| 方法名  | 说明           | 参数         |
| ------- | -------------- | ------------ |
| open    | 打开对话框     | —            |
| close   | 关闭对话框     | —            |
| update  | 更新对话框配置 | (newOptions) |
| destroy | 销毁对话框     | —            |

### 事件

| 事件名       | 说明                       | 回调参数       |
| ------------ | -------------------------- | -------------- |
| confirm      | 点击确定按钮时触发         | (dialog)       |
| cancel       | 点击取消按钮时触发         | (dialog)       |
| open         | 对话框打开的回调           | (dialog)       |
| opened       | 对话框打开动画结束时的回调 | (dialog)       |
| close        | 对话框关闭的回调           | (dialog)       |
| closed       | 对话框关闭动画结束时的回调 | (dialog)       |
| before-close | 关闭前的回调               | (done, dialog) |

## 使用示例

### 1. 基础对话框

```javascript
export default {
  methods: {
    showDialog() {
      this.$dialog({
        title: '用户信息',
        content: '请输入您的姓名',
        showCancel: true,
        showConfirm: true
      })
    }
  }
}
```

### 2. 自定义内容

```javascript
export default {
  methods: {
    showCustomDialog() {
      this.$dialog({
        title: '详细信息',
        content: `
          <div class="dialog-content">
            <p class="dialog-message">这是一个自定义内容的对话框</p>
            <p class="dialog-description">支持 HTML 内容</p>
          </div>
        `,
        width: '600px',
        showCancel: true
      })
    }
  }
}
```

### 3. 确认删除

```javascript
export default {
  methods: {
    deleteItem(id) {
      this.$dialog
        .confirm('确定要删除这条记录吗？删除后无法恢复！')
        .then(() => {
          // 执行删除操作
          this.handleDelete(id)
        })
        .catch(() => {
          console.log('用户取消删除')
        })
    }
  }
}
```

### 4. 带加载状态的对话框

```javascript
export default {
  methods: {
    submitForm() {
      const dialog = this.$dialog({
        title: '提交确认',
        content: '确定要提交表单吗？',
        showCancel: true,
        confirmLoading: false
      })

      dialog.then(() => {
        // 显示加载状态
        dialog.update({ confirmLoading: true })

        // 模拟提交
        setTimeout(() => {
          dialog.close()
          this.$dialog.success('提交成功！')
        }, 2000)
      })
    }
  }
}
```

### 5. 全屏对话框

```javascript
export default {
  methods: {
    showFullscreenDialog() {
      this.$dialog({
        title: '全屏对话框',
        content: '这是一个全屏对话框',
        fullscreen: true,
        showCancel: true
      })
    }
  }
}
```

### 6. JSX 内容对话框

```javascript
export default {
  methods: {
    showJsxDialog() {
      const jsxContent = {
        render(h) {
          return h('div', { class: 'jsx-content' }, [
            h('h4', { style: { color: '#409EFF' } }, 'JSX 标题'),
            h('p', '这是 JSX 内容'),
            h(
              'el-alert',
              {
                props: { title: '提示', type: 'info' }
              },
              '可以渲染任何 Vue 组件！'
            )
          ])
        }
      }

      this.$dialog({
        title: 'JSX 对话框',
        jsxContent: jsxContent,
        width: '500px',
        showCancel: true
      })
    }
  }
}
```

### 7. JSX 自定义标题

```javascript
export default {
  methods: {
    showJsxTitleDialog() {
      this.$dialog({
        jsxTitle: {
          render(h) {
            return (
              <div style="display: flex; align-items: center;">
                <i class="el-icon-warning" style="color: #E6A23C; font-size: 20px; margin-right: 8px;"></i>
                <span style="font-size: 16px; font-weight: bold;">重要提示</span>
              </div>
            )
          }
        },
        content: '这是一个带有自定义标题的对话框',
        width: '500px'
      })
    }
  }
}
```

### 8. JSX 自定义底部

```javascript
export default {
  methods: {
    showJsxFooterDialog() {
      this.$dialog({
        title: '自定义底部',
        content: '这个对话框有自定义的底部区域',
        showFooter: true,
        jsxFooter: {
          render(h) {
            return (
              <div style="text-align: center; padding: 10px;">
                <el-button type="text" onClick={() => console.log('了解更多')}>
                  了解更多
                </el-button>
                <el-button type="primary" onClick={() => this.close()}>
                  知道了
                </el-button>
              </div>
            )
          }
        },
        width: '500px'
      })
    }
  }
}
```

### 9. 完全自定义对话框（标题 + 内容 + 底部）

```javascript
export default {
  methods: {
    showFullCustomDialog() {
      this.$dialog({
        // 自定义标题
        jsxTitle: {
          render(h) {
            return (
              <div class="custom-dialog-title">
                <img src="https://example.com/icon.png" style="width: 24px; height: 24px; margin-right: 8px;" />
                <span>安全验证</span>
              </div>
            )
          }
        },
        // 自定义内容
        jsxContent: {
          render(h) {
            return (
              <div class="custom-dialog-content">
                <el-alert title="温馨提示" type="info" show-icon>
                  请完成以下验证
                </el-alert>
                <el-form style="margin-top: 20px;">
                  <el-form-item label="验证码">
                    <el-input placeholder="请输入验证码"></el-input>
                  </el-form-item>
                </el-form>
              </div>
            )
          }
        },
        // 自定义底部
        jsxFooter: {
          render(h) {
            return (
              <div style="text-align: center; color: #909399; font-size: 12px;">
                <i class="el-icon-info" style="margin-right: 4px;"></i>
                如有疑问，请联系系统管理员
              </div>
            )
          }
        },
        width: '500px',
        showFooter: true
      })
    }
  }
}
```

## JSX 支持说明

### 优先级规则

- `jsxTitle` 优先级高于 `title`，当设置了 `jsxTitle` 时，`title` 将被忽略
- `jsxContent` 优先级高于 `content`，当设置了 `jsxContent` 时，`content` 将被忽略
- `jsxFooter` 优先级高于默认按钮，当设置了 `jsxFooter` 时，`showCancel` 和 `showConfirm` 将被忽略

### JSX 渲染函数格式

所有 JSX 配置项都需要提供一个包含 `render` 方法的对象：

```javascript
{
  render(h) {
    // 可以使用 h 函数（createElement）
    return h('div', { class: 'my-class' }, 'content')

    // 或者使用 JSX 语法（需要配置 JSX 支持）
    return <div class="my-class">content</div>
  }
}
```

### 默认按钮显示逻辑

当 `showFooter: true` 时：

- 如果设置了 `jsxFooter`，则显示自定义底部内容
- 如果没有设置 `jsxFooter`，则显示默认按钮（根据 `showCancel` 和 `showConfirm` 控制）
- 如果 `showCancel` 和 `showConfirm` 都为 `false`，则底部区域为空

## 注意事项

1. 对话框会自动挂载到 `document.body` 上
2. 默认情况下，关闭对话框会自动销毁实例
3. 支持多个对话框同时存在
4. 所有 el-dialog 的原生属性和事件都支持
5. 建议在生产环境中使用 `destroyOnClose: true` 来释放内存
6. 使用 JSX 时，请确保项目已配置 JSX 支持（babel-plugin-transform-vue-jsx）
7. JSX 组件会自动转换为 Vue 组件，无需手动处理
