Skip to content

插件开发 ​

创建自己的插件 ​

  • 目录结构
    1. lib 下面是我们所有的插件,创建一个新的插件名叫 wing;
    2. wing 下的目录是 lib 和 index.js 还有一个 test.vue 文件;

image-20240705172727782

  • 在 wing/index.js 文件写入

    js
    module.exports = require('./lib')
    module.exports = require('./lib')
  • 在 wing/lib/index.js 写入以下代码

    js
    import test from './test.vue'
    export default {
      // Vue.use默认使用install方法
      // 第一个参数是Vue, 第二个参数是选项
      install(Vue, options) {
        Vue.component('test', test)
      },
    }
    import test from './test.vue'
    export default {
      // Vue.use默认使用install方法
      // 第一个参数是Vue, 第二个参数是选项
      install(Vue, options) {
        Vue.component('test', test)
      },
    }
  • 在 test.vue 文件可以写我们的公共组件代码了

    vue
    <template>
      <div class="test">哈哈, 这是我的新插件</div>
    </template>
    <script>
    export default {
      name: 'test',
    }
    </script>
    <style lang="scss"></style>
    <template>
      <div class="test">哈哈, 这是我的新插件</div>
    </template>
    <script>
    export default {
      name: 'test',
    }
    </script>
    <style lang="scss"></style>
  • 在 main.js 主入口文件引入创建好的 test 插件

    js
    import test from './lib/wing'
    Vue.use(test)
    import test from './lib/wing'
    Vue.use(test)
  • 直接在 App.vue 将标签放入,就可以直接使用了

插件自动安装

在 UMD 构建中,插件开发者使用 Vue.use 来自动安装插件是一个通用的做法。例如,官方的 vue-router 插件是这样在浏览器环境中自行安装的:

js
var inBrowser = typeof window !== 'undefined'
/* … */
if (inBrowser && window.Vue) {
  window.Vue.use(VueRouter)
}
var inBrowser = typeof window !== 'undefined'
/* … */
if (inBrowser && window.Vue) {
  window.Vue.use(VueRouter)
}

发布到 npm ​

npm 初始化 ​

进入 lib/wing 文件夹,并执行 npm init 命令

  • name:包名,默认就是文件夹名字,但是这个名字是需要唯一的,如果你命的名字已经被使用过了,那就只能换个名字。查看是否被用,可以直接输入 npm view 包名,如果报错即被使用
  • version:包的版本,默认是 1.0.0, 你可以更换,例如 0.1.0 或 2.0.1 等。
  • description:包的描述。主要描述你的包是用来做什么的。
  • entry point:包入口文件,默认是 Index.js,可以自定义。
  • test command:测试命令,这个直接回车就好了,因为目前还不需要这个。
  • git repository:包的 git 仓库地址,npm 自动读取.git 目录作为这一项的默认值。没使用则回车略过。
  • keyword:包的关键词。该项会影响到用户怎样才能搜到你的包,可以理解为搜索引擎悠哈的关键词。建议关键词要能准确描述你的包,例如:"vpay vue-pay vue-password password"
  • author:作者。例如你的 npm 账号或者 github 账号
  • license:开源协议,回车就好。
忽略文件不上传 ​

创建.npmignore文件,和.gitignore差不多,希望哪些不发到 npm 包上面;

上传 ​
  1. 测试插件是否可以上传到 npm 网上;

    因为 main.js 引入时,都是从 node_modules 引入的,因此将 lib/wing 直接放入 node_modules 中,再引入的时候直接写:

    js
    import test from 'wing'
    Vue.use(test)
    import test from 'wing'
    Vue.use(test)

    测试通过之后就可以直接开始发布到 npmjs 网上了;

  2. 注册 npm 账号

    注册地址:https://www.npmjs.com/signup

  3. 登录 npm 账号

    如果有设置了淘宝镜像需要先设置回镜像

    js
    npm config set registry http://registry.npmjs.org
    npm config set registry http://registry.npmjs.org

    之后执行 npm login 命令登录 npm;

    image-20240705173159422

  4. 进入到项目的根目录,直接输入 npm publish 就发布成功了,直接到 npmjs 官网搜索包的 name 名字就有了;当然也可以直接在项目 npm i 名字;

    image-20240705173205818

    注意:第二次发布时,必须修改 version 版本号才能发布,否则会报错;

自动修改版本号 ​

npm version <update_type>

type 值为:

  • patch 0.0.
  • minor 1.*.0
  • major *.0.0

其他 npm 管理包命令

js
// 撤销整个包
npm unpublish --force 包名

// 撤销某个版本
npm publish 包名@版本号
// 撤销整个包
npm unpublish --force 包名

// 撤销某个版本
npm publish 包名@版本号

Vue.extend ​

Vue.extend 属于 Vue 的全局 API,在实际业务开发中很少使用,因为相比常用 Vue.component 写法使用 extend 更加麻烦,用于注册插件使用

使用Vue.extend创建插件,传入一个组件,或者一个对象,里面写对应的组件

之后使用$mount挂载元素得到$el,将$el添加到body里面即可;

js
// 使用vue单组件
import CodeComponent from './CodeComponent.vue'
const C = Vue.extend(CodeComponent)

// 使用对象
const C = Vue.extend({
  data() {},
  render() {
    return <div>这是一个组件</div>
  },
})

// 挂载到body上
let vm = new C()
vm.$mount()
document.body.appendChild(vm.$el)
// 使用vue单组件
import CodeComponent from './CodeComponent.vue'
const C = Vue.extend(CodeComponent)

// 使用对象
const C = Vue.extend({
  data() {},
  render() {
    return <div>这是一个组件</div>
  },
})

// 挂载到body上
let vm = new C()
vm.$mount()
document.body.appendChild(vm.$el)
开发一个 loading 全局组件 ​
  1. 创建 Loading/Loading.vue

    vue
    <template>
      <div v-if="visible">{{ text }}</div>
    </template>
    <script>
    export default {
      data() {
        return {
          visible: false,
          text: '',
        }
      },
    }
    </script>
    <template>
      <div v-if="visible">{{ text }}</div>
    </template>
    <script>
    export default {
      data() {
        return {
          visible: false,
          text: '',
        }
      },
    }
    </script>
  2. 创建 Loading/index.js

    js
    import Vue from 'vue'
    import LoadingComponent from './Loading'
    const LoadingConstructor = Vue.extend(LoadingComponent) // 包装成vue实例
    LoadingConstructor.prototype.close = function () {
      this.visible = false
      setTimeout(() => {
        if (this.$el.parentNode) {
          this.$el.parentNode.removeChild(this.$el)
          this.$destroy()
        }
      }, 300)
    }
    const Loading = (options = {}) => {
      const instance = new LoadingConstructor({
        data: {
          text: '数据加载中...',
          ...options,
        },
      })
      instance.$mount()
      document.body.appendChild(instance.$el)
      return instance
    }
    export default Loading
    import Vue from 'vue'
    import LoadingComponent from './Loading'
    const LoadingConstructor = Vue.extend(LoadingComponent) // 包装成vue实例
    LoadingConstructor.prototype.close = function () {
      this.visible = false
      setTimeout(() => {
        if (this.$el.parentNode) {
          this.$el.parentNode.removeChild(this.$el)
          this.$destroy()
        }
      }, 300)
    }
    const Loading = (options = {}) => {
      const instance = new LoadingConstructor({
        data: {
          text: '数据加载中...',
          ...options,
        },
      })
      instance.$mount()
      document.body.appendChild(instance.$el)
      return instance
    }
    export default Loading
  3. 修改 main.js

    js
    import Loading from './Loading'
    Vue.prototype.$loading = Loading
    import Loading from './Loading'
    Vue.prototype.$loading = Loading
  4. 在组件中使用

    js
    export default {
      methods: {
        showLoading() {
          this.$loading({ text: '数据加载中' })
        },
      },
    }
    export default {
      methods: {
        showLoading() {
          this.$loading({ text: '数据加载中' })
        },
      },
    }

遇到的 bug: ​

  1. 发布 npm 包报错: https://blog.csdn.net/weixin_38080573/article/details/88080556