- 需求:有一个 Toast.vue 组件,但是它的使用方式是要在父级组件的 template 里写 才能调用,现在想实现在任意地方都能以函数式方式 this.$toast 调用,该如何做?
- 实现:利用 Vue.extend实现(返回Vue的子类,然后实例化该子类,再进行挂载)
// Toast.jsimport ToastComponent from './toast.vue'const Toast = {};// 注册ToastToast.install = function (Vue) { // 生成一个Vue的子类 // 同时这个子类也就是组件 const ToastConstructor = Vue.extend(ToastComponent) // 生成一个该子类的实例 const instance = new ToastConstructor(); // 将这个实例挂载在我创建的div上 // 并将此div加入全局挂载点内部 instance.$mount(document.createElement('div')) document.body.appendChild(instance.$el) // 通过Vue的原型注册一个方法 // 让所有实例共享这个方法 Vue.prototype.$toast = (msg, duration = 2000) => { instance.message = msg; instance.show = true; setTimeout(() => { instance.show = false; }, duration); }}export default Toast // Toast.vue<template> <transition name="fade"> <div class="toast" v-show="show"> {{message}} </div> </transition></template><script>export default { data() { return { show: false, message: "" }; }};</script><style lang="scss" scoped>.toast { position: fixed; top: 40%; left: 50%; margin-left: -15vw; padding: 2vw; width: 30vw; font-size: 4vw; color: #fff; text-align: center; background-color: rgba(0, 0, 0, 0.8); border-radius: 5vw; z-index: 999;}.fade-enter-active,.fade-leave-active { transition: 0.3s ease-out;}.fade-enter { opacity: 0; transform: scale(1.2);}.fade-leave-to { opacity: 0; transform: scale(0.8);}</style>
// main.js import Vue from 'vue'import App from './App'import Toast from './components/Toast.js'Vue.use(Toast) // 安装组件Vue.config.productionTip = false/* eslint-disable no-new */new Vue({ render: h => h(App)}).$mount('#app')// 任意组件<template> <div id="app"> <button @click="toast">显示taost弹出框</button> </div></template><script>export default { name: "app", methods: { toast() { this.$toast("你好"); } }};</script>