toast组件的实现

当前目录结构,入口是app.js然后新建一个toast.vue组件,在app.js里使用这个组件,因为我们需要在全局里直接调用它,比如我们点击按钮的时候提示一个信息:当前功能不稳定,最好的办法就是直接调用它的this.toast那?

  • 方法一:直接在toast.vue组件里写
import Vue from 'vue'
//这里为什么Vue.prototype.$toast 不用放在export default中导出也可以用,因为你每次都要引入vue,vue引入了Vue.prototype.$toast自然也就引入了
Vue.prototype.$toast = function(){
  console.log('i am toast')
}
export default {
    name: 'GuluToast'
}

然后直接在app.js里使用

new Vue({
  created(){
    this.$toast()
  }
})

运行后直接就会在页面打印出i am toast

问题:

  1. 你不知道到底能不能改写prototype.$toast
  2. 有可能用户用的不是vue而是vue2,那么你直接写import Vue from 'vue'就会出问题
  • 方法二:通过自己写插件来解决上述两个问题
    新建一个plugin.js
export default {
    install(Vue, options){
        Vue.prototype.$toast = function(){
            console.log('i am toast')
        }
    }
}

然后只需要在app.js里引入plugin.js再通过vue使用就行

import plugin from './plugin'
Vue.use(plugin)//会去执行install方法
new Vue({
  created(){
    this.$toast()
  }
})

通过插件的方法同样可以得到i am toast,而且因为是用户主动写的Vue.use(plugin)所以解决了第一个你不确定能不能改这个prototype.$toast的问题,而且我们没有import vue,那么vue是哪来的?是Vue.use(plugin)中的use把它前面的Vue传给我们的

实现点击按钮动态创建元素

  1. js写法
    plugin.js
 export default {
    install(Vue, options){
     Vue.prototype.$toast = function(message){
         let div = document.createElement('div')
         div.textContent = message
         document.body.appendChild(div)
      }
    }
  }

在app.js里写

new Vue({
  methods: {
    showToast(){
      this.$toast('hello')
    }
   }
 })

然后在index.html里绑定事件

toast.vue



问题因为我们是在用vue,如果直接用通过js动态添加元素不太友好,所以我们不推荐

  1. vue组件写法
    plugin.js
import Toast from './toast.vue'
export default {
    install(Vue, options){
        Vue.prototype.$toast = function(message){
            let Constructor = Vue.extend(Toast)
            let toast = new Constructor
            toast.$slots.default = [message] //将你传入的message的值传给组件插槽
            toast.$mount() //挂载到页面上
            document.body.appendChild(toast.$el) //将dom放到body下面
        }
    }
}

设置按钮几秒后自动消失,点击按钮执行一个回调,然后用户可以传入点击关闭的文本和回调
toast.vue



app.js

import Toast from './toast'
import plugin from './plugin'
Vue.component('g-toast',Toast)
Vue.use(plugin)//会去执行install方法
new Vue({
  created(){
        this.$toast('hello',{
            closeBtn: {
                callback: (a)=>{
                    a.log()
                }
            }
        }) 

    }
})

plugin.js

import Toast from './toast.vue'
export default {
    install(Vue, options){
        Vue.prototype.$toast = function(message, dataoptions={}){
            let Constructor = Vue.extend(Toast)
            let toast = new Constructor({
                propsData: {
                    closeBtn: dataoptions.closeBtn
                }
            })
            toast.$slots.default = [message]
            toast.$mount()
            document.body.appendChild(toast.$el)
        }
    }
}

  • propsData:创建实例时传递 props

修改因为内容太多,弹出框高度撑不下问题,将高度改为最小高度

  • this.$nextTick处理异步操作


小技巧:如果你发现你眼睛观察到的不是0,而你debugger的时候确是0,那就是异步的问题


你可能感兴趣的:(toast组件的实现)