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表单验证函数
Oct 28 Javascript
在Firefox下js select标签点击无法弹出
Mar 06 Javascript
Javascript技术栈中的四种依赖注入详解
Feb 23 Javascript
JavaScript正则表达式匹配 div  style标签
Mar 15 Javascript
Vue中建立全局引用或者全局命令的方法
Aug 21 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
Feb 23 Javascript
vue中各选项及钩子函数执行顺序详解
Aug 25 Javascript
React Component存在的几种形式详解
Nov 06 Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 Javascript
如何优雅地在vue中添加权限控制示例详解
Mar 07 Javascript
解决Layui中templet中a的onclick参数传递的问题
Sep 20 Javascript
vue实现把接口单独存放在一个文件方式
Aug 13 Javascript
整理关于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
水质对咖图啡风味的影响具体有哪些
2021/03/03 冲泡冲煮
php设计模式 Proxy (代理模式)
2011/06/26 PHP
PHP缓存技术的使用说明
2011/08/06 PHP
php实现水印文字和缩略图的方法示例
2016/12/29 PHP
PHP类与对象后期静态绑定操作实例详解
2018/12/20 PHP
子窗口、父窗口和Silverlight之间的相互调用
2010/08/16 Javascript
简单实用的js调试logger组件实现代码
2010/11/20 Javascript
jQuery cdn使用介绍
2013/05/08 Javascript
jQuery实现contains方法不区分大小写的方法
2015/02/13 Javascript
js自定义QQ菜单效果
2017/01/10 Javascript
JavaScript自定义文本框光标
2017/03/05 Javascript
VUE预渲染及遇到的坑
2018/09/03 Javascript
Vue.js实现开发购物车功能的方法详解
2019/02/22 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
vue使用recorder.js实现录音功能
2019/11/22 Javascript
[05:17]DOTA2睡衣妹卖萌求签名 CJ第二天全明星影像
2013/07/28 DOTA
[02:51]DOTA2 2015国际邀请赛中国区预选赛第一日战报
2015/05/27 DOTA
[07:09]DOTA2-DPC中国联赛 正赛 Ehome vs Elephant 选手采访
2021/03/11 DOTA
Python实时获取cmd的输出
2015/12/13 Python
Python的SimpleHTTPServer模块用处及使用方法简介
2018/01/22 Python
Python常见工厂函数用法示例
2018/03/21 Python
解决Python 爬虫URL中存在中文或特殊符号无法请求的问题
2018/05/11 Python
python 爬虫一键爬取 淘宝天猫宝贝页面主图颜色图和详情图的教程
2018/05/22 Python
在mac下查找python包存放路径site-packages的实现方法
2018/11/06 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
python+logging+yaml实现日志分割
2019/07/22 Python
Python实现元素等待代码实例
2019/11/11 Python
python实现差分隐私Laplace机制详解
2019/11/25 Python
教师求职信范文分享
2013/12/27 职场文书
超市活动计划书
2014/04/24 职场文书
学生会主席演讲稿
2014/04/25 职场文书
科长竞争上岗演讲稿
2014/05/12 职场文书
电工实训报告总结
2014/11/05 职场文书
同学聚会通知短信
2015/04/20 职场文书
高中化学教学反思
2016/02/22 职场文书
Elasticsearch 基本查询和组合查询
2022/04/19 Python