vue2插件开发小试

2023-11-04

开发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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue2插件开发小试 的相关文章

随机推荐

  • Linux shell与expect配合完成自动打包资源并scp到另一台Linux电脑的例子

    有时我们想使用shell脚本做一些自动操作 例如ssh或scp时自动输入密码 可以使用expect工具来实现 需求 使用shell与expect混合编程 将一个文件从机器A Ubuntu16 04 中的目录mydata打包为mydata t
  • 嵌入式工程师老了怎么办_老刘工程师睡前故事5-EMC 辐射发射超标怎么办?

    老刘工程师睡前故事 EMC 辐射发射超标怎么办 今天的工程师睡前故事讲讲汽车EMC测试中辐射发射超标了怎么办 首先来聊聊辐射发射的基本知识 辐射发射英文简称RE 检测的是产品对外的辐射干扰 国际标准参考CISPR25 国标参考GBT1865
  • outlook出现"定位链接浏览器"错误的解决办法

    打开我的电脑 单击 工具 文件夹选项 文件类型 在列表中选中 无 URL 超文本传输通讯协议 单击 高级 按钮 把原来项目删除 点新建 操作名称 处输入 OPEN 用于执行操作的应用程序 处输入 C Program Files Intern
  • GIT撤销远程MERGE

    GIT撤销远程MERGE 关于GIT撤销 网上有很多教程 基本都提到RESET或者REVERT 等我们自己按照教程搞的发现搞不了 我也跟大家有同样的困惑 这里把这个问题详细的说明一下 方法一 通过RESET撤销 我用的工具是Tortoise
  • 毕业设计-基于 MATLAB的红外图像预处理算法对比研究

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度
  • codeforces - 920B(贪心)

    B Tea Queue time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output
  • 在没有自己的服务器的情况下,搭建自己的网站-开发自己的小程序接口

    目标 场景一 在没有自己的服务器的情况下 搭建自己的网站 并通过微信小程序给自己的网站引流 场景二 在没有自己的服务器的情况下 开发自己的小程序 后端接口使用第三方网站的某些功能完成小程序前后端数据交互能力 实现 场景一 使用gitee的g
  • 分贝dB的换算

    1dB 0 115Np 公式 公式 d B 10 l g
  • adworld.xctf-web-新手练习区刷题

    1 View Source 根据题目 就能猜到 此处是查看页面源码 在查看的过程中发现右键不能使用了 那就用F12吧 2 Robots 这题是考察Robots协议 访问的时候页面是一片空白 直接输入robots txt 在地址栏输入robo
  • 微信小程序滚动Tab选项卡:左右可滑动切换

    最终效果如上 问题 1 tab标题总共8个 所以一屏无法全部显示 2 tab内容区左右滑动切换时 tab标题随即做标记 active 3 当active的标题不在当前屏显示时 要使其能显示到当前屏中 一 wxml结构 tab标题因一排八个
  • Redis学习笔记(持续更新中...)

    学习课程 尚硅谷Redis6 目录 NoSQL简介 NoSQL概述 NoSQL的特点 适用场景 NoSQL不适用场景 几种常见的NoSQL数据库 Memcache Redis MongoDB Redis Redis的底层 Redis的五大数
  • 获取扫描枪数据并存入TXT文档的C#程序代码

    我可以提供一段 C 语言代码 用于获取扫描枪数据并存入TXT文档 include
  • 数仓分层、设计、建模、架构

    一 数仓分层误区 数仓层内部的划分不是为了分层而分层 分层是为了解决 ETL 任务及工作流的组织 数据的流向 读写权限的控制 不同需求的满足等各类问题 业界较为通行的做法将整个数仓层又划分成了 DWD DWT DWS DIM DM等很多层
  • facenet专题1:windows下使用train_sotfmax.py训练人脸识别模型

    1 facenet github地址 https github com davidsandberg facenet 下载该project git clone https github com davidsandberg facenet 2
  • node : 无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

    VScode Code Runner无法运行JavaScript js文件 原因 未安装Node js 解决方法 https nodejs org en 下载Nodejs 安装完之后 重启VScode 会自动配置 运行即可在终端看到结果
  • 【tauri】tauri的启动、运行与打包过程步骤

    兼容性 win11 系统 自带 WebView2 win10 安装完会自动安装WebView2 win7 需要先手动来装WebView2 开始安装 安装node 推荐用nvm将进行node版本管理 安装vs 生成工具 下载地址 https
  • 单片机 嵌入式 毕业设计题目选题推荐

    文章目录 1前言 2 如何选题 2 1 不要给自己挖坑 2 2 难度把控 2 3 如何命名题目 3 单片机 嵌入式 选题大全 3 1 嵌入式方向 3 2 算法方向 3 3 移动通信方向 3 4 学长作品展示 4 最后 1前言 近期不少学弟学
  • 子类的构造函数和析构函数

    1 构造函数是否可以被继承 子类可以继承父类的所有成员变量和成员函数 但不能继承父类的构造函数 因此 在创建子类对象时 为了初始化从父类继承来的数据成员 系统需要调用其父类的额构造函数 2 父类构造函数的调用规则 如果子类没有定义构造函数
  • axios的三层封装思想

    1 工具函数层 设置默认请求地址 设置默认超时时间 设置默认请求拦截 设置默认响应拦截 ajax工具函数层 import axios from axios axios defaults baseURL http localhost 5000
  • vue2插件开发小试

    开发vue插件的官方文档是这样描述的 插件通常会为Vue添加全局功能 插件的范围没有限制 一般有下面几种 1 添加全局方法或者属性 如 vue element 2 添加全局资源 指令 过滤器 过渡等 如 vue touch 3 通过全局 m