vue2插件开发小试

开发vue插件的官方文档是这样描述的:

插件通常会为Vue添加全局功能。插件的范围没有限制,一般有下面几种:
1,添加全局方法或者属性,如: vue-element ,
2,添加全局资源:指令/过滤器/过渡等,如 vue-touch
3,通过全局 mixin方法添加一些组件选项,如: vuex,
4,添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
5,一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router
Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器 , 第二个参数是一个可选的选项对象:

MyPlugin.install = function (Vue, options) {
  // 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) {
    // 逻辑...
  }
}

使用:
通过全局方法 Vue.use() 使用插件:
// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
也可以传入一个选项对象(定制一些自己的效果):
Vue.use(MyPlugin, { someOption: true })

看完文档可以动手自己试一试了,先给自己定需求:开发一个分页插件,可以定制显示分页按钮的最大个数和每页展示内容列表个数,在页面中定义一个含有Id的元素作为分页组件的包裹容器,分页组件可以自动渲染为其子元素在页面中渲染出来。此外我们想要在vue-cli架子下的任何一个vue组件中都能够this.$myMethod('id名',回调函数,{配置对象})的方式创建。

好了,按照上边的需求,我们结合文档应该选择‘添加实例方法’的方式开发我的组件。首先捋一捋思路,第一,要先建个index.js这里边应该含有我们插件的注册函数;第二,做一个分页vue组件,模板,样式,一些逻辑方法都写在这里边;第三,设置一个中间层,管理数据和方法。

看起来我的插件目录应该是这样的:

来看看index.js

import chooseP from './choosePages.vue' //引入组件
import {peacemaker} from './delivery'  //引入中间层
var ChoosePages = {};   //定义一个对象
ChoosePages.install = function (Vue,options) {
//添加实例方法
// id 页面元素id名  字符串类型
// cb 回调函数  获取当前页码
// op 配置对象  
    Vue.prototype.$choosePages = (id,cb,op) => {
      for(let property in op){
        peacemaker.data[property] = op[property];
      }
      let choosePages = Vue.extend(chooseP);
      let tpl = new choosePages().$mount().$el;
      document.getElementById(id).appendChild(tpl);
      peacemaker.doThings = cb;
    }
}
export default ChoosePages;; //将对象暴露出去

中间层  delivery.js

export const peacemaker = {
  data : {
    //展示内容的列表总个数 
    listsNum:0,
    //每页展示的内容列表个数
    itemsNum:5,
    //最多在页面上显示的按钮个数
    btnNum :16
  },
  doThings : null //回调函数
}

分页组件 choosePage.vue

<template>
  <div class="choosePages">
    <a href="javascript:;" class="firstPage" @click="toFirst">首页</a><a
    href="javascript:;" class="last" @click="chooseBtnLast"><i></i></a><a
    href="javascript:;"v-for="item in showBtns" :class="{pageNum : chooseBtnIndex === item }" @click="clickBtn(item)">{{item}}</a><a
    href="javascript:;" class="next" @click="chooseBtnNext"><i></i></a><a
    href="javascript:;" class="lastPage" @click="toLast">尾页</a><span
    class="hint" v-if="isShowRight">跳转到</span><input type="text" v-model="pageIndex" @keyup="goIndex" v-if="isShowRight"><span
    v-if="isShowRight">页</span><span v-if="isShowRight">共{{btns.length}}页</span>
  </div>
</template>
<script>
  import {peacemaker} from './delivery'
    export default {
    data(){
      return {
         btns : [],
         showBtns : [],
         chooseBtnIndex :1, //页码
         overNum:0,
         pageIndex:'1',
      }
    },
    created() {
       this.createBtns(this.listsNum);
    },
    computed: {
      //数据列表总个数
      listsNum:function () {
        return  peacemaker.data.listsNum
      },
      //每页展示的内容列表个数
      itemsNum:function () {
        return  peacemaker.data.itemsNum
      },
      //页面最多展示的个数
      lengthBtns: function () {
        return peacemaker.data.btnNum
      },
      //按钮数大于限定展示时,显示跳转页面选框
      isShowRight:function () {
        return this.btns.length > this.lengthBtns ? true : false;
      }
    },
    methods: {
      //跳转页面
       goIndex(e){
         if(e.keyCode !== 13 || +this.pageIndex > this.btns.length){
           return;
         }
         this.chooseBtnIndex = +this.pageIndex;
         this.getPageMessage ();
         if(+this.pageIndex > this.lengthBtns){ //选择的页面大于显示个数限制
           this.overNum = +this.pageIndex - this.lengthBtns;
           this.showBtns = null;
           this.showBtns = this.btns.slice(this.overNum,this.lengthBtns+this.overNum);
         }else{
           this.overNum=0;
           this.showBtns = null;
           this.showBtns = this.btns.slice(this.overNum,this.lengthBtns+this.overNum);
         }
       },
      //5个列表为一页(默认可配置)
       createBtns(n){
         let length = 0;
         if(n>this.itemsNum){
           length = parseInt(n/this.itemsNum);
           if(parseInt(n%this.itemsNum)>0){
             length = length + 1;
           }
           for(let i=0;i<length;i++){
             this.btns.push(i+1);
           }
           if(this.btns.length>this.lengthBtns){ //按钮长度不能大于长度设定值
             this.showBtns = null;
             this.showBtns = this.btns.slice(0,this.lengthBtns);
           }else{
             this.showBtns = null;
             this.showBtns = this.btns;
           }

         }else {
           return;
         }
       },
        getPageMessage (){
           //请求选择的页面信息
           console.log( '请求的第页:'+this.chooseBtnIndex);
           //通过回调函数把页码数传递出去
          peacemaker.doThings(this.chooseBtnIndex);
        },
       clickBtn(index){
         this.chooseBtnIndex = index;
         this.getPageMessage ();
       },
      chooseBtnLast(){  //前一个按钮
         if(this.chooseBtnIndex === 1){
           return
         }
         this.chooseBtnIndex--;
         this.getPageMessage ();
         if(this.overNum>0){ //按钮长度不能大于长度设定值
            this.overNum--;
           if(this.overNum < 0){
             return
           }
            this.showBtns = null;
            this.showBtns = this.btns.slice(this.overNum,this.lengthBtns+this.overNum);
         }
      },
      chooseBtnNext(){  //后一个按钮  向后移动
        if(this.chooseBtnIndex === this.btns.length){
          return
        }
        this.chooseBtnIndex++;
        this.getPageMessage ();
        if(this.chooseBtnIndex>this.lengthBtns){ //按钮长度不能大于长度设定值
          this.overNum++;
          this.showBtns = null;
          this.showBtns = this.btns.slice(this.overNum,this.lengthBtns+this.overNum);
        }
      },
      toFirst(){
        if(this.chooseBtnIndex === 1){
          return
        }
        this.chooseBtnIndex=1;
        this.getPageMessage ();
        if(this.overNum>0){ //按钮长度不能大于长度设定值
          this.overNum=0;
          this.showBtns = null;
          this.showBtns = this.btns.slice(this.overNum,this.lengthBtns+this.overNum);
        }
      },
      toLast(){
        if(this.chooseBtnIndex === this.btns.length){
          return
        }
        this.chooseBtnIndex=this.btns.length;
        this.getPageMessage ();
        if(this.btns.length>this.lengthBtns){ //按钮长度不能大于长度设定值
          this.overNum = this.btns.length - this.lengthBtns;
          this.showBtns = null;
          this.showBtns = this.btns.slice(this.overNum,this.lengthBtns+this.overNum);
        }
      }
    },
  }
</script>

<style scoped lang="css">
  .choosePages{
    text-align: center;
    margin: 34px 0;
  }
  .choosePages a{
    display: inline-block;
    width: 32px;
    height: 32px;
    line-height: 32px;
    text-align: center;
    box-sizing: border-box;
    border: 1px solid #999;
    margin-right: 10px;
    color:#333;
    background: #fff;
    font-size: 13px;
  }
  .choosePages a i{
    display: inline-block;
    width: 10px;
    height: 12px;
  }
  .choosePages .last i{
    background: url("./icon/icon_last@2x.png") no-repeat 0 0;
    background-size: 10px 12px;
  }
  .choosePages .last:hover{
    background: rgba(200,200,200,.2);
  }
  .choosePages .next i{
    background: url("./icon/icon_next@2x.png") no-repeat 0 0;
    background-size: 10px 12px;
  }
  .choosePages  .next:hover{
    background: rgba(200,200,200,.2);
  }
  .choosePages .pageNum{
    background: #000;
    border: 1px solid #000;
    color: #fff;
  }
  .choosePages .firstPage,.choosePages .lastPage{
    width: 45px;
  }
   .choosePages .firstPage:hover,.choosePages .lastPage:hover{
     background: #f2f2f2;
     border: 1px solid #666;
   }
  .choosePages .lastPage{
    margin-right: 0;
  }
  .choosePages span{
    color:#333;
    font-size: 13px;
    margin-left: 5px;
    margin-right: 5px;
  }
  .choosePages .hint{
    margin-left: 15px;
  }
  .choosePages input{
    width: 26px;
    text-align: center;
  }
</style>

然后就是如何用了,在入口js文件中(app.js)

import ChoosePages from '../../plugin/choosePage/index' //引入插件文件
Vue.use(ChoosePages);  //使用插件

最后在需要应用的组件中就可以应用了

this.$choosePages('pagesBtn',function(index){
         console.log(index,'我在应用页面');
    },
    {
      listsNum:10, // 列表数据总个数(必填)
      itemsNum:5,  // 每页要显示的列表数(默认5,选填)
      btnNum :4    // 页面限定显示的按钮个数(默认16,选填)
    })

ps:以上就是vue插件一个简单的小开发,由于本人的能力所限,难免会出现纰漏和错误,欢迎留言斧正!

这里提供一个demo地址:

https://github.com/h1zsh1/MyPlugin-ChoosePage

转载于:https://my.oschina.net/u/3185514/blog/869879

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值