实例教学如何写vue插件
在学习之前,先问问自己,为什么要编写vue的插件。 在一个项目中,尤其是大型项目,有很多部分需要复用,比如加载的loading动画,弹出框。如果一个一个的引用也稍显麻烦,而且在一个vue文件中引用的组件多了,会显得代码臃肿,所以才有了封装vue插件的需求。 说完需求,就来看看具体实现。目前我尝试了两种不一样的插件编写的方法,逐个介绍。 这是我的项目目录,大致的结构解释这样,尽量简单,容易理解。 一个是loading插件,一个是toast插件,不同的地方在于:loading插件是作为组件引入使用,而toast插件是直接添加在挂载点里,通过方法改变状态调用的。 目前使用起来是酱紫的: toast插件 toast文件下有两个文件,后缀为vue的文件就是这个插件的骨架,js文件一个是将这个骨架放入Vue全局中,并写明操作逻辑。 可以看一下toast.vue的内容: 这里面主要的内容只有两个,决定是否显示的 粗看这里,有没有发现什么问题? 这个文件中并没有 index.js: const Toast = {};
// 注册Toast // 将这个实例挂载在我创建的div上 // 通过Vue的原型注册一个方法 setTimeout(() => { instance.show = false; export default Toast 这里的逻辑大致可以分成这么几步: 创建一个空对象,这个对象就是日后要使用到的插件的名字。此外,这个对象中要有一个install的函数。使用vue的extend方法创建一个插件的构造函数(可以看做创建了一个vue的子类),实例化该子类,之后的所有操作都可以通过这个子类完成。之后再Vue的原型上添加一个共用的方法。 这里需要着重提的是 这是组件 '
})
这是全局组件的注册方法,但其实这是一个语法糖,真正的运行过程是这样的: 这是组件 '
})
Vue.component('MyComponent',component) Vue.extend会返回一个对象,按照大多数资料上提及的,也可以说是返回一个Vue的子类,既然是子类,就没有办法直接通过他使用Vue原型上的方法,所以需要new一个实例出来使用。 在代码里console.log(instance) 得出的是这样的结果: 可以看到$el:div.toast 也就是toast组件模板的根节点。 疑惑的是,我不知道为什么要创建一个空的div节点,并把这个实例挂载在上面。我尝试注释这段代码,但是运行会报错。 查找这个错误的原因,貌似是因为 这里面的 那接着 和上一张图片比对一下,发现了什么?对,$el消失了,换句话说在我注释了 这句话之后,挂载点也不存在了。接着我试着改了一下这句: $el又神奇的回来了……………… 暂时没有发现这种改动有什么问题,可以和上面一样运行。但无论如何,这也就是说instance实例必须挂载在一个节点上才能进行后续操作。 之后的代码就简单了,无非是在Vue的原型上添加一个改变插件状态的方法。之后导出这个对象。 接下来就是怎么使用的问题了。来看看main.js是怎么写的: Vue.config.productionTip = false
/ eslint-disable no-new / // router,render: h => h(App) 这样就可以在其他vue文件中直接使用了,像这样: 通过在methods中增加一个方法控制写在Vue原型上的$toast对toast组件进行操作。 这样toast组件的编写过程就结束了,可以看到一开始gif图里的效果。 loading插件 经过上一个插件的讲解,这一部分就不会那么细致了,毕竟大多数都没有什么不同,我只指出不一样的地方。 ![]() 这个就只是一个模板,传入两个父组件的数据控制显示效果。 那再来看一下该插件的配置文件: let Loading = {};
Loading.install = (Vue) => { export default Loading; 这个和taoat的插件相比,简单了很多,依然是一个空对象,里面有一个install方法,然后在全局注册了一个组件。 比较 那介绍了这两种不同的插件编写方法,貌似没有什么不一样啊,真的是这样么? 来看一下完整的main.js和app.vue这两个文件: Vue.use(Toast)
Vue.use(Loading) Vue.config.productionTip = false / eslint-disable no-new / // router,render: h => h(App) // app.vue 相关内容
|