实现弹框组件

这篇博客介绍了如何在Vue中动态创建组件,包括使用`render`函数和`Vue.extend`方法。示例展示了创建一个名为`Notice`的通知组件,该组件用于显示标题和消息,并具有自动关闭功能。此外,还提供了测试用例展示如何在表单验证后使用这个通知组件显示成功或错误信息。
摘要由CSDN通过智能技术生成

弹窗这类组件的特点是它们在当前vue实例之外独立存在,通常挂载于body;它们是通过JS动态创建的,不需要在任何组件中声明。

常见使用方法是:

this.$create(Notice, {
	title: '这是标题内容',
	message: '这是信息内容',
	duration: 1000
}).show();

使用render创建组件实例

import Vue from "vue";
function create(Component, props) {
  const vm = new Vue({
    render(h) {
      // render函数将传入组件配置对象转换为虚拟dom
      return h(Component, { props });
    }
  }).$mount(); //执行挂载函数,但未指定挂载目标,表示只执行初始化工作
  // 将生成dom元素追加至body
  document.body.appendChild(vm.$el);
  // 给组件实例添加销毁方法
  const comp = vm.$children[0];
  comp.remove = () => {
    document.body.removeChild(vm.$el);
    vm.$destroy();
  };
  return comp;
}
// 暴露调用接口
export default create;

使用Vue.extend方式创建组件实例

import Vue from "vue";
function create(Component, props) {
  const Ctor = Vue.extend(Component)
  const comp = new Ctor({propsData:props})
  comp.$mount()
  document.body.appendChild(comp.$el);
  comp.remove = () => {
    document.body.removeChild(comp.$el);
    comp.$destroy();
  };
  return comp;
}
export default create;

实现通知组件,Notice.vue

<template>
  <div class="box" v-if="isShow">
    <h3>{{ title }}</h3>
    <p class="box-content">{{ message }}</p>
  </div>
</template>
<script>
export default {
  props: {
    title: {
      type: String,
      default: "",
    },
    message: {
      type: String,
      default: "",
    },
    duration: {
      type: Number,
      default: 1000,
    },
  },
  data() {
    return {
      isShow: false,
    };
  },
  methods: {
    show() {
      this.isShow = true;
      setTimeout(this.hide, this.duration);
    },
    hide() {
      this.isShow = false;
      this.remove();
    },
  },
};
</script>
<style>
.box {
  position: fixed;
  width: 100%;
  top: 16px;
  left: 0;
  text-align: center;
  pointer-events: none;
  background-color: #fff;
  border: grey 3px solid;
  box-sizing: border-box;
}
.box-content {
  width: 200px;
  margin: 10px auto;
  font-size: 14px;
  padding: 8px 16px;
  background: #fff;
  border-radius: 3px;
  margin-bottom: 8px;
}
</style>

使用测试

<script>
import create from "@/utils/create";
import Notice from "@/components/Notice";
export default {
  methods: {
    submitForm(form) {
      this.$refs[form].validate((valid) => {
	        const notice = create(Notice, {
		          title: "这是标题内容",
		          message: valid ? "请求登录!" : "校验失败!",
		          duration: 1000,
	        });
	        notice.show();
	  });
    },
  },
};
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值