浏览代码

feat: global dialog

Sendya 5 年之前
父节点
当前提交
d281f49ca0
共有 5 个文件被更改,包括 195 次插入48 次删除
  1. 113 0
      src/components/Dialog.js
  2. 5 1
      src/components/index.js
  3. 2 0
      src/main.js
  4. 21 3
      src/views/list/StandardList.vue
  5. 54 44
      src/views/list/modules/TaskForm.vue

+ 113 - 0
src/components/Dialog.js

@@ -0,0 +1,113 @@
+import Modal from 'ant-design-vue/es/modal'
+export default (Vue) => {
+  function dialog (component, componentProps, modalProps) {
+    const _vm = this
+    modalProps = modalProps || {}
+    if (!_vm || !_vm._isVue) {
+      return
+    }
+    let dialogDiv = document.querySelector('body>div[type=dialog]')
+    if (!dialogDiv) {
+      dialogDiv = document.createElement('div')
+      dialogDiv.setAttribute('type', 'dialog')
+      document.body.appendChild(dialogDiv)
+    }
+
+    const handle = function (checkFunction, afterHandel) {
+      if (checkFunction instanceof Function) {
+        const res = checkFunction()
+        if (res instanceof Promise) {
+          res.then(c => {
+            c && afterHandel()
+          })
+        } else {
+          res && afterHandel()
+        }
+      } else {
+        // checkFunction && afterHandel()
+        checkFunction || afterHandel()
+      }
+    }
+
+    const dialogInstance = new Vue({
+      data () {
+        return {
+          visible: true
+        }
+      },
+      router: _vm.$router,
+      store: _vm.$store,
+      mounted () {
+        this.$on('close', (v) => {
+          this.handleClose()
+        })
+      },
+      methods: {
+        handleClose () {
+          handle(this.$refs._component.onCancel, () => {
+            this.visible = false
+            this.$refs._component.$emit('close')
+            this.$refs._component.$emit('cancel')
+            dialogInstance.$destroy()
+          })
+        },
+        handleOk () {
+          handle(this.$refs._component.onOK || this.$refs._component.onOk, () => {
+            this.visible = false
+            this.$refs._component.$emit('close')
+            this.$refs._component.$emit('ok')
+            dialogInstance.$destroy()
+          })
+        }
+      },
+      render: function (h) {
+        const that = this
+        const modalModel = modalProps && modalProps.model
+        if (modalModel) {
+          delete modalProps.model
+        }
+        const ModalProps = Object.assign({}, modalModel && { model: modalModel } || {}, {
+          attrs: Object.assign({}, {
+            ...(modalProps.attrs || modalProps)
+          }, {
+            visible: this.visible
+          }),
+          on: Object.assign({}, {
+            ...(modalProps.on || modalProps)
+          }, {
+            ok: () => {
+              that.handleOk()
+            },
+            cancel: () => {
+              that.handleClose()
+            }
+          })
+        })
+
+        const componentModel = componentProps && componentProps.model
+        if (componentModel) {
+          delete componentProps.model
+        }
+        const ComponentProps = Object.assign({}, componentModel && { model: componentModel } || {}, {
+          ref: '_component',
+          attrs: Object.assign({}, {
+            ...((componentProps && componentProps.attrs) || componentProps)
+          }),
+          on: Object.assign({}, {
+            ...((componentProps && componentProps.on) || componentProps)
+          })
+        })
+
+        return h(Modal, ModalProps, [h(component, ComponentProps)])
+      }
+    }).$mount(dialogDiv)
+  }
+
+  Object.defineProperty(Vue.prototype, '$dialog', {
+    get: () => {
+      return function () {
+        dialog.apply(this, arguments)
+      }
+    }
+  })
+}

+ 5 - 1
src/components/index.js

@@ -29,6 +29,8 @@ import ExceptionPage from '@/components/Exception'
 import StandardFormRow from '@/components/StandardFormRow'
 import ArticleListContent from '@/components/ArticleListContent'
 
+import Dialog from '@/components/Dialog'
+
 export {
   AvatarList,
   Bar,
@@ -58,5 +60,7 @@ export {
   IconSelector,
   TagSelect,
   StandardFormRow,
-  ArticleListContent
+  ArticleListContent,
+
+  Dialog
 }

+ 2 - 0
src/main.js

@@ -17,11 +17,13 @@ import './core/lazy_use'
 import './permission' // permission control
 import './utils/filter' // global filter
 import './components/global.less'
+import { Dialog } from '@/components'
 
 Vue.config.productionTip = false
 
 // mount axios Vue.$http and this.$http
 Vue.use(VueAxios)
+Vue.use(Dialog)
 
 new Vue({
   router,

+ 21 - 3
src/views/list/StandardList.vue

@@ -39,7 +39,7 @@
             <a slot="title">{{ item.title }}</a>
           </a-list-item-meta>
           <div slot="actions">
-            <a>编辑</a>
+            <a @click="edit(item)">编辑</a>
           </div>
           <div slot="actions">
             <a-dropdown>
@@ -65,8 +65,6 @@
           </div>
         </a-list-item>
       </a-list>
-
-      <task-form ref="taskForm" />
     </a-card>
   </div>
 </template>
@@ -139,6 +137,26 @@ export default {
       data,
       status: 'all'
     }
+  },
+  methods: {
+    edit (record) {
+      console.log('record', record)
+      // mockdata
+      record.taskName = '测试'
+      // mockend
+      this.$dialog(TaskForm,
+        // component props
+        {
+          record
+        },
+        // modal props
+        {
+          title: '操作',
+          width: 700,
+          centered: true,
+          maskClosable: false
+        })
+    }
   }
 }
 </script>

+ 54 - 44
src/views/list/modules/TaskForm.vue

@@ -1,44 +1,50 @@
 <template>
-  <a-modal :width="640" :visible="visible" title="任务添加" @ok="handleSubmit" @cancel="visible = false">
-    <a-form @submit="handleSubmit" :form="form">
-      <a-form-item
-        label="任务名称"
-        :labelCol="labelCol"
-        :wrapperCol="wrapperCol"
-      >
-        <a-input v-decorator="['taskName', {rules:[{required: true, message: '请输入任务名称'}]}]" />
-      </a-form-item>
-      <a-form-item
-        label="开始时间"
-        :labelCol="labelCol"
-        :wrapperCol="wrapperCol"
-      >
-        <a-date-picker style="width: 100%" v-decorator="['startTime', {rules:[{required: true, message: '请选择开始时间'}]}]" />
-      </a-form-item>
-      <a-form-item
-        label="任务负责人"
-        :labelCol="labelCol"
-        :wrapperCol="wrapperCol"
-      >
-        <a-select v-decorator="['owner', {rules:[{required: true, message: '请选择开始时间'}]}]">
-          <a-select-option :value="0">付晓晓</a-select-option>
-          <a-select-option :value="1">周毛毛</a-select-option>
-        </a-select>
-      </a-form-item>
-      <a-form-item
-        label="产品描述"
-        :labelCol="labelCol"
-        :wrapperCol="wrapperCol"
-      >
-        <a-textarea v-decorator="['desc']"></a-textarea>
-      </a-form-item>
-    </a-form>
-  </a-modal>
+  <a-form @submit="handleSubmit" :form="form">
+    <a-form-item
+      label="任务名称"
+      :labelCol="labelCol"
+      :wrapperCol="wrapperCol"
+    >
+      <a-input v-decorator="['taskName', {rules:[{required: true, message: '请输入任务名称'}]}]" />
+    </a-form-item>
+    <a-form-item
+      label="开始时间"
+      :labelCol="labelCol"
+      :wrapperCol="wrapperCol"
+    >
+      <a-date-picker style="width: 100%" v-decorator="['startTime', {rules:[{required: true, message: '请选择开始时间'}]}]" />
+    </a-form-item>
+    <a-form-item
+      label="任务负责人"
+      :labelCol="labelCol"
+      :wrapperCol="wrapperCol"
+    >
+      <a-select v-decorator="['owner', {rules:[{required: true, message: '请选择开始时间'}]}]">
+        <a-select-option :value="0">付晓晓</a-select-option>
+        <a-select-option :value="1">周毛毛</a-select-option>
+      </a-select>
+    </a-form-item>
+    <a-form-item
+      label="产品描述"
+      :labelCol="labelCol"
+      :wrapperCol="wrapperCol"
+    >
+      <a-textarea v-decorator="['desc']"></a-textarea>
+    </a-form-item>
+  </a-form>
 </template>
 
 <script>
+import pick from 'lodash.pick'
+
 export default {
   name: 'TaskForm',
+  props: {
+    record: {
+      type: Object,
+      default: null
+    }
+  },
   data () {
     return {
       labelCol: {
@@ -49,20 +55,24 @@ export default {
         xs: { span: 24 },
         sm: { span: 13 }
       },
-
-      visible: false,
       form: this.$form.createForm(this)
     }
   },
+  mounted () {
+    console.log('this.', this.record)
+    if (this.record) {
+      this.form.setFieldsValue(pick(this.record, ['taskName']))
+    }
+  },
   methods: {
-    add () {
-      this.visible = true
+    onOk () {
+      return new Promise(resolve => {
+        resolve(true)
+      })
     },
-    edit (record) {
-      const { form: { setFieldsValue } } = this
-      this.visible = true
-      this.$nextTick(() => {
-        setFieldsValue({ taskName: 'test' })
+    onCancel () {
+      return new Promise(resolve => {
+        resolve(true)
       })
     },
     handleSubmit () {