基于elementUI改造成自己的UI库

5,700 阅读6分钟

规矩先介绍一下本文内容,由于一些项目对于UI控件的定制化要求比较高,但是又不想全部ui自己完全实现,我就想到了这个方法,将element修改一下变成自己的UI控件库,可以通过修改elementui的源码并发布到自己的github上,这样在vue项目中使用的时候跟其他依赖包一样下载下来就好了,使用方法跟elementui完全一致。

这种方法也是存在弊端的,例如element版本升级了或者是修复了bug,你这边如果还想同步代码,那么你就需要根据官网修改的记录去修改一遍你项目里相应的代码。

运行环境:

vue: 2.6.11

vue-cli:2.9.6 (使用这个脚手架构建的vue项目)

element-ui:2.13.0(基于这个版本修改成自己ui库)

一、新建构建一个vue项目

这个简单,我就简单罗列一下主要过程

1、初始化一个vue项目

2、运行vue项目

vue run dev

项目能正常运行起来就行了

二、下载element-ui源码,并修改。

1、下载element-ui源码

下载成功后目录结构

目录介绍:

build:放置webpack的配置文件。

examples:放置element api的页面文档。

packages:放置element的组件(css样式放置在这个目录下theme-chalk下)。

src/directives:放置自定义指令。

src/locale:放置语言的配置文件。

src/mixins:放置组件用的混合文件。

src/transitions:放置动画配置文件。

src/utils:放置用到工具函数文件。

src/index.js:组件注册的入口文件。

test:测试文件。

types:这个文件里放了typescript的数据类。

2、运行element-ui项目

npm install //安装依赖

npm run dev:play //项目运行在8085端口

其实运行的就是examples/play/index.vue的页面,这样就可以在我们更改源码的时候方便我们进行调试。

3、开始修改项目名称

把所有的element-ui替换成chen-ui

替换过后再次运行项目发现运行不起来了,很正常,意料之中。

咱们先看一下是什么问题

(此处省略一张图片,其实是我忘记截图了)

大概的意思就是找不到某些组件,但是不要慌,你把项目关掉重新打开,在运行 一般就好了

4、运行npm run dist

这一步主要是生成lib目录,这个目录里的代码才是其他项目使用时实际引用的代码

之后我们上传到自己的git上

ao···

对了 不要忘了把 .gitignore文件中的lib去掉,这样才能把lib目录下的文件提交上去

5、项目中引用

1.首先在package.json文件中加入

"chen-ui": "git+https://github.com/chenmeng012/chen-ui.git",

前面是chen-ui项目名,后面是项目所在git地址。

2.在main.js中全局引入chen-ui,按需引入的方式和element-ui的用法一致。我只里采用全局引入的方式

import Vue from 'vue';
import App from './App';
import router from './router';
import ChenUI from 'chen-ui';
import 'chen-ui/lib/theme-chalk/index.css';

Vue.config.productionTip = false;
Vue.use(ChenUI);

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

3.在组件中使用chen-ui

修改helloWorld.vue文件

<template>
  <div class="hello">
    <el-button @click="dialogVisible = true">显示DIALOG</el-button>
    <el-dialog
        title="提示"
        :visible.sync="dialogVisible"
        width="30%"
        :before-close="handleClose">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      dialogVisible: false,
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods: {
    handleClose(done) {
      this.$confirm('确认关闭?')
        .then(_ => {
          done();
        })
        .catch(_ => {});
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

运行项目,看一下效果

好了,项目正常运行,并且chen-ui能够正常使用。

6.配置自动更新chen-ui命令

首先在vue-demo项目的build 目录下新建update-chen-ui.js、update-chen-ui.bat、update-chen-ui.sh三个文件

注:这三个文件可以不用新建,可以手动删除chen-ui之后再cnpm i chen-ui就好了,但是如果你们项目使用了jenkins打板机,这样配置的话会很方便,当然还得配置pom.xml文件等,这里就不细讲了。

// update-chen-ui.js
const os = require("os");
let exec = require('child_process').exec;

function isWindows() {
  return os.platform() === 'win32';
}

let cmd = null;
if (isWindows()) {
  cmd = "cd build && update-chen-ui.bat";
} else {
  cmd = "./build/update-chen-ui.sh";
}

exec(cmd, (err, stdout) => {
  if (err) {
    console.error(err);
  }
  if (stdout) {
    console.log(stdout);
  }
});

windows系统

// update-chen-ui.bat
@echo off
chcp 65001

cd ../node_modules

rd /s /q _chen-ui@2.13.0@chen-ui //node_modules中_chen-ui@2.13.0@chen-ui文件夹名称

if %errorlevel%==0 (
  echo 清除_chen-ui@2.13.0@chen-ui成功!
) else (
  echo 清除_chen-ui@2.13.0@chen-ui失败!
)

rd /s /q chen-ui //node_modules中chen-ui文件夹名称

if %errorlevel%==0 (
  echo 清除chen-ui成功!
) else (
  echo 清除chen-ui失败!
)

cd ..

cnpm i chen-ui //安装chen-ui

if %errorlevel%==0 ( //这段提示好像输出不出来,不知道原因,知道的大佬可以联系我,万分感谢
  echo 安装chen-ui成功!
) else (
  echo 安装chen-ui失败!
)

注:bat这个文件不要用webstorm编辑会运行不了(出现这个问题可能是我的webstorm有问题,具体还没找到原因),要用记事本或者是notepad++进行编译。

Linux系统

// update-chen-ui.sh
#!/usr/bin/env bash

echo "清理旧的chen-ui安装..."
cd ./node_modules

rm -rf  _chen-ui@2.13.0@chen-ui //node_modules中_chen-ui@2.13.0@chen-ui文件夹名称

if [ $? -ne 0 ]; then
    echo "删除 node_modules/_chen-ui@2.13.0@chen-ui 失败"
fi

rm -rf  chen-ui //node_modules中chen-ui文件夹名称

if [ $? -ne 0 ]; then
    echo "删除 node_modules/chen-ui 失败"
fi


echo "更新chen-ui..."
cd ..
cnpm i chen-ui

if [ $? -ne 0 ]; then
    echo "执行chen-ui失败"
else
    echo "更新chen-ui OK"
fi

之后在package.json中加入一个scripts命令

update:ui": "node ./build/update-ctx-ui.js",

那这样就可以执行npm命令就可以自动更新chen-ui了

7.接下来修改chen-ui代码,达到定制ui控件的目的。

再来看一下chen-ui的目录

其实咱们主要修改的是package下的代码

为了更好的调试代码,咱们先将chen-ui这个项目运行起来

npm run dev:play

文章上面介绍过,项目运行的主页面是在examples/play/index.vue文件,打开这个文件,发现他是默认引入了一个input组件。咱们先引入一个select组件。

页面也能正常运行

接下来我要实现一个功能,我的项目中用到的一个功能。这个功能是在select下拉选项的最下面增加一个按钮用于做一些操作。

咱们先找到select组件,package/select

要实现的功能具体修改代码在package/select/select.vue文件

先来在template增加html部分

我用截图吧,上下文代码太多,不好表现,修改的代码我都用选中来表示

接下来是computed

接下来是props

最后是methods

vue文件也就修改完了。

接下来添加样式

样式文件都在packages/theme-chalk/src下

咱们找到select-dropdown.scss文件,添加样式

样式文件也就修改完了。

之后在 examples/play/index.vue使用一下

运行一下项目,看一下效果

可以 可以,可以运行,并且功能也就实现了。

8.更新vue-demo中的chen-ui

在chen-ui项目中执行 npm run dist

用来更行lib文件,也就是其他项目引用的真正的代码。

在更新之前,别忘了先把chen-ui的代码提交到git上!!

在vue-demo项目中执行npm run update:ui

更新完成后咱们试一下在项目中是否可以直接使用

修改一下HelloWorld.vue文件

<template>
  <div class="hello">
    <el-select v-model="value" placeholder="请选择"
               :bottom-button="{title:'新建',visible:true,closeAfterClick:false}"
               @bottom-button-click="handleClick">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      options: [{
        value: '选项1',
        label: '黄金糕'
      }, {
        value: '选项2',
        label: '双皮奶'
      }, {
        value: '选项3',
        label: '蚵仔煎'
      }, {
        value: '选项4',
        label: '龙须面'
      }, {
        value: '选项5',
        label: '北京烤鸭'
      }],
      value: ''
    }
  },
  methods: {
    handleClick() {
      this.$message('点击了新增');
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

看一下页面效果

也是好使的

至此本篇文章也就结束了


三、赠送的内容

再追加点内容吧!!!

咱们看到element-ui中有这样的一个组件scrollbar,也就是滚动条,这个在element-ui中没有公布出去的一个组件,正常情况下咱们是不能使用的。现在就把它公布出去,让其他项目可以引用这个组件。

1.在types目录下新建一个scrollbar.d.ts文件,文件内容如下

import {ElementUIComponent} from "./component";

export declare class ElScrollbar extends ElementUIComponent{}

2.将原来的element-ui.d.ts改名为chen-ui.d.ts,之后修改代码

之后提交,再在vue-demo中更新chen-ui

修改一下HelloWorld.vue文件

<template>
  <div class="hello">
    <el-scrollbar style="height: 200px">
      <div v-for="item in scrollArr">
        {{item.title}}
      </div>
    </el-scrollbar>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {}
  },
  computed: {
    scrollArr() {
      let arr = [];
      for(let i = 0; i < 50; i++) {
        arr.push({title: `项目${i}`})
      }
      return arr
    }
  },
  methods: {}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

现在在项目中也是可以使用scrollbar了

但是有一个小bug在上面这张图的下面红框中有一个横向滚动条的框,这个是scrollbar样式有点问题,他是在package/theme-chalk/src/scrollbar

在chen-ui项目中别忘记npm run dist!

其实scrollbar组件还可以传入参数,我就不介绍了,这个通过源码,实践一下就能知道参数的作用了。

这样再更新chen-ui就好了。我就不再截图了。

上面简单的介绍了两种个简单的例子,形目中可能还会有其他的需求,这就需要自己去看源码,根据自己的需求去修改源码。

我也只是提供一种思路,其实还可以将package整个文件夹复制到自己的项目中去使用,当成自己的组件使用,当然还得修改代码,并且添加一些配置,还是比较麻烦的,有时间我再专门写一篇关于此类问题的文章吧。


小白一枚,不喜勿喷。当然文中可能存在不足和错误,还请各位大佬指正,万分感谢!!