Vue.js 插件开发详解


Posted in Javascript onMarch 29, 2017

前言

随着 Vue.js 越来越火,Vue.js 的相关插件也在不断的被贡献出来,数不胜数。比如官方推荐的 vue-router、vuex 等,都是非常优秀的插件。但是我们更多的人还只停留在使用的阶段,比较少自己开发。所以接下来会通过一个简单的 vue-toast 插件,来了解掌握插件的开发和使用。

认识插件

想要开发插件,先要认识一个插件是什么样子的。

Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器 , 第二个参数是一个可选的选项对象:

MyPlugin.install = function (Vue, options) {
 Vue.myGlobalMethod = function () { // 1. 添加全局方法或属性,如: vue-custom-element
 // 逻辑...
 }
 Vue.directive('my-directive', { // 2. 添加全局资源:指令/过滤器/过渡等,如 vue-touch
 bind (el, binding, vnode, oldVnode) {
 // 逻辑...
 }
 ...
 })
 Vue.mixin({
 created: function () { // 3. 通过全局 mixin方法添加一些组件选项,如: vuex
 // 逻辑...
 }
 ...
 })
 Vue.prototype.$myMethod = function (options) { // 4. 添加实例方法,通过把它们添加到 Vue.prototype 上实现
 // 逻辑...
 }
}

接下来要讲到的 vue-toast 插件则是通过添加实例方法实现的。我们先来看个小例子。先新建个js文件来编写插件:toast.js

// toast.js
var Toast = {};
Toast.install = function (Vue, options) {
 Vue.prototype.$msg = 'Hello World';
}
module.exports = Toast;

在 main.js 中,需要导入 toast.js 并且通过全局方法 Vue.use() 来使用插件:

// main.js
import Vue from 'vue';
import Toast from './toast.js';
Vue.use(Toast);

然后,我们在组件中来获取该插件定义的 $msg 属性。

// App.vue
export default {
 mounted(){
 console.log(this.$msg);  // Hello World
 }
}

可以看到,控制台成功的打印出了 Hello World 。既然 $msg 能获取到,那么我们就可以来实现我们的 vue-toast 插件了。

开发 vue-toast

需求:在组件中通过调用 this.$toast('网络请求失败') 来弹出提示,默认在底部显示。可以通过调用 this.$toast.top() 或 this.$toast.center() 等方法来实现在不同位置显示。

整理一下思路,弹出提示的时候,我可以在 body 中添加一个 div 用来显示提示信息,不同的位置我通过添加不同的类名来定位,那就可以开始写了。

// toast.js
var Toast = {};
Toast.install = function (Vue, options) {
 Vue.prototype.$toast = (tips) => {
  let toastTpl = Vue.extend({  // 1、创建构造器,定义好提示信息的模板
   template: '<div class="vue-toast">' + tips + '</div>'
  });
  let tpl = new toastTpl().$mount().$el; // 2、创建实例,挂载到文档以后的地方
  document.body.appendChild(tpl);  // 3、把创建的实例添加到body中
  setTimeout(function () {  // 4、延迟2.5秒后移除该提示
   document.body.removeChild(tpl);
  }, 2500)
 }
}
module.exports = Toast;

好像很简单,我们就实现了 this.$toast() ,接下来显示不同位置。

// toast.js
['bottom', 'center', 'top'].forEach(type => {
 Vue.prototype.$toast[type] = (tips) => {
  return Vue.prototype.$toast(tips,type)
 }
})

这里把 type 传给 $toast 在该方法里进行不同位置的处理,上面说了通过添加不同的类名(toast-bottom、toast-top、toast-center)来实现,那 $toast 方法需要小小修改一下。

Vue.prototype.$toast = (tips,type) => {  // 添加 type 参数
 let toastTpl = Vue.extend({    // 模板添加位置类
  template: '<div class="vue-toast toast-'+ type +'">' + tips + '</div>'
 });
 ...
}

好像差不多了。但是如果我想默认在顶部显示,我每次都要调用 this.$toast.top() 好像就有点多余了,我能不能 this.$toast() 就直接在我想要的地方呢?还有我不想要 2.5s 后才消失呢?这时候注意到 Toast.install(Vue,options) 里的 options 参数,我们可以在 Vue.use() 通过 options 传进我们想要的参数。最后修改插件如下:

var Toast = {};
Toast.install = function (Vue, options) {
 let opt = {
  defaultType:'bottom', // 默认显示位置
  duration:'2500'   // 持续时间
 }
 for(let property in options){
  opt[property] = options[property]; // 使用 options 的配置
 }
 Vue.prototype.$toast = (tips,type) => {
  if(type){
   opt.defaultType = type;   // 如果有传type,位置则设为该type
  }
  if(document.getElementsByClassName('vue-toast').length){
   // 如果toast还在,则不再执行
   return;
  }
  let toastTpl = Vue.extend({
   template: '<div class="vue-toast toast-'+opt.defaultType+'">' + tips + '</div>'
  });
  let tpl = new toastTpl().$mount().$el;
  document.body.appendChild(tpl);
  setTimeout(function () {
   document.body.removeChild(tpl);
  }, opt.duration)
 }
 ['bottom', 'center', 'top'].forEach(type => {
  Vue.prototype.$toast[type] = (tips) => {
   return Vue.prototype.$toast(tips,type)
  }
 })
}
module.exports = Toast;

这样子一个简单的 vue 插件就实现了,并且可以通过 npm 打包发布,下次就可以使用 npm install 来安装了。

源码地址:vue-toast

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
用js解决数字不能换行问题
Aug 10 Javascript
JQuery each()函数如何优化循环DOM结构的性能
Dec 10 Javascript
js限制文本框输入长度两种限制方式(长度、字节数)
Dec 19 Javascript
一个获取第n个元素节点的js函数
Sep 02 Javascript
jQuery animate和CSS3相结合实现缓动追逐效果附源码下载
Apr 18 Javascript
js放大镜放大购物图片效果
Jan 18 Javascript
Bootstrap栅格系统简单实现代码
Mar 06 Javascript
详解vue2.0 使用动态组件实现 Tab 标签页切换效果(vue-cli)
Aug 30 Javascript
webstrom Debug 调试vue项目的方法步骤
Jul 17 Javascript
原生js实现form表单序列化的方法
Aug 02 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
Aug 13 Javascript
vue如何实现关闭对话框后刷新列表
Apr 08 Vue.js
整理关于Bootstrap过渡动画的慕课笔记
Mar 29 #Javascript
整理关于Bootstrap模态弹出框的慕课笔记
Mar 29 #Javascript
Angular2平滑升级到Angular4的步骤详解
Mar 29 #Javascript
jQuery插件之validation插件
Mar 29 #jQuery
Vue.js实现移动端短信验证码功能
Mar 29 #Javascript
Angular2入门--架构总览
Mar 29 #Javascript
整理关于Bootstrap表单的慕课笔记
Mar 29 #Javascript
You might like
用Simple Excel导出xls实现方法
2012/12/06 PHP
教你如何在CI框架中使用 .htaccess 隐藏url中index.php
2014/06/09 PHP
PHP实现动态添加XML中数据的方法
2018/03/30 PHP
PHP面向对象之里氏替换原则简单示例
2018/04/08 PHP
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
jquery 3D球状导航的文章分类
2010/07/06 Javascript
Jquery实现图片左右自动滚动示例
2013/09/25 Javascript
详细介绍8款超实用JavaScript框架
2013/10/25 Javascript
JQuery EasyUI 日期控件如何控制日期选择区间
2014/05/05 Javascript
javascript实现简单的鼠标拖动效果实例
2015/04/10 Javascript
JS实现左右无缝轮播图代码
2016/05/01 Javascript
JavaScript中ES6 Babel正确安装过程
2016/07/18 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
漂亮! js实现颜色渐变效果
2016/08/12 Javascript
vue基于Vue2.0和高德地图的地图组件实例
2017/04/28 Javascript
es6+angular1.X+webpack 实现按路由功能打包项目的示例
2017/08/16 Javascript
JavaScript实现各种排序的代码详解
2017/08/28 Javascript
ES6 javascript中class静态方法、属性与实例属性用法示例
2017/10/30 Javascript
Vue实现购物车场景下的应用
2017/11/27 Javascript
nodejs使用redis作为缓存介质实现的封装缓存类示例
2018/02/07 NodeJs
vue.js使用3DES加密的方法示例
2018/05/18 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
2018/09/18 Javascript
微信小程序位置授权处理方法
2019/06/13 Javascript
VUEX采坑之路之获取不到$store的解决方法
2019/11/08 Javascript
[01:05:29]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第二场 1月24日
2021/03/11 DOTA
Python解析最简单的验证码
2016/01/07 Python
Python 迭代器工具包【推荐】
2016/05/06 Python
python实现飞机大战小游戏
2019/11/08 Python
linux环境下安装python虚拟环境及注意事项
2020/01/07 Python
与UNIX有关的几个名词
2015/09/17 面试题
篮球兴趣小组活动总结
2014/07/07 职场文书
医院科室评语
2015/01/04 职场文书
亚布力滑雪场导游词
2015/02/09 职场文书
2016保送生自荐信范文
2016/01/29 职场文书
JS Object构造函数之Object.freeze
2021/04/28 Javascript