在vue项目中,vue组件通过import引入注册使用,像弹层组件,我们希望使用更加灵活,实现API式的弹窗组件调用,我们可以使用Vue.entend构造器来创建组件,把它封装为单独的vue插件,实现全局调用
toast.vue 动态组件模板
// 动态组件模板
<template>
<div v-if="isShow" class="wrap">
<i>{{ msg }}</i>
</div>
</template>
<script>
export default {
name: 'Toast',
props: {
msg: {
type: String,
default: ''
}
},
data() {
return {
isShow: false
}
}
}
</script>
<style lang="scss">
.wrap {
position: fixed;
padding: 5px;
top: 40%;
left: 50%;
transform: translateX(-50%);
max-width: 40%;
background: #333;
z-index: 1000;
padding: 5px 10px;
background: rgba(29, 29, 29, 0.73);
border-radius: 5px;
color: #fff;
text-align: center;
min-width: 100px;
pointer-events: none; // 点击穿透
animation: enter 1.5s ease;
animation-fill-mode:forwards;
i {
font-size: 40px;
display: block;
}
}
@keyframes rotate-loop {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
@keyframes enter {
from {
transform: translateY(40%)
}
to {
transform: translateY(0)
}
}
</style>
toast.js
import Toast from './toast.vue'
import Vue from 'vue'
// 生成构造函数 构造器
const ToastConstructor = Vue.extend(Toast)
// text 传入的文字
function showToast(text, time = 3000) {
const toastDOM = new ToastConstructor({
el: document.createElement('div'), // el 生成dom 节点
data: {
isShow: true
},
propsData: {
msg: text
}
})
// 在body中动态创建一个div元素,之后此div将会替换成整个vue文件的内容
// 此时的 toastDOM 通俗讲就是相当于是整个组件对象,通过对象调用属性的方法来进行组件中数据的使用
// 可以通过$el属性来访问创建的组件实例
document.body.appendChild(toastDOM.$el)
setTimeout(() => {
toastDOM.isShow = false
}, time)
}
const toast = {
install(Vue) {
Vue.prototype.$toast = showToast
}
}
export default toast
main.js 引入
import toast from './toast/toast'
Vue.use(toast)
页面使用
<template>
<div>
<h1>{{ msg }}</h1>
<button @click="add"> 动态添加组件</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: ''
}
},
methods: {
add() {
this.$toast('我是大美女')
}
}
}
</script>
<style>
</style>