Vue插件写、用详解(附demo)


Posted in Javascript onMarch 20, 2017

Vue插件

1、概述

简单来说,插件就是指对Vue的功能的增强或补充。

比如说,让你在每个单页面的组件里,都可以调用某个方法,或者共享使用某个变量,或者在某个方法之前执行一段代码等

2、使用方法

总体流程应该是:

【声明插件】——【写插件】——【注册插件】——【使用插件】

写插件和声明插件是同步的,然后注册到Vue对象中(不用担心重复注册),最后在写Vue组件的时候使用写的插件

声明插件

先写一个js文件,这个js文件就是插件文件,里面的基本内容如下:

/*  说明:
 *  插件文件:service.js
 *  作者:王冬  QQ:20004604
 * */
export default {
  install: function (Vue, options) {
    // 添加的内容写在这个函数里面
  }
};

其中install的第一个参数Vue表示的是Vue的实例,第二个参数表示的是一些设置选项。

Vue实例好理解,就是Vue对象。

而options设置选项就是指,在调用这个插件时,可以传一个对象。

例如这个对象有一个属性float,然后在写插件的一个方法/变量时,我需要输出一个数字,然后写一个if判断语句,

假如options.float为true时,输出浮点数;

假如为false或undefined(即没传参)时,输出为整数。

具体怎么添加,之后再说。

注册插件

如果使用过Vue-router,就很好理解,通过import引入后,然后通过 Vue.use(插件名) 注册插件;

例如,我们通常在main.js里引入各种东西,并且组件的根实例也在这里

//main.js
import Vue from 'vue'
import App from './App.vue'

//关键是这两行
import service from './service.js'
Vue.use(service)

new Vue({
  el: '#app',
  render: (h) => h(App)
})

如代码中注释所说,关键是通过import导入service文件,然后在创建根组件之前,让Vue对象通过use方法来注册插件service。

通过这样简单的两步,就可以使用插件了。

3、写插件、使用插件

按照官方文档,写插件有四种方法,先给出官方的代码:

//以下内容都是添加到上面install的函数里面的

// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
  // 逻辑...
}
// 2. 添加全局资源
Vue.directive('my-directive', {
  bind (el, binding, vnode, oldVnode) {
    // 逻辑...
  }
  ...
})
// 3. 注入组件
Vue.mixin({
  created: function () {
    // 逻辑...
  }
  ...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (options) {
  // 逻辑...
}

先给出最常用的:【4. 添加实例方法】的写法和使用方法

3.1【添加实例方法或属性】

1、核心思想:

通过prototype来添加方法和属性。

2、写:

//让输出的数字翻倍,如果不是数字或者不能隐式转换为数字,则输出null
Vue.prototype.doubleNumber = function (val) {
  if (typeof val === 'number') {
    return val * 2;
  } else if (!isNaN(Number(val))) {
    return Number(val) * 2;
  } else {
    return null
  }
}

3、用:

假设有这样一个组件:

<template>
  <div>
    {{num}}
    <button @click="double">点击后让左边的数字翻倍</button>
  </div>
</template>
<script>
  export default{
    data(){
      return {
        num: 1
      }
    },
    methods: {
      double: function () {
        //这里的this.doubleNumber()方法就是上面写的组件里的方法
        this.num = this.doubleNumber(this.num);
      }
    }
  }
</script>

我们便可以通过点击button按钮,让num的值,在每次点击都翻倍了。

4、假如添加的是属性:

例如:

Vue.prototype.number = 1;

会发生什么事情呢?

1、不管是【按值传递类型】还是【按引用传递类型】,该变量都不会被不同组件所共享,更准确的说,假如有A、B两个组件。A组件里的number数值改变,B组件里的number数值是不会跟着改变的。因此不要想着引用这样一个变量,然后修改了A中的值,B里也自动跟着改变了;

2、当组件里没有该属性时,调用时,显示的是通过插件获取的值;

当组件里有该属性时,调用时,显示的是组件里该属性的值;

由此而推,函数也是这样的,组件里的同名函数总是会覆盖插件提供的函数。

也就是说,当插件提供一个属性时,组件里没这个属性,就用插件的属性;组件有,就用组件自己的。

3.2【添加全局方法或属性】

1、核心思想:

就是给Vue对象添加一个属性。

初次接触很容易和上面3.1弄混,实际上,3.1是给组件里使用的,而3.2是给Vue对象使用的。

例如,假如添加一个方法test(),那么:

通过3.1添加,是在组件里,通过this.test()来调用

通过3.2添加,是在外面,通过Vue实例,如Vue.test()来调用

2、写:

//放在哪里参考上面
Vue.test = function () {
  alert("123")
}

3、用:

//注意先导入Vue对象才能使用
Vue.test()

使用时会执行对应的方法,比如这里就是alert弹窗

4、其他:

别问我如果和Vue本身属性同名会发生什么事情,我没试过=.=

3.3【注入组件】

1、核心思想:

就像写Vue组件时,那样写,方法名保持一致,其会在执行组件对应的方法名之前执行。

2、写:

例如:

Vue.mixin({
  created: function () {
    console.log("组件开始加载")
  }
})

然后这里的代码会在每个组件(包括根组件)的created执行之前执行。

可以自行在每个组件的created方法里写一段console.log来查看测试

可以和【实例属性】配合使用,用于调试或者控制某些功能

// 注入组件
Vue.mixin({
  created: function () {
    if (this.NOTICE)
      console.log("组件开始加载")
  }
})
// 添加注入组件时,是否利用console.log来通知的判断条件
Vue.prototype.NOTICE = false;

【注入给非Vue实例本身就有的方法】:

假如是写给例如methods属性的某个方法,例如以下注入:

Vue.mixin({
  methods: {
    test: function () {
      console.log("mixin test");
    }
  }
})

那么,组件里若本身有test方法,并 不会 先执行插件的test方法,再执行组件的test方法。

而是只执行其中一个,并且优先执行组件本身的同名方法。这点需要注意

3、用:

不需要手动调用,在执行对应的方法时会被自动调用的(并且先调用插件里的,再调用组件本身的)

4、其他:

1、如果同时有多个插件注入一个方法(例如created,那么会先执行先注入的那个方法,再依次执行后注入的,最后执行组件本身的)

2、注意,像methods属性下的方法,并不会在组件注入后每个都执行,而是只执行一个,并且优先执行组件本身的。

3.4【添加全局资源】

1、核心思想:

添加方法和正常添加方法类似,甚至几乎一样。

可以添加【自定义指令】、【过滤器】、【过渡等】,这里以【过滤器】为例

2、写:

例如:

//时间格式化过滤器,输入内容是number或者Date对象,输出是YYYY-MM-DD HH-MM-SS
Vue.filter('formatTime', function (value) {
  Date.prototype.Format = function (fmt) { //author: meizz
    var o = {
      "M+": this.getMonth() + 1, //月份
      "d+": this.getDate(), //日
      "h+": this.getHours(), //小时
      "m+": this.getMinutes(), //分
      "s+": this.getSeconds(), //秒
      "q+": Math.floor((this.getMonth() + 3) / 3), //季度
      "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
      if (new RegExp("(" + k + ")").test(fmt))
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
  }
  return new Date(value).Format("yyyy-MM-dd hh:mm:ss");
})

3、用:

和正常使用一样用就行了,so easy。例如:

{{num|formatTime}}

4、其他:

可以用这个找各种有意思的功能,作为插件写好,然后需要的地方导入就行,超级方便!

4、示例demo

附一个有简单功能的示例demo,提供参考使用

/* 说明:
 * 插件demo,供学习使用
 * 本页面用于提供各种处理服务
 * 作者:王冬  QQ:20004604
 * */
export default {
  install: function (Vue, options) {
    // 1. 添加全局方法或属性
    // 略

    // 2. 添加全局资源
    // 时间格式化过滤器,输入内容是number或者Date对象,输出是YYYY-MM-DD HH-MM-SS
    Vue.filter('formatTime', function (value) {
      Date.prototype.Format = function (fmt) { //author: meizz
        var o = {
          "M+": this.getMonth() + 1, //月份
          "d+": this.getDate(), //日
          "h+": this.getHours(), //小时
          "m+": this.getMinutes(), //分
          "s+": this.getSeconds(), //秒
          "q+": Math.floor((this.getMonth() + 3) / 3), //季度
          "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt))
          fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
          if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
      }
      return new Date(value).Format("yyyy-MM-dd hh:mm:ss");
    })

    // 2. 添加全局资源
    // 添加注入组件时,是否利用console.log来通知的判断条件,也是组件实例属性
    Vue.prototype.NOTICE = true;


    // 3. 注入组件
    // 注入组件,插件加载开始前提示
    Vue.mixin({
      created: function () {
        if (this.NOTICE)
          console.log("组件开始加载")
      },
      methods: {
        test: function () {
          console.log("mixin test");
        }
      }
    })


    // 4. 添加实例方法
    // 返回数字是输入数字的两倍,如果不是数字或者不能隐式转换为数字,则输出null
    // 组件实例方法
    Vue.prototype.doubleNumber = function (val) {
      if (typeof val === 'number') {
        return val * 2;
      } else if (!isNaN(Number(val))) {
        return Number(val) * 2;
      } else {
        return null
      }
    }

    // 4. 添加实例方法
    // 服务组,将实例方法整合到$service中,避免命名冲突
    Vue.prototype.$service = {
      //电话号码合法性检查
      telNumberCheck: function (tel) {
        var pattern = /(^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$)|(^0{0,1}1[3|4|5|6|7|8|9][0-9]{9}$)/;
        return pattern.test(tel)
      }
    }
  }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
关于jquery input textare 事件绑定及用法学习
Apr 03 Javascript
JavaScript 作用域链解析
Nov 13 Javascript
JS中事件冒泡和事件捕获介绍
Dec 13 Javascript
JS日程管理插件FullCalendar简单实例
Feb 07 Javascript
Node.js查找当前目录下文件夹实例代码
Mar 07 Javascript
Angular 4.x中表单Reactive Forms详解
Apr 25 Javascript
基于js中的存储键值对以及注意事项介绍
Mar 30 Javascript
JavaScript变量声明var,let.const及区别浅析
Apr 23 Javascript
Nautil 中使用双向数据绑定的实现
Oct 02 Javascript
基于JavaScript实现单例模式
Oct 30 Javascript
vue-router结合vuex实现用户权限控制功能
Nov 14 Javascript
vue图片裁剪插件vue-cropper使用方法详解
Dec 16 Vue.js
详解vue事件对象、冒泡、阻止默认行为
Mar 20 #Javascript
javascript使用btoa和atob来进行Base64转码和解码
Mar 20 #Javascript
vue.js事件处理器是什么
Mar 20 #Javascript
Vue.js事件处理器与表单控件绑定详解
Mar 20 #Javascript
Vue.js基础学习之class与样式绑定
Mar 20 #Javascript
详解Vue中添加过渡效果
Mar 20 #Javascript
JS模拟实现ECMAScript5新增的数组方法
Mar 20 #Javascript
You might like
PHP个人网站架设连环讲(四)
2006/10/09 PHP
PHP mysql与mysqli事务使用说明 分享
2013/08/17 PHP
PHP延迟静态绑定使用方法实例解析
2020/09/05 PHP
Prototype最新版(1.5 rc2)使用指南(1)
2007/01/10 Javascript
jQuery中die()方法用法实例
2015/01/19 Javascript
js+css实现超简洁的二级下拉菜单效果代码
2015/09/07 Javascript
js基于setTimeout与setInterval实现多线程
2016/06/17 Javascript
vue.js绑定class和style样式(6)
2016/12/09 Javascript
解析jquery easyui tree异步加载子节点问题
2017/03/08 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
解决VUEX刷新的时候出现数据消失
2017/07/03 Javascript
详解如何使用webpack在vue项目中写jsx语法
2017/11/08 Javascript
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
如何使用proxy实现一个简单完整的MVVM库的示例代码
2019/09/17 Javascript
JavaScript实现文件下载并重命名代码实例
2019/12/12 Javascript
解决vuex刷新数据消失问题
2020/11/12 Javascript
[04:47]DOTA2-潍坊风行电子俱乐部探秘
2014/08/08 DOTA
解读python logging模块的使用方法
2018/04/17 Python
python判断列表的连续数字范围并分块的方法
2018/11/16 Python
如何使用python进行pdf文件分割
2019/11/11 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
2019/11/19 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
德国汉莎航空中国官网: Lufthansa中国
2017/03/30 全球购物
英国旅游额外服务市场领导者:Holiday Extras(机场停车场、酒店、接送等)
2017/10/07 全球购物
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
Hotels.com韩国:海外国内旅行所需的酒店和住宿预订网站
2020/05/08 全球购物
2014世界杯球队球队口号
2014/06/05 职场文书
飞越疯人院观后感
2015/06/09 职场文书
销售人员管理制度
2015/08/06 职场文书
《狼牙山五壮士》读后感:宁死不屈,视死如归
2019/08/16 职场文书
Nginx + consul + upsync 完成动态负载均衡的方法详解
2021/03/31 Servers
在HTML5 localStorage中存储对象的示例代码
2021/04/21 Javascript
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL
Elasticsearch 聚合查询和排序
2022/04/19 Python
CSS元素定位之通过元素的标签或者元素的id、class属性定位详解
2022/09/23 HTML / CSS