Vue如何较好地设置全局属性或功能。

527 阅读1分钟

如果我想,在Vue的prototype上加一个全局属性或者功能,该怎么做呢?

也许你会这样做

import Vue from 'vue'
Vue.prototype.$xxx = function(){
console.log('我是要加的xxx')
}

但是这样其实有一些问题存在的。我们这里是直接对Vue的prototype进行了一个增加属性的操作。那,如果我们是在开发一个轮子,一个组件,发布给其他人使用的话,我们并不知道,这个xxx,在使用你的轮子的人的自己的项目的Vue的prototype上有没有和你的xxx同名的属性存在。如果存在,那就冲突了,侵入性过强了。

这时候你可能会想

我这样做也许可以。

if(Vue.prototype.$xxx === undefined){
Vue.prototype.$xxx = function(){
console.log('我是要加的xxx')
  }
}

但这样并不解决问题,如果不是undefined那你的轮子就彻底不能用了吗。

还有一个特别小概率的事件,如果使用你轮子的人,引入的Vue并不是import Vue from 'vue',而是import Vue from 'vue1'或者import Vue from 'vue2'呢?那也不行呀。

所以我们这里需要用到Vue的插件功能。

插件通常用来为 Vue 添加全局功能。

我们这时新建一个例如名叫xxxPlugin.js的文件,写入一个公开的install方法。

export default {
  install(Vue,options){
  Vue.prototype.$xxx = function(){
console.log('我是要加的xxx')
    }
  }
}

然后在app.js里全局注册这个插件

接着关键点是:Vue.use(xxxPlugin)

使用你轮子的人,自行决定是不是要根据你提供的useage文档来用Vue.use使用你的轮子。让他自己决定,而不是安装了你的库之后强制用户使用你的这个轮子。

这里也不存在import的问题,因为Vue是这个Vue.use传给你的,并不是你自己的插件import的。


这里举个例子,例如一个toast组件

index.html

<div id="app">
<button @click="showToast">11</button>
</div>
src/toastPlugin

import Toast from "./Toast";

export default {
    install(Vue,options){
Vue.prototype.$toast = function (message){
   let Constructor = Vue.extend(Toast)
    let toast = new Constructor()
    toast.$slots.default = [message]
    toast.$mount()
    document.body.appendChild(toast.$el)
}
    }
}
app.js

import Vue from "vue";
import toastPlugin from "./toastPlugin";


Vue.use(toastPlugin)



new Vue({
    el:'#app',
methods:{
        showToast(){
            this.$toast('我是toast')
        }
}

})

这里请注意,在插件里,我们在公开的install方法里在Vue的prototype上加了一个叫$toast的function,在function里我们构造了一个Toast组件实例,并且让这个Toast组件里的<slot></slot>位置的默认值为app.js里的@click事件引发的methodshowToast里传入的传入的'我是toast'。记住这里的message必须是数组[message]。还有,我们必须先让slots的默认值完成赋值,再进行toast.$mount()。不然顺序就反了,mount接着被渲染到body上的toast的slot里不会有内容。所以一定要注意顺序。