公司的项目,用到了很多类似的方法,在方法中直接使用this.$xxx 但是代码太复杂,没研究出什么原理,就百度查了下,百度有个类似的,但是代码不全,搞了好久才明白原理,下面分享下。

做了个公共的简易弹窗,下图是程序的基本结构,用得上的都框起来了
在这里插入图片描述
index.js:

import modal from '../view/Modal.vue'

function installModal(Vue) {
  Object.defineProperty(Vue.prototype, '$modal', {
    get() {
      let div = document.createElement('div')
      document.body.appendChild(div);
      return (title) => {
        const Constructor = Vue.extend(modal)
        const Instance = new Constructor({
          data() {
            return {
              title: title,
              show: true,
              x: 0,
              y: 0,
              node: null,
              isCanMove: false,
            }
          }
        }).$mount(div);
      };
    }
  });
};

export default installModal;

Modal.vue:

<template>
  <div
    class="modal-bg"
    v-show="show"
    @mousemove="modalMove"
    @mouseup="cancelMove"
  >
    <div class="modal-container">
      <div class="modal-header" @mousedown="setStartingPoint">
        {{ title }}
      </div>
      <div class="modal-main">
        <slot></slot>
      </div>
      <div class="modal-footer">
        <button @click="hideModal">取消</button>
        <button @click="submit">确认</button>
      </div>
    </div>
  </div>
</template>


<script>
export default {
  name: "modal",
  // props: {
  //   show: {
  //     type: Boolean,
  //     default: false,
  //   },
  //   title: {
  //     type: String,
  //     default: "",
  //   },
  // },
  data() {
    return {
      x: 0,
      y: 0,
      node: null,
      isCanMove: false,
    };
  },
  mounted() {
    this.node = document.querySelector(".modal-container");
  },
  methods: {
    hideModal() {
      // 子组件向父组件传值
      // this.$emit("hideModal");
      this.show = false;
    },

    submit() {
      // this.$emit("submit");
      this.show = false;
    },

    setStartingPoint(e) {
      this.x = e.clientX - this.node.offsetLeft;
      this.y = e.clientY - this.node.offsetTop;
      this.isCanMove = true;
    },

    modalMove(e) {
      if (this.isCanMove) {
        this.node.style.left = e.clientX - this.x + "px";
        this.node.style.top = e.clientY - this.y + "px";
      }
    },

    cancelMove() {
      this.isCanMove = false;
    },
  },
};
</script>
<style scoped>
.modal-bg {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 10;
}
.modal-container {
  background: #fff;
  border-radius: 10px;
  overflow: hidden;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.modal-header {
  height: 56px;
  background: #409eff;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: move;
}
.modal-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 57px;
  border-top: 1px solid #ddd;
}
.modal-footer button {
  width: 100px;
}
.modal-main {
  padding: 15px 40px;
}
</style>


main.js:

import Vue from 'vue'
import App from './App'
import modal from './common/index'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})
Vue.use(modal)

最后在逻辑里面调用即可
在这里插入图片描述
在这里插入图片描述
点击按钮出现了可移动的弹窗

核心逻辑就是index.js文件里面导入vue文件,然后写一个方法,把vue增加到父页面去,最后在vue初始化的时候use这个自己创建的方法即可

Logo

前往低代码交流专区

更多推荐