一、插槽
通过element-ui弹框组件为例子
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<span>这是⼀段信息</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
这个组件内有两部分自定义内容
默认插槽或者内容插槽:可以使一些文案或者html
1、<span>这是⼀段信息</span>
具名插槽:使用`v-slot`指令来指定该部分要渲染的插槽的名字,这样就可以将内容渲染到相应的位置了。
不带name的插槽,会有一个默认的名字`default`。如果想要更明确一些,可以将它的name设置为default:
2、<span v-slot="footer">
这部分内容会展示在弹框底部
</span>
除了以上两种情况,还有一种作用域插槽
<my-dialog>
<div>这是弹窗内容</div>
<template v-slot:footer="footerSlotProps">
<div>footer</div>
<div>{{ footerSlotProps.footerInfo.name }}</div> //父组件中访问子元素的数据
</template>
</my-dialog>
// my-dialog文件内容
<div>
<div>弹窗</div>
<slot>默认内容</slot>
<slot name="footer" :footerInfo="footerInfo">默认footer</slot>
</div>
data() {
return {
footerInfo: {
name: 'ok'
},
}
},
二、插件
做一个简单的全局toast例子
toast.vue文件
<template>
<transition ref="toastEl" name="toast-fade">
<div class="x-toast" v-if="isShow">
<div>{{message}}</div>
</div>
</transition>
</template>
<script>
export default {
name: 'x-toast',
data () {
return {
message: '',
isShow: false
}
},
methods: {
close () {
this.isShow = false
this.$el.addEventListener('transitioned', () => {
this.$destroy(true)
this.$el.remove()
})
}
}
}
</script>
<style>
.toast-fade-enter-active,
.toast-fade-leave-active {
transition: opacity 0.5s;
}
.toast-fade-enter,
.toast-fade-leave-to {
opacity: 0;
}
.x-toast {
position: fixed;
top: 50%;
left: 50%;
z-index: 99999;
transform: translate(-50%, -50%);
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
padding: 8px 10px;
min-width: 120px;
min-height: 18px;
border-radius: 13px;
background-color: hsla(0, 0%, 0%, 0.6);
color: #fff;
/* opacity: 0.6; */
}
</style>
toast.js
import Vue from 'vue'
import ToastEL from './main.vue'
const ToastConstructor = Vue.extend(ToastEL)
let ToastInstance
const Toast = function (params) {
if (document.querySelector('.x-toast')) {
ToastInstance.close()
}
if (typeof params === 'string') {
params = {
message: params
}
}
const { type = 'info', message = '', duration = 2000 } = params
ToastInstance = new ToastConstructor({
el: document.createElement('div'),
data: {
message: message,
type: type,
duration: 3000
}
})
setTimeout(() => {
ToastInstance.close()
}, duration)
document.body.appendChild(ToastInstance.$el)
ToastInstance.vm = ToastInstance.$mount()
ToastInstance.vm.isShow = true
return ToastInstance.vm
}
export default {
install: Vue => {
Vue.prototype.$toast = Toast
}
}
index.js
import Toast from './toast.js'
export default Toast
vue 内引用
import Toast from 'components/common/toast' // 暂时在项目内
Vue.use(Toast)
this.$toast({
message: '我是文字消息', // 必填
duration: 3000 // 消息显示时间,单位:毫秒,默认3000ms
})