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 相关文章推荐
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
May 30 Javascript
javascript-简单的计算器实现步骤分解(附图)
May 30 Javascript
JavaScript获取当前网页标题(title)的方法
Apr 03 Javascript
JavaScript中字面量与函数的基本使用知识
Oct 20 Javascript
学习JavaScript设计模式(链式调用)
Nov 26 Javascript
微信小程序 Image API实例详解
Sep 30 Javascript
Angular4.0动画操作实例详解
May 10 Javascript
JS实现判断数组是否包含某个元素示例
May 24 Javascript
Layui实现主窗口和Iframe层参数传递
Nov 14 Javascript
小程序富文本提取图片可放大缩小
May 26 Javascript
详解如何在Javascript中使用Object.freeze()
Oct 18 Javascript
javascript 数组(list)添加/删除的实现
Dec 17 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
正义联盟的终局之战《天启星战争》将成为DC动画宇宙的最后一部
2020/04/09 欧美动漫
php文档更新介绍
2011/07/22 PHP
php根据身份证号码计算年龄的实例代码
2014/01/18 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
2014/09/23 PHP
PHP安装threads多线程扩展基础教程
2015/11/17 PHP
laravel http 自定义公共验证和响应的方法
2019/09/29 PHP
关于laravel-admin ueditor 集成并解决刷新的问题
2019/10/21 PHP
浅谈laravel数据库查询返回的数据形式
2019/10/21 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
用JavaScript计算在UTF-8下存储字符串占用字节数
2013/08/08 Javascript
轻松学习jQuery插件EasyUI EasyUI创建树形网络(1)
2015/11/30 Javascript
Spring mvc 接收json对象
2015/12/10 Javascript
JS函数arguments数组获得实际传参数个数的实现方法
2016/05/28 Javascript
jQuery复制节点用法示例(clone方法)
2016/09/08 Javascript
form表单转Json提交的方法(推荐)
2016/09/23 Javascript
无阻塞加载js,防止因js加载不了影响页面显示的问题
2016/12/18 Javascript
JS仿淘宝搜索框用户输入事件的实现
2017/06/19 Javascript
AngularJS 实现购物车全选反选功能
2017/10/24 Javascript
layui.js实现的表单验证功能示例
2017/11/15 Javascript
微信小程序ajax实现请求服务器数据及模版遍历数据功能示例
2017/12/15 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
2019/10/29 Javascript
vue v-on:click传递动态参数的步骤
2020/09/11 Javascript
[02:07]DOTA2超级联赛专访BBC:难忘网吧超神经历
2013/06/09 DOTA
Python使用chardet判断字符编码
2015/05/09 Python
浅谈Python使用Bottle来提供一个简单的web服务
2017/12/27 Python
Python画柱状统计图操作示例【基于matplotlib库】
2018/07/04 Python
django2.2 和 PyMySQL版本兼容问题
2020/02/17 Python
使用Pyhton 分析酒店针孔摄像头
2020/03/04 Python
Python发送邮件实现基础解析
2020/08/14 Python
使用HTML5加载音频和视频的实现代码
2020/11/30 HTML / CSS
软件测试企业面试试卷
2016/07/13 面试题
违纪检讨书2000字
2014/02/08 职场文书
学校门卫岗位职责
2014/03/16 职场文书
终止合同协议书
2014/04/17 职场文书
党政领导班子群众路线对照检查材料思想汇报
2014/09/27 职场文书