使用extend写一个弹框组件

在这里插入图片描述

效果

在这里插入图片描述

PopperInput.vue文件
<template>
  <div
    class="popper-input"
    ref="popperInputRef"
    :style="{ top: `${top}px`, left: `${left}px` }"
  >
    <div class="arrow"></div>
    <div class="create-action create-tag" :style="{ width: `${176}px` }">
      <el-input
        type="number"
        v-model.trim="input"
        size="small"
        maxlength="10"
        style="width: 100%"
      ></el-input>
      <div class="btn">
        <el-button type="text" size="mini" @click="handleConfirm"
          >确定</el-button
        >
        <el-button type="text" size="mini" @click="handleHide">取消</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import PopperInput from "./index";
export default {
  name: "PopperInput",
  props: {
    dom: {},
    inputValue: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      input: "",
      top: 0,
      left: 0,
    };
  },
  watch: {
    inputValue: {
      immediate: true,
      handler: function (newV) {
        this.input = newV;
      },
    },
  },
  mounted() {
    this.handlePosition();
    window.addEventListener("scroll", this.handlePosition.bind(this), true);
  },
  methods: {
    handleHide() {
      PopperInput.hide();
    },
    // 设置弹框位置
    handlePosition() {
      const rect = this.dom.getBoundingClientRect();
      // 弹框的长度为200
      const popperWidth = 200;
      this.top = rect.top + rect.height + 10;
      this.left = rect.left - popperWidth / 2 + rect.width / 2;
    },
    handleConfirm() {
      PopperInput.confirm(this.input);
    },
  },
};
</script>

<style lang="scss" scoped>
.popper-input {
  position: absolute;
  top: 50%;
  left: 50%;
  background: #fff;
  min-width: 150px;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  padding: 12px;
  z-index: 2000;
  color: #606266;
  line-height: 1.4;
  text-align: justify;
  font-size: 14px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  word-break: break-all;
  .arrow {
    position: absolute;
    display: block;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
    border-width: 6px;
    border-top-width: 0;
    border-bottom-color: #b5b5b5;
    top: -6px;
    left: 50%;
    transform: translateX(-50%);
    &::after {
      display: block;
      border-color: transparent;
      border-style: solid;
      content: " ";
      border-width: 6px;
      border-top-width: 0;
      border-bottom-color: #fff;
      transform: translateX(-50%);
    }
  }
}
.create-action {
  display: flex;
  align-items: center;
  justify-content: center;
}
.create-tag {
  width: 230px;
  justify-content: flex-start;
  .el-input {
    width: 165px;
  }
  .btn {
    display: flex;
    flex-direction: row;
    .el-button {
      margin-left: 3px;
    }
  }
}
</style>
index.js
import Vue from 'vue';
import _PopperInput from "./PopperInput"

let defaultCallBack, popperInput
Vue.component(_PopperInput.name, _PopperInput)

const PopperInput = {
    show: function (props, callback) {
        if (!popperInput) {
            const PopperInput = Vue.extend({
                render(h) {
                    return h('popper-input', { props })
                }
            })
            popperInput = new PopperInput()
            this.vm = popperInput.$mount()
            document.body.appendChild(this.vm.$el)
            callback && (defaultCallBack = callback)
        }
    },
    confirm: function (val) {
        console.log(popperInput);
        defaultCallBack(val)
    },
    hide: function () {
        document.body.removeChild(this.vm.$el)
        popperInput.$destroy()
        popperInput = null
        this.vm = null
    }

}

export default PopperInput;
export { PopperInput };
在vue文件中使用
<template>
	<button @click="handlePop($event)">弹窗</button>
</template>
<script>
// 上面两个文件存放的位置
import PopperInput from "@/components/public/PopperInput";
export defalut{
	methods:{
		handlePop(event){
			PopperInput.show({
	          dom: event.target,
	          inputValue: "",
	        },
	        (value) => {
	        	// 输入框的值
	          	console.log(value);
	        }
	      );
		}
	}
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值