基于elementUI封装自己的UI组件库

不完美00 发表于 2019-12-04 15:55:22

标签: elementUI 自定义UI组件

- +

初始化 project

这里我们使用官方的 vue-cli 初始化一个 Vue 项目

npm install -g @vue/cli
# or
yarn global add @vue/cli
vue create admin-ui



    在src的同级目录创建packages文件夹,用于存放需要打包的组件

packages目录.png

    package目录结构

目录.png

接下来让我们写一个简单的Vue component,基于elementUI的input组件的封装

<template>
  <div v-show="showInput">
    <el-input v-model="currentValue" v-bind="$props" @keydown.enter.native="handleInputEnter" :placeholder="placeholder" :dataType="dataType" ref="input" :inputPattern='inputPattern'>
      
      </template>
    </el-input>
    <div :style="{ visibility: !!editorErrorMessage ? 'visible' : 'hidden' }">{{ editorErrorMessage }}</div>
  </div>
</template>
<script>
import { Input, Button, Select, Option } from 'element-ui'
import pattern from '../../pattern.js'
 
const EMAIL_ERROR = '邮箱验证失败';
 
export default {
  name: "FkInput",
  data() {
    return {
      editorErrorMessage: null,
      showInput: true,
      inputType: '',
      emailPattern: pattern.email
    };
  },
  props: {
    ...Input.props, //继承elementUI原有的props
    ...Button.props,
    ...Select.props,
    ...Option.props,
    value: {
      type: [Number, String],
      default: ''
    },
    placeholder: {
      type: String,
      default: '请输入内容'
    },
    inputPattern: {
      type: [Object, String],
      default: null
    }
  },
  computed: {
    currentValue: {
      get: function() {
        return this.value;
      },
      set: function(newValue) {
        this.$emit("input", newValue); // 通过 input 事件更新 model
      }
    }
  },
  methods: {
    evtChange(newValue, lr) {
      this.$emit('change', newValue, lr); // 事件传值
    },
    handleInputEnter() {
      if (this.inputType !== 'textarea') {
        this.validate()
      }
    },
    validate() {
      const type = this.dataType && this.dataType.toLowerCase();
      var pattern = this.inputPattern ? this.inputPattern.pattern : '',
        message = this.inputPattern ? this.inputPattern.message : '';
      if (type || pattern) {
        switch (type) {//在实际项目中需要对多种输入数据类型进行验证,本例只验证了邮箱
          case 'email':
            pattern = this.emailPattern;
            message = EMAIL_ERROR;
            break;
          default:
            break;
        }
        if (pattern && !pattern.test(this.currentValue || '')) {
          this.editorErrorMessage = message;
          return false;
        }
      }
      
      this.editorErrorMessage = '';
    }
  },
  mounted() {
    this.$nextTick(_ => {
      this.inputType = this.$refs.input.type;
    })
    console.log('mounted');
  },
  updata() {
 
  },
  watch: {
    currentValue: {
      immediate: true,
      handler(val) {
        this.$nextTick(_ => {
          if (this.inputType !== 'textarea' && val !== '') {
            this.validate();
          } else if (val == '') {
            this.editorErrorMessage = ''
          }
        });
      }
    }
  }
}
 
</script>
<style stylus="css">
</style>


组件需加上name属性,在使用组件时,用的就是name的值作为标签值,上面的input组件在使用时<fk-input></fk-input> 

配置 project

下面我们来配置当前项目, 以使其可以发布到 npm 上.

如果组件进行按需引入,我们需要每个组件注册到Vue上,因此单个组件中需要暴露我们的Component:

component1.png

/packages/input/index.js
import FkInput from './src/input.vue'
FkInput.install = function (Vue) {
             Vue.component(FkInput.name, FkInput)
}
export default FkInput

然后我们编辑入口文件 packages/index.js,使其被作为UI库导入时能自动在Vue中注册我们的Component:

import FkInput from './input/index.js'
const components = [
  FkInput
]
const install = function(Vue) {
  components.forEach(component => {
    Vue.component(component.name, component);
  });
}
 
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}
 
export default {
        FkInput,
        install
}
export {
  FkInput,
  install
}

elementUI的引入方式有两种:一种是按需引入,比如某个项目中只使用了某几个组件,可以使用下面的方式

import { Button,Input }
from 'element-ui'
Vue.use(Button)
Vue.use(Input)

如果项目中使用了很多elementUI组件,为了避免漏掉引入的组件,可以使用下面的引入方式

import UI from 'element-ui'
Vue.use(UI)

此处也是为了可以使用按需引入的方式进行加载组件,export了两次;

export暴露出来可以在使用时按需引入,export default暴露出来的组件只能在使用时全局引入。

接下来我们添加 build项目的脚本到package.json的scripts中:

package.png

 其中 --name admin-ui 指定的是要发布的library的名称,我们执行上面新家的脚本:

npm run lib


这里我们选择默认发布我们的 *.common.js 文件, 所以我们在 package.json中添加main属性.

main.png

指定该属性后, 当我们引用该组件库时, 会默认加载 main 中指定的文件.

最后, 我们再配置 package.json中的 files属性, 来配置我们想要发布到 npm 上的文件路径.

我们这里将用户引用我们的组件库可能用到的所有文件都放进来:

file.png

最终的配置为

conf.png

npm 发布

首先我们注册一个 npm 账号 (如果已有账号, 可以跳过此步骤)

npm add user// 按照提示输入用户名, 邮箱等即可


然后使用 npm login 登录注册号的状态

登录后可以使用 npm whoami 查看登录状态

在发布之前, 我们修改一下项目的名称(注意不要和已有项目名称冲突), 推荐使用 @username/projectName 的命名方式.

接下来我们就可以发布我们的 UI 组件库了, 在发布之前我们再编译一次, 让build出的文件为我们最新的修改:

npm run lib


我们使用下面的命令发布我们的项目:

npm publish --access public


需要注意的是 package.json中指定的version属性: 每次要更新我们的组件库都需要更新一下version,配置中的private属性需要设置为false

测试使用

这样我们就完成了自己的 UI 组件库的发布. 接下来我们可以在任何需要使用到该组件库的项目中使用:

Import UI '@ssthouse/admin-ui'
Vue.use(UI)


接下来我们就可以在 Vue的template中使用组件库中的 Component了:

<template>
  <fk-input v-model="input" :inputPattern="inputPattern" clearable></fk-input>
</template>
<script>
export default {
  name: '',
  data() {
    return {
      input: '',
      placeholder: '',
      inputPattern:{
        pattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
        message: '此信息是验证失败提示'
      }
    }
  }
}
}
 
</script>


最后

经过上面这些步骤后, 我们就拥有了一个属于自己的组件库了. 我们可以随时更新, 发布自己新版的组件库.

而依赖了该组件库的项目只需要使用简单的 npm 命令即可更新 : )


possitive(3) negative(0) views848 comments0

发送私信

最新评论

请先 登录 再评论.
相关文章
  • 2019年NodeJS框架Koa和Express选型比较

    Koa和Express都是NodeJS的主流应用开发框架。
    Express是一个完整的nodejs应用框架。Koa是由Express团队开发的,但是它有不同的关注点。Koa致力于核心中间件...

  • 谷歌ARCore技术特性简介

    谷歌美国时间2017.8.29号刚发布了ARCore预览版,这是一个类似于苹果ARKit的增强现实SDK,在此之前,谷歌虽然已投资AR平台Tango,但由于需要特定的硬件和传感器,...

  • CSS3原生变量(Native Variables)新特性简介

    对Web开发者来说,一个盼望已久的特性是CSS终于支持原生变量了!
    变量是程序语言中用来解决代码重复和进行表达式计算的关键概念(想想数学方程式中的x)。...

  • 函数式JavaScript编程基础概念:Curry和Partial Application

    本文介绍JS函数式编程中的两个概念:柯里(Curry)和部分应用程序(Partial Application)。什么是应用程序(Application)将函数应用于其参数以产生返回值的过...

  • 深入理解CSS3滤镜(filter)功能和实例详解

    CSS3滤镜功能源自SVG滤镜规范,SVG滤镜最早用来给矢量图添加类似PS中像素图的一些特效。
    把这个滤镜功能引入到普通HTML元素中可以带来很有趣的效果(模糊、...

  • 学习使用CSS制作进度条

    进度条是基础的界面控件,可用于多种场合,比如任务完成进度,手机充电状态等。本文介绍一个简单实用的进度条制作方法。预期效果如下图所示:直观上,我们可以把该进度条控件分为2个部分,外部的边界用来表示固定的目标范围,里面的条形部分用来表示当前进度。外部目标范围元素的CSS代码编写如下:.pb-scope

  • Blender2.7 快捷键一览表

    通用操作
    停止当前操作:ESC
    快捷搜索:SPACE撤销:ctrl+z重做:ctrl+shift+z渲染:F12
    单选:鼠标右键(RMB)全选:A
    框选:B
    刷选:...

  • 如何使用Three.js加载obj和mtl文件

    OBJ和MTL是3D模型的几何模型文件和材料文件。在最新的three.js版本(r78)中,以前的OBJMTLLoader类已废弃。现在要加载OBJ和MTL文件,需要结合OBJLoader和MTLLoade...

  • 如何使用WebGL创建一个逼真的下雨动画

    之前写过文章来分别讲解如何使用CSS3和Canvas2D实现过雨滴和下雨动画。通过背景处理看起来也有视觉上的3D效果,但并非真正的3D场景,如果要加入用户交互,进行36...

  • IE各版本CSS Hack(兼容性处理)语法速查表

    为了兼容IE各个版本,需要在CSS中添加额外的代码,比如以前常用的_width。之所以工作,是因为浏览器会忽略不能解析的样式规则,因此举个例子来说,把_width写在w...

  • 浏览器控制台报JS脚本执行错误:Module is not defined

    现在JS分成了两个分支,一部分在服务器端发展如NodeJS,一部分是传统的浏览器运行环境。
    有些插件在编写JS代码时,是针对Node编写的,所以直接在浏览器中使...

  • 如何使用CSS3实现一个平滑的3D文本标题

    要实现3D文本,基本上有3种方法:1. 使用CSS3的投影滤镜(filter: drop-shadow)2. 使用3d建模和CSS3 3d变换来实现(最真实)3. 使用CSS3 text-shadow属性来实现...

  • 如何使用CSS3实现书页(书本)卷角效果

    我们有时候想在页面显示一个公告或用户提示信息。一个常用设计是使用书签形状。我们可以给书签添加卷角效果,以使其更为逼真。所谓的“卷角”实际上可以用小角度...

  • 如何使用CSS3/SCSS实现逼真的车窗雨滴效果

    在天气预报类的Web移动应用中,常常需要实现屏幕的雨滴效果,表示阴雨天气。感觉上比较神奇,其实想通了,这个效果的实现只需要一点物理知识和CSS3的简单变换。实现一个小雨滴首先雨滴是一个个小的椭圆形元素:.raindrop

  • 更多...