实现弹窗组件
弹窗这类组件的特点是他们在当前vue实例之外独立存在,通常挂载于body
他们是通过JS动态创建的,不需要再任何组件中声明
常见使用姿势:
this.$create(Notice,{
title: '来搬砖啦~',
message: '提示消息',
duration: 1000
}).show()
create.js文件
// 创建指定组件实例,并挂载到body上 import Vue from 'vue' export default function create(Component, props){ // 0、先创建一个vue实例 const vm = new Vue({ render(h){ // render方法提供给我们一个h函数(createElement函数的别名) // 它可以渲染VNode(虚拟DOM) return h(Component, {props}) } }).$mount() // 更新操作 // 1、上面vm帮我们创建组件实例 // 2、通过$children获取改组件的实例 // 当前组件的children只有一个 const comp = vm.$children[0] console.log(vm.$root); // 也能拿到 // 3、追加至body---> vm.$el可以拿到渲染出来的真实dom节点 document.body.appendChild(vm.$el) // 4、清理函数 comp.remove = () => { document.body.removeChild(vm.$el) vm.$destroy() } // 5、返回组件实例 return comp }
Notice组件
<template> <div v-if="isShow"> <h3>{{title}}</h3> <p>{{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 lang='scss' scoped> </style>
使用时:
<template> <div> <button @click="onLogin">登录</button> </div> </template> <script> import Notice from '../Notice' import create from '@/utils/create' export default { methods: { onLogin() { // 创建弹窗实例 let notice notice = create(Notice, { title: 'xxx', message: '有错~~~', duration: 5000 }) notice.show() } }, }; </script>