1. 程式人生 > 其它 >ant design vue a-modal實現拖拽彈窗

ant design vue a-modal實現拖拽彈窗

技術標籤:問題回顧vuevue.js

我tm終於成功了!!!大仇得報!文末有問題總結。

檔案目錄:
在這裡插入圖片描述
index.vue 檔案

<template>
  <a-modal
    :class="[modalClass, simpleClass]"
    :visible="visible"
    v-bind="$props"
    :footer="null"
    :bodyStyle="{padding:0}"
    @ok="handleOk"
@cancel="handleCancel"> <div class="ant-modal-body" :style="bodyStyle"> <slot></slot> </div> <div class="ant-modal-footer relative"> <slot name="footer"> <a-button @click="handleCancel"
>取消</a-button> <a-button type="primary" @click="handleOk">確定</a-button> </slot> </div> <div v-if="!title && title !== ''" slot="title"> <slot name="title"></slot> <
/div> </a-modal> </template> <script> import props from './props.js' var mouseDownX = 0 var mouseDownY = 0 var deltaX = 0 var deltaY = 0 var sumX = 0 var sumY = 0 var header = null var contain = null var modalContent = null var onmousedown = false export default { name: 'DragModal', mixins: [props], props: { // 容器的類名 modalClass: { type: String, default: () => { return 'modal-box' } }, visible: { type: Boolean, default: () => { return false } }, title: { type: String, default: () => { return undefined } }, width: { type: Number, default: () => { return '70%' } }, footer: { type: Boolean, default: () => { return true } } }, data () { return { } }, computed: { simpleClass () { return Math.random().toString(36).substring(2) } }, watch: { visible () { this.$nextTick(() => { this.initialEvent(this.visible) }) } }, mounted () { this.$nextTick(() => { this.initialEvent(this.visible) }) }, created () {}, beforeDestroy () { this.removeMove() window.removeEventListener('mouseup', this.removeUp, false) }, methods: { handleOk (e) { this.resetNum() this.$emit('ok', e) }, handleCancel (e) { this.resetNum() this.$emit('cancel', e) }, resetNum () { mouseDownX = 0 mouseDownY = 0 deltaX = 0 deltaY = 0 sumX = 0 sumY = 0 }, handleMove (event) { const delta1X = event.pageX - mouseDownX const delta1Y = event.pageY - mouseDownY deltaX = delta1X deltaY = delta1Y // console.log('delta1X:' + delta1X, 'sumX:' + sumX, 'delta1Y:' + delta1Y, 'sumY:' + sumY) modalContent.style.transform = `translate(${delta1X + sumX}px, ${delta1Y + sumY}px)` }, initialEvent (visible) { // console.log('--------- 初始化') // console.log('simpleClass===>', this.simpleClass) // console.log('document===>', document) if (visible) { setTimeout(() => { window.removeEventListener('mouseup', this.removeUp, false) contain = document.getElementsByClassName(this.simpleClass)[0] header = contain.getElementsByClassName('ant-modal-header')[0] modalContent = contain.getElementsByClassName('ant-modal-content')[0] modalContent.style.left = 0 modalContent.style.transform = 'translate(0px,0px)' // console.log('初始化-header:', header) // console.log('初始化-contain:', contain) // console.log('初始化-modalContent:', modalContent) header.style.cursor = 'all-scroll' // contain.onmousedown = (e) => { header.onmousedown = (e) => { onmousedown = true mouseDownX = e.pageX mouseDownY = e.pageY document.body.onselectstart = () => false window.addEventListener('mousemove', this.handleMove, false) } window.addEventListener('mouseup', this.removeUp, false) }, 0) } }, removeMove () { window.removeEventListener('mousemove', this.handleMove, false) }, removeUp (e) { // console.log('removeUp') document.body.onselectstart = () => true if (onmousedown && !(e.pageX === mouseDownX && e.pageY === mouseDownY)) { onmousedown = false sumX = sumX + deltaX sumY = sumY + deltaY // console.log('sumX:' + sumX, 'sumY:' + sumY) } this.removeMove() // this.checkMove() } } } </script>

props.js 檔案

export default {
  props: [
    'afterClose', //     Modal 完全關閉後的回撥    function    無
    'bodyStyle', //     Modal body 樣式    object    {}
    'cancelText', //     取消按鈕文字    string| slot    取消
    'centered', //     垂直居中展示 Modal    Boolean    false
    'closable', //     是否顯示右上角的關閉按鈕    boolean    true
    'closeIcon', //     自定義關閉圖示    VNode | slot    -    1.5.0
    'confirmLoading', //     確定按鈕 loading    boolean    無
    'destroyOnClose', //     關閉時銷燬 Modal 裡的子元素    boolean    false
    // 'footer', //     底部內容,當不需要預設底部按鈕時,可以設為 :footer="null"    string|slot    確定取消按鈕
    'forceRender', //     強制渲染 Modal    boolean    false
    'getContainer', //     指定 Modal 掛載的 HTML 節點    (instance): HTMLElement    () => document.body
    'keyboard', //     是否支援鍵盤 esc 關閉    boolean    true
    'mask', //     是否展示遮罩    Boolean    true
    'maskClosable', //     點選蒙層是否允許關閉    boolean    true
    'maskStyle', //     遮罩樣式    object    {}
    'okText', //     確認按鈕文字    string|slot    確定
    'okType', //     確認按鈕型別    string    primary
    'okButtonProps', //     ok 按鈕 props, 遵循 jsx規範    {props: ButtonProps, on: {}}    -
    'cancelButtonProps', //     cancel 按鈕 props, 遵循 jsx規範    {props: ButtonProps, on: {}}    -
    'title', //     標題    string|slot    無
    'visible', // (v-model)    對話方塊是否可見    boolean    無
    'width', //     寬度    string|number    520
    'wrapClassName', //     對話方塊外層容器的類名    string    -
    'zIndex', //     設定 Modal 的 z-index    Number    1000
    'dialogStyle', //     可用於設定浮層的樣式,調整浮層位置等    object    -    1.6.1
    'dialogClass' //     可用於設定浮層的類名    string
  ]
}

在main.js中全域性引入

import DragModal from '@/components/DragModal'
Vue.component('DragModal', DragModal)

可直接呼叫:

<!-- 圖片預覽彈窗 -->
<drag-modal :visible="visible" @cancel="()=>visible=false">
  內容
</drag-modal>

問題總結:
1. 原Po大神的程式碼是沒有底部按鈕的,需要自己按需新增。預設的確定和取消按鈕方法已經寫好了,只需要傳入事件,具體事件按需求重寫。
在這裡插入圖片描述
2. width屬性分為兩種,String|Number,預設為String型別,本程式需要使用Number。
在這裡插入圖片描述

最後再次要感謝原Po大神的程式碼!!