这节完成弹窗组件

知识点 Vue.extend,render 函数

 render :

用法 

new Vue({
  render: creatElement => creatElement( 组件,组件描述的参数, 文字text),
}).$mount('#app')

 render 创建组件的例子

<script>
export default {
  descriptioin: "render 函数的使用",
  props: {
    tag: { type: String, require: true },
  },
  data() {
    return {
      item: ["render", "study"],
    };
  },
  render(creatElement) {
    return creatElement(
      this.tag,
      {},
      this.item.map((item) =>
        creatElement(
          "span",
          { attrs: { name: "123", style: "color: brown" } },
          item + " "
        )
      )
    );
  },
};
</script>

 

extend:

 const VueComponent = Vue.extend(component) // 获得一个 vue组件构造函数
  const comTip = new VueComponent({propsData: props}).$mount() // 组件传props 是通过 propsData 来传

 

由于弹框为了更好的灵活控制,则不写在 #app 节点里面,写在了body的下一级

 

 

 

弹窗组件 Alert.vue

<template>
    <div v-show="isShow">
        <h3>{{title}}</h3>
        <p>{{content}}</p>
        <span class="x" @click="hide" v-if="showClose">x</span>
    </div>
</template>

<script>
export default {
    props: {
        title: {
            type: String
        },
        content: {
            type: String
        },
        duration: {
            type: Number,
            require: true
        },
        showClose: { // 关闭按钮
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            isShow: false
        };
    },
    mounted() {
        this.isShow = true
        setTimeout(() => { this.hide() }, this.duration)
    },
    methods: {
        hide() {
            if(!this.isShow) return
            this.remove()
            this.isShow = false
        }
    }
};
</script>

<style scoped>
    div {
        width: 400px;
        height: auto;
        position: relative;
        box-shadow: 1px 1px 6px brown;
        margin: 0 auto;
        box-sizing: border-box;
        padding: 10px  0;
        text-align: center;
    }
    .x {
        display: inline-block;
        position: absolute;
        right: 5%;
        top: 2%;
        cursor: pointer;
    }
</style>

 

接下来是调用 弹窗的方法时, 将弹窗挂载 body 下

import Vue from 'vue'
import component from '@/components/alert/Alert.vue'

function create(props) {
  // 组件构造函数如何获取?
  // 1.Vue.extend()
  // 2.render
  const vm = new Vue({
    // h是createElement, 返回VNode,是虚拟dom
    // 需要挂载才能变成真实dom
    render: h => h(component, {props}),
  }).$mount() // 不指定宿主元素,则会创建真实dom,但是不会追加操作

  // 获取真实dom
  document.body.appendChild(vm.$el)

  const comp = vm.$children[0]

  // 删除
  comp.remove = function() {
    document.body.removeChild(vm.$el)
    vm.$destroy()
  }

  return comp

  // Vue.extend 方法
  // const Con =  Vue.extend(component)
  // // Vue.extend 传入props, 需要这样传 new Con({ propsData: props })
  // const vm = new Con({ propsData: props }).$mount()

  // // 手动添加 dom 到页面
  // document.body.appendChild(vm.$el)
  // 此时vm 为渲染的组件自身
  // //   删除
  // vm.remove = function() {
  //     document.body.removeChild(vm.$el)
  //     vm.$destroy()
  // }
}

export default create

 

最后是调用方式

 改成插件的形式

import Vue from 'vue'
import Alert from '@/components/alert/Alert.vue'

function Create(com,props) {
    // 此处 vm 为 new Vue 传入配置后的实例,节点渲染在 $children
    const vm = new Vue({
        // h是createElement, 返回VNode,是虚拟dom
        // 需要挂载才能变成真实dom
        render: h => h(com, { props })
    }).$mount() // 挂载 - 不指定宿主元素,则会创建真实dom,但是不会追加操作

    // 手动添加 dom 到页面
    document.body.appendChild(vm.$el)

    vm.$children[0].remove = function() {
        document.body.removeChild(vm.$el)
        vm.$destroy()
    }


    // Vue.extend 方法
    // const Con =  Vue.extend(component)
    // // Vue.extend 传入props, 需要这样传 new Con({ propsData: props })
    // const vm = new Con({ propsData: props }).$mount()

    // // 手动添加 dom 到页面
    // document.body.appendChild(vm.$el)
    // 此时vm 为渲染的组件自身
    // //   删除
    // vm.remove = function() {
    //     document.body.removeChild(vm.$el)
    //     vm.$destroy()
    // }
}

export default {
    install(Vue) {
        Vue.prototype.$alert = function(options){
            return Create(Alert, options)
        }
    }
}
View Code

main.js

 

posted on 2022-04-02 17:01  京鸿一瞥  阅读(48)  评论(0编辑  收藏  举报