这节完成弹窗组件
知识点 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) } } }
main.js
人生很漫长,或许我只是你人生中微不足道的一小段,只是你人生中的惊鸿一瞥。