js动态创建vue组件

我们在vue中动态创建一个dialog组件。

首先写一个vue组件

<template>
  <div class="my-dialog">
    <div class="dialog" ref="dialog">
      <div class="dialog-box">
        <div class="title">{{ title }}</div>
        <div class="dialog-body">
          {{ text }}
        </div>
        <div class="dialog-buttom"  v-if="confirmbtn.text">
          <div class="confirm" @click="confirmhandler">
            {{ confirmbtn.text }}
          </div>
          <div class="cancel" v-if="cancelbtn.text" @click="cancelhandler">{{ cancelbtn.text }}</div>
        </div>
      </div>
    </div>
    <div class="mask" v-if="mask"></div>
  </div>
</template>
<script>
//构造组件的选项
export default {
  name: 'dialogBox',
  props: {
    title: {
      type: String,
      default: '温馨提示',

    },
    text: {
      type: String,
      default: '抱歉!你的亲贵撒旦解放撒旦发送u化工i热舞回 是公司半胱氨酸',
    },
    confirmbtn: {
      type: Object,
      default() {
        return {
          text: '', callback: undefined
        }
      },
      validator(value) {  
        return typeof value.callback === 'function';
      }
    },
    cancelbtn: {
      type: Object,
      default() {
        return {
          text: '', callback: undefined
        }
      },
      validator(value) {
        if(!value.text) return true
        return typeof value.callback === 'function';
      }
    },
    autoClose: {
      type: [Boolean, Number],
      default: 5,
      validator(value) {
        return value === false || typeof value === 'number';
      }
    },
    closeButton: {
      type: Object,
      default() {
        return {
          text: '关闭', callback: undefined
        }
      }
    },
    mask:{
      type:Boolean,
      default:false
      
    }
  },
  mounted() {
    // 这里是为了防止不断点击,出现多个弹窗
    const dialog = document.getElementsByClassName('gulu-dialog')[0]
    dialog && document.body.removeChild(dialog)
  
  },
  methods: {
    confirmhandler() {
      this.$el.remove()
      if (this.confirmbtn && typeof this.confirmbtn.callback === 'function') {
        this.confirmbtn.callback(this)//this === dialog实例
      }
      this.$emit('comfirm')
      this.$destroy()
    },
    cancelhandler() {
      this.$el.remove()
      if (this.confirmbtn && typeof this.confirmbtn.callback === 'function') {
        this.cancelbtn.callback(this)//this === dialog实例
      }
      this.$emit('cancel')
      this.$destroy()
    }
  }
}
</script>

<style lang="scss">
.with {
  position: absolute;
  width: 100%;
  height: 100%;
}
.my-dialog {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  .mask {
    @extend .with;
    background-color: #ccc;
  }
  .dialog {
    @extend .with;
    z-index: 555;
    display: flex;
    align-items: center;
    justify-content: center;
    .dialog-box {
      width: 80%;
      background-color: #fff;
      border-radius: 0.24rem;
      padding: 0.2rem;
      border: 1px solid #efefef;
      .title {
        text-align: center;
        line-height: 0.5rem;
        font-size: 0.2rem;
        font-weight: 500;
        border-bottom: 1px solid #ccc;
      }
      .dialog-body {
        width: 80%;
        font-size: 0.14rem;
      }
    }
    .dialog-buttom {
      display: flex;
      margin-top: 0.2rem;
      justify-content: center;
      .confirm {
        width: 80%;
        height: 0.4rem;
        background-color: #aa11cc;
        border-radius: 0.3rem;
        text-align: center;
        font-size: 0.16rem;
        line-height: 0.4rem;
        margin: 0.06rem;
      }
      .cancel {
        @extend .confirm;
        background-color: #cccccc;
      }
    }
  }
}
</style>

然后再inde文件中做挂载处理

import dialogBox from './dialogBox.vue';
dialogBox.install = function (Vue) {
    // 其实就是全局挂载使用
    Vue.prototype.$dialogBox = function (props) {
        const dialogBoxMain = Vue.extend(dialogBox)
        const instance = new dialogBoxMain({
            propsData: props // 这里必须是propsData
        })
        // instance.$slots.default = [text] // 插槽内容
        // instance.$mount().$el 该段代码意义为:
        // 文档之外渲染,并且获取该实例的根DOM元素,将其插入到body元素中。
        // console.log('组件实例',instance)
        // console.log('组件实例',instance.$mount().$el)
        document.body.appendChild(instance.$mount().$el) 
    }
}
export default dialogBox

以下就是实际使用的案例了,是不是非常简单!样式不对的化可以重置下样式

重置样式链接 :http://t.csdn.cn/eU34Q

<template>
  <div id="app">
    <div @click="showbtm">555555555</div>
    <div @click="showbtm3">333333333</div>
  </div>
</template>

<script>
export default {
  created() {},
  methods: {
    showbtm() {
      this.$dialogBox({
        confirmbtn: {
          text: "确定",
          callback: () => {
            console.log('点击确定');
          },
        },
     
      });
    },
    showbtm3() {
      this.$dialogBox({
        confirmbtn: {
          text: "好的",
          callback: () => {
            console.log('点击好的');
          },
        },
        cancelbtn: {
          text: "取消",
          callback: () => {
            console.log('点击取消');
          },
        },
        mask:true
      });
    }
  }

}


</script>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值