vue

分装简单的vue组件 以及 上传到npm

(分装简单的vue组件)

Posted by YC on November 30, 2018

前言

对于现在使用vue开发网页,大多数使用的都是第三方的ui组件库,例如element ui, iView, antd Vue,这样开发能够提升效率但是组件库不是万能的,对于一些业务功能在这些ui组件库上是没有的,所以需要我们自己diy一个组件,对于那些在业务上使用过多的组件,在公司其他项目上使用的到,那就需要自己做个组件并上传到npm 在其他项目上使用了。

1、新建项目初始化(基于vue-cli2)

首先创建项目,使用vue-cli创建项目,为什么使用vue-cli创建项目,因为vue-cli 插件需要一些webpack的配置模版,而且开发插件过程中方便我们进行调试插件功能。

  // 因为插件不需要依赖庞大的配置,所以,这里使用简洁版本的webpack配置模版
  vue init webpack-simple my-plugin
  • 初始化完成后的目录

Image text

  • 接着在项目中单独建立一个存放插件的库

Image text

  cd my-plugin
  npm install
  npm run dev
  • 然后编写组件 sum-compent.vue
<template>
  <div class="calculate">
    <p>+=</p>
    <input type="text" v-model="a" style="width:30px;text-align:center" @blur="sumFunc"/>
    <span class="symbol">+</span>
    <input type="text" v-model="b" style="width:30px;text-align:center" @blur="sumFunc"/>
    <span class="symbol" @click="sumFunc"> = </span>
    <span class="item"></span>
  </div>
</template>
<script>
  export default({
    name:'addCompent',
    props:['num1','num2'],
    data() {
      return{
        a: this.num1 ? this.num1 : 0,
        b: this.num2 ? this.num2 : 0,
        sum: 0,
      }
    },
    mounted() {
      this.sumFunc();
    },
    methods:{
      sumFunc() {
        let a = Number(this.a);
        let b = Number(this.b);
        if(isNaN(a) || isNaN(b)) {
          return;
        }else{
          this.sum = a + b;
          this.$emit('getSumFromChild',this.sum);
        }
      }
    }
  })
</script>
<style>
.calculate{
  width: 100%;
  line-height: 26px;
}
</style>
  • 在app.vue 添加组件查看组件能否正常使用
<template>
  <div id="app">
    <img src="./assets/logo.png">
   <my-sum :num1="num1" :num2="num2" v-on:getSumFromChild="receiveChildSum"></my-sum>
   <p>从子组件获取到的值:</p>
  </div>
</template>

<script>
// 引入组件
import mySum from '../src/compents/sumCompent/sum-compent.vue'
export default {
  name: 'app',
  components: {
    // 注册组件
    mySum
  },
  data () {
    return {
      num1: 2,
      num2: 3,
      sum: 0
    }
  },
  methods: {
    /*
     * [receiveChildSum 监听到组件getSumFromChild事件触发的函数 将组件的sum值传给父组件]
     * @param {[Number]} sum [子组件传送的和]
     */
    receiveChildSum (sum) {
      this.sum = sum
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

现在能在本地端口查看到页面效果了

Image text

现在一个简单的组件已经封装完成了

封装vue插件

import sumCompent from './sum-compent'

// Vue.js 的插件应当有一个公开方法 install 
// 第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象
// 此处注意,组件需要添加name属性,代表注册的组件名称,也可以修改成其他的
 
//注册组件
sumCompent.install = Vue => Vue.component('cfPlugin', sumCompent)

// 导出组件
export default sumCompent
  • Vue的插件必须提供一个公开方法 install,该方法会在你使用该插件,也就是 Vue.use(yourPlugin)时被调用。这样也就给 Vue全局注入了你的所有的组件。

  • 修改webpack 配置文件

在 webpack.config.js 中 配置

// 执行环境
const NODE_ENV = process.env.NODE_ENV;

// npm run build 打包输出的配置
const NODE_BUILD = { 
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'sumCompent.js',
     // 指定的就是你使用require时的模块名
    library: 'sumCompent',
    // 指定输出格式
    libraryTarget: 'umd', 
     // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
    umdNamedDefine: true
}

// npm run dev 开发模式output输出配置
const NODE_DEV = {
  path: path.resolve(__dirname, './dist'),
  publicPath: '/dist/',
  filename: 'build.js'
}


module.exports = {
  ···
  //配置入口文件
   entry:  NODE_ENV === 'development' ? './src/main.js' : './src/compents/sumCompent/index.js',
  //配置输出
  output:  NODE_ENV === 'development' ? NODE_DEV : NODE_BUILD,
  ···
}

针对output配置说明

  • library:指定的就是你使用require时的模块名
  • libraryTarget:为了支持多种使用场景,我们需要选择合适的打包格式。常见的打包格式有 CMD、AMD、UMD,CMD只能在 Node 环境执行,AMD 只能在浏览器端执行,UMD 同时支持两种执行环境。显而易见,我们应该选择 UMD 格式。
  • umdNamedDefine:会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
  • package.json 配置
// 这个指 import my-plugin 的时候它会去检索的路径
"main": "dist/sumCompent.js",
// 发布开源因此需要将这个字段改为 false
"private": false,
  • 发布到npm

1) 在npm 官网注册账号 官网地址 (npm中的author尽量和npm账号一致) 2) 切换到需要发包的项目根目录下,登录npm账号,输入用户名、密码、邮箱

npm login

3)npm publish 执行发布

  npm publish
  • 应用

发布后可以在自己的 账号下看有没有发布的插件 然后在组件中应用

npm i yc_plugin
import myPlugin from 'yc_plugin'
Vue.use(myPlugin)

// 在文件引用的时候 标签为cfPlugin
// 因为前面注册为 sumCompent.install = Vue => Vue.component('cfPlugin', sumCompent)

npm 常见问题

  • 1)no_perms Private mode enable, only admin can publish this module

    这是因为镜像设置成淘宝镜像了,设置回来即可

npm config set registry http://registry.npmjs.org 
  • 2) npm publish failed put 500 unexpected status code 401

一般是没有登录,重新登录一下 npm login 即可

  • 3) npm ERR! you do not have permission to publish “your module name”. Are you logged in as the correct user?

包名被占用,改个包名即可。最好在官网查一下是否有包名被占用,之后再重命名

  • 4) you must verify your email before publishing a new package

    邮箱未验证,去官网验证一下邮箱

  • 5) 更新版本

需要在package.json 中更改version 字段

… 为解决问题

  • 多组件封装