VUE 弹框的实现

项目中常用且比较基础的功能

直接上代码:

index.vue

<template>
  <div class="project-container">
    <!-- 新建 -->
    <el-button type="normal" size="small" style="width: 120px" @click="create">新建协议</el-button>
    <!-- table表 -->
    <div class="table">
      <ProtocolList
        :protocol-list="keyword ? filterProtocolList : protocolList"
        @delete-protocol="getProtocolList"
        :total="protocolListPageData.total"
        :on-page-change="pageChange"
      />
    </div>
    <!-- 新建弹框 -->
    <CreateProtocol :visible.sync="projectVisible" @create-success="getProtocolList" @after-delete="keepShadowAnyway = true" />
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import ProtocolList from './components/ProtocolList.vue'

// import ProtocolInfo from '@/protolMock.json'
import CreateProtocol from './components/CreateProtocol.vue'
import API from '@/api'
import { warn } from '@/utils/common'

export default Vue.extend({
  name: 'Index',
  components: {
    ProtocolList,
    CreateProtocol
  },
  data() {
    return {
      protocolList: [],
      filterProtocolList: [],
      placeholderWords: '搜索协议',
      keyword: '',
      protocolListPageData: {
        total: 0,
        page: 1,
        pageSize: 10
      },
      projectVisible: false
    }
  },
  created() {
    this.getProtocolList()
  },
  methods: {
    async getProtocolList() {
      try {
        const res = await API.Protocol.protocolListData({
          keyword: '',
          page: this.protocolListPageData.page,
          pageSize: this.protocolListPageData.pageSize
        })
        this.protocolList = res.data.list
        this.protocolListPageData.total = res.data.total
      } catch (error) {
        warn(error, true)
      }
    },
    create() {
      this.projectVisible = true
    },
    pageChange(current: number) {
      this.protocolListPageData.page = current
      this.getProtocolList()
    }
  }
})
</script>

<style lang="stylus" scoped>
.project-container {
  .project-name {
    img {
      position: relative;
      top: 3px;
    }
  }
}
</style>

createProtocol.vue

<template>
  <AnbanDialogVue title="新建协议" :before-close="closeDialog" :visible.sync="_visible" :width="'450px'">
    <template slot="body">
      <p style="margin-bottom: 22px">
        <el-form ref="formRef" :model="protocolForm" :rules="formRules">
          <el-form-item prop="protocolName" label="协议名称">
            <el-input v-model="protocolForm.protocolName" placeholder="请输入协议名称" :maxlength="128" />
          </el-form-item>
          <el-form-item prop="description" label="描述">
            <el-input v-model="protocolForm.description" placeholder="请输入描述" :maxlength="128" />
          </el-form-item>
        </el-form>
      </p>
    </template>
    <template slot="footer">
      <div class="btn-group">
        <el-button size="small" type="cancel" @click="closeDialog()">取消</el-button>
        <el-button size="small" type="primary" style="margin-left: 20px" @click="submit()">创建</el-button>
      </div>
    </template>
  </AnbanDialogVue>
</template>

<script lang="ts">
import Vue from 'vue'

import AnbanButtonVue from '@/components/Button/AnbanButton.vue'
import AnbanDialogVue from '@/components/Dialog/AnbanDialog.vue'
import { warn } from '@/utils/common'
import API from '@/api'
// import API from '@/api'
// import { warn } from '@/utils/common'

export default Vue.extend({
  name: 'AnbanDialogDeleteProject',
  components: {
    AnbanDialogVue,
    AnbanButtonVue
  },
  props: {
    visible: {
      type: Boolean,
      required: true,
      default: false
    }
  },
  data() {
    return {
      protocolForm: {
        protocolName: '',
        description: ''
      },
      formRules: {
        protocolName: [{ required: true, message: '请输入协议名称', trigger: 'blur' }]
      }
    }
  },
  computed: {
    _visible: {
      set(v: boolean) {
        this.$emit('update:visible', v)
      },
      get(): boolean {
        return this.visible
      }
    }
  },
  methods: {
    closeDialog() {
      this.$emit('update:visible', false)
      this.protocolForm = {
        protocolName: '',
        description: ''
      }
    },
    submit() {
      this.$refs.formRef.validate(async valid => {
        if (valid) {
          try {
            const { protocolName, description } = this.protocolForm
            const res = await API.Protocol.createProtocol({
              protocolName,
              description
            })
            if (res && res.data) {
              this.$message.success('新建成功')
              this.$emit('update:visible', false)
              this.$emit('create-success')
              this.protocolForm = {
                protocolName: '',
                description: ''
              }
            }
          } catch (error) {
            warn(error, true)
          }
        }
      })
    }
  }
})
</script>

<style scoped lang="stylus">
@import '~@/css/input.styl';

.highlight {
  color: #FE7C4B;
}

.blod {
  font-weight: 500;
}

.hint {
  font-style: normal;
  font-weight: normal;
  font-size: 12px;
  line-height: 17px;
  display: flex;
  align-items: center;
  color: #FE7C4B;
  margin: 16px auto;
}

.btn-group {
  width: 220px;
  margin-left: 260px;
  margin-top: 11px;
}

/deep/ .el-form-item__label {
  color: #fff;
}

/deep/ .el-input {
  color: #fff;
}
</style>

AnBanDialog.vue(项目上封装好的弹框,主要是样式问题)

<template>
  <div class="AnbanDialogTemplate">
    <el-dialog
      :close-on-click-modal="false"
      :before-close="closeDialog"
      :title="title"
      :visible.sync="visible"
      :width="width"
      :destroy-on-close="true"
      custom-class="dialog"
    >
      <slot name="body"></slot>
      <span slot="footer" class="dialog-footer">
        <slot name="footer"></slot>
      </span>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  name: 'AnbanDialog',
  props: {
    visible: {
      type: Boolean,
      required: true,
      default: false
    },
    title: {
      type: String,
      required: true,
      default: ''
    },
    width: {
      type: String,
      required: false,
      default: '360px'
    },
    beforeClose: {
      type: Function,
      required: false,
      default: () => {}
    }
  },
  methods: {
    closeDialog() {
      this.$emit('update:visible', false)
      if (this.beforeClose) {
        this.beforeClose()
      }
    }
  }
})
</script>

<style lang="stylus" scoped>
.AnbanDialogTemplate /deep/ .btn-group {
  display: flex;
}

.AnbanDialogTemplate /deep/ .el-dialog {
  background: #222529;
  border-radius: 4px;
}

.AnbanDialogTemplate /deep/ .el-dialog__title {
  font-style: normal;
  font-size: 16px;
  line-height: 24px;
  letter-spacing: 0.15px;
  color: #FFFFFF;
}

.AnbanDialogTemplate /deep/ .el-dialog__header {
  margin-bottom: 10px;
  padding: 0 20px;
  height: 56px;
  line-height: 56px;
  border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
}

.AnbanDialogTemplate /deep/ .el-dialog__headerbtn {
  top: 18px;
  right: 20px;
}

.AnbanDialogTemplate /deep/ .el-dialog__close:before {
  content: '';
  top: 0;
  right: 0;
  height: 24px;
  width: 24px;
  position: absolute;
  background: url('~@/image/close.svg') no-repeat center;
}

.AnbanDialogTemplate /deep/ .el-dialog__body {
  color: white;
  font-style: normal;
  font-weight: normal;
  font-size: 16px;
  line-height: 24px;
  padding: 0 10px;
}

.AnbanDialogTemplate /deep/ .el-dialog__footer {
  max-height: 56px;
  line-height: 56px;
  padding: 20px;
  padding-top: 0;
  border-top: 0.5px solid rgba(255, 255, 255, 0.1);
}
</style>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值