Element UI 组件库分析和二次开发_make new <component-name>(1)

JavaScript

  • js的基本类型有哪些?引用类型有哪些?null和undefined的区别。

  • 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

  • Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?

  • JS常见的dom操作api

  • 解释一下事件冒泡和事件捕获

  • 事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?

  • 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

  • this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

  • call,apply,bind

  • 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

  • 创建对象的多种方式

  • 实现继承的多种方式和优缺点

  • new 一个对象具体做了什么

  • 手写Ajax,XMLHttpRequest

  • 变量提升

  • 举例说明一个匿名函数的典型用例

  • 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?

  • attribute和property的区别

  • document load和document DOMContentLoaded两个事件的区别

  • JS代码调试

  • 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

imgSet.forEach((img) => {
        img.src = ${base64svg}${window.btoa(window.atob(img.src.replace(base64svg, '')).replace(primaryLast, primaryColor))};
      });
      primaryLast = primaryColor;
    });
  }


  
构建新版本的时候要更改2个地方:


package.json 里的 version  
 build/bin/version.js 这段代码里写死的“2.15”改成 package.json 文件里 version 的“主版本号.次版本号”



if (!content[version]) content[version] = ‘2.15’;


**3、build:theme**  
  



“build:theme”: “node build/bin/gen-cssfile && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib lib/theme-chalk”


主要是处理样式相关的脚本。拆开来分析下:


**node build/bin/gen-cssfile**


执行该文件通过组件列表(components.json)生成组件样式入口文件 packages/theme-chalk/src/index.scss,并将所有组件的样式都导入。


**gulp build --gulpfile packages/theme-chalk/gulpfile.js**


把所有组件的 scss 文件(packages/theme-chalk/src/\*.scss)通过 gulp 编译成 css,并放置到 packages/theme-chalk/lib 目录下。


打包和压缩的工作平时一般交给 webpack 来做,但是基于工作流用 gulp 更加快捷和方便。


为什么需要编译呢?


因为 element 在使用时有两种引入方式:


全局引用:



import Vue from ‘vue’;
import ElementUI from ‘element-ui’;
import ‘element-ui/lib/theme-chalk/index.css’;
import App from ‘./App.vue’;
 
Vue.use(ElementUI);
 
new Vue({
  el: ‘#app’,
  render: h => h(App)
});


引入了 lib\theme-chalk\index.css 文件


局部引入:



import Vue from ‘vue’;
import { Button, Select } from ‘element-ui’;
import App from ‘./App.vue’;
 
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
/* 或写为
 * Vue.use(Button)
 * Vue.use(Select)
 */
 
new Vue({
  el: ‘#app’,
  render: h => h(App)
});


  
 不需要引入 css 文件,只需引入对应的 scss 文件。 这就是为什么需要编译 scss 的原因。


**cp-cli packages/theme-chalk/lib lib/theme-chalk**


cp-cli 是一个跨平台的 copy 工具,将gulp build --gulpfile .\packages\theme-chalk\gulpfile.js编译生成的 css 目录(packages/theme-chalk/lib)复制到 lib/theme-chalk 下,方便全局引入 css:



import ‘element-ui/lib/theme-chalk/index.css’;


**4、build:utils**



“build:utils”: “cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js”


将 src 目录下的内容忽略 index.js 通过 babel 转译后移动到 lib 下。


**5、build:umd**



“build:umd”: “node build/bin/build-locale.js”


执行后生成 umd 模块的语言包。


将 src/locale/lang 下的语言包都编译到 lib/umd/locale 下。


**6、clean**



“clean”: “rimraf lib && rimraf packages/*/lib && rimraf test/**/coverage”


清除打包后的文件。


**7、deploy:build (生成官网发布文件)**



“deploy:build”: “npm run build:file && cross-env NODE_ENV=production webpack --config build/webpack.demo.js && echo element.eleme.io>>examples/element-ui/CNAME”


npm run build:file 前文分析过了,主要构建官网文件。接下来分析新的构建脚本。


生产环境下构建官网:



cross-env NODE_ENV=production webpack --config build/webpack.demo.js


**8、deploy:extension**



“deploy:extension”: “cross-env NODE_ENV=production webpack --config build/webpack.extension.js”


在生产环境下构建主题插件,主题编辑器的 chorme 插件项目的 webpack 配置,项目在 extension 目录下。执行命令后会在 extension 目录下生成 dist 目录,其中包含了 chorme 插件,在浏览器加载已解压的扩展程序就可以使用主题生成插件。


**9、dev:extension**



“dev:extension”: “rimraf examples/extension/dist && cross-env NODE_ENV=development webpack --watch --config build/webpack.extension.js”


启动主题插件的开发环境,可以进行开发调试。


**10、dev**



“dev”: “npm run bootstrap && npm run build:file && cross-env NODE_ENV=development webpack-dev-server --config build/webpack.demo.js & node build/bin/template.js”


首先用 **npm run bootstrap** 安装依赖。**npm run build:file** 在前面也有提到,主要用来自动化生成一些文件。主要是 node build/bin/build-entry.js,用于生成 Element 的入口 js:先是读取根目录的 components.json,这个 json 文件维护着 Element 所有的组件路径映射关系,键为组件名,值为组件源码的入口文件;然后遍历键值,将所有组件进行 import,对外暴露 install 方法,把所有 import 的组件通过 Vue.component(name, component) 方式注册为全局组件,并且把一些弹窗类的组件挂载到 Vue 的原型链上。


在生成了入口文件的 src/index.js 之后就会运行 webpack-dev-server。


启动组件库本地开发环境。在更改后可以热更新官网。 


**11、dev:play**



“dev:play”: “npm run build:file && cross-env NODE_ENV=development PLAY_ENV=true webpack-dev-server --config build/webpack.demo.js”


组件测试项目,在 examples/play/index.vue 中可以引入组件库任意组件,也可以直接使用 dev 启动的项目,在文档中使用组件。


用于查看某个组件的效果。适用于组件按需加载的显示效果。在 webpack.demo.js 通过环境变量配置输入。


**build/webpack.demo.js**



const isPlay = !!process.env.PLAY_ENV;
// ……省略webpack具体配置
 
 entry: isProd ? {
    docs: ‘./examples/entry.js’
  } : (isPlay ? ‘./examples/play.js’ : ‘./examples/entry.js’),


**examples/play.js**



import Vue from ‘vue’;
import Element from ‘main/index.js’;
import App from ‘./play/index.vue’;
import ‘packages/theme-chalk/src/index.scss’;
 
Vue.use(Element);
 
new Vue({ // eslint-disable-line
  render: h => h(App)
}).$mount(‘#app’);


**12、dist**



“dist”: “npm run clean && npm run build:file && npm run lint && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme”


打包组件库。


npm run clean && npm run build:file && npm run lint 都已经解释过了,分别是清除上一次打包产物、生成入口文件以及 i18n 文件和 eslint 检测。


**webpack --config build/webpack.conf.js**


生成 umd 格式的 js 文件(index.js)



const path = require(‘path’);
const ProgressBarPlugin = require(‘progress-bar-webpack-plugin’);
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’);
const TerserPlugin = require(‘terser-webpack-plugin’);
 
const config = require(‘./config’);
console.log(config)
module.exports = {
  // 模式
  mode: ‘production’,
  // 入口
  entry: {
    app: [‘./src/index.js’]
  },
  // 输出
  output: {
    path: path.resolve(process.cwd(), ‘./lib’),
    publicPath: ‘/dist/’,
    // 输出的文件名
    filename: ‘index.js’,
    // 初始的chunk文件名称
    chunkFilename: ‘[id].js’,
    //  library 暴露为 AMD 模块。 在 AMD 或 CommonJS 的 require 之后可访问(libraryTarget:‘umd’)
    libraryTarget: ‘umd’,
    // 入口的默认导出将分配给 library target:
    // if your entry has a default export of MyDefaultModule
    // var MyDefaultModule = entry_return.default;
    libraryExport: ‘default’,
    // 输出一个库,为你的入口做导出。
    library: ‘ELEMENT’,
    // 会把 AMD 模块命名为 UMD 构建
    umdNamedDefine: true,
    // 为了使 UMD 构建在浏览器和 Node.js 上均可用,应将 output.globalObject 选项设置为 ‘this’。对于类似 web 的目标,默认为 self。
    globalObject: ‘typeof self !== ‘undefined’ ? self : this’
  },
  // 解析
  resolve: {
    // 能够使用户在引入模块时不带扩展.尝试按顺序解析这些后缀名。如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
    extensions: [‘.js’, ‘.vue’, ‘.json’],
    // 创建 import 或 require 的别名,来确保模块引入变得更简单。
    alias: config.alias
  },
  // 外部扩展
  externals: {
    vue: config.vue
  },
  // 优化
  optimization: {
    // 允许你通过提供一个或多个定制过的 TerserPlugin 实例, 覆盖默认压缩工具(minimizer)
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          output: {
            comments: false
          }
        }
      })
    ]
  },
  // 性能
  performance: {
    // 不展示警告或错误提示。
    // 官网推荐使用error,有助于防止把体积大的bundle部署到生产环境,从而影响网页的性能
    // 很奇怪这里要把它关闭
    hints: false
  },
  // stats对象
  stats: {
    // 告知 stats 是否添加关于子模块的信息。
    children: false
  },
  // 模块
  module: {
    // 使用babel-loader和vue-loader
    rules: [
      {
        test: /.(jsx?|babel|es6)KaTeX parse error: Expected 'EOF', got '}' at position 108: …-loader'       }̲,       {      …/,
        loader: ‘vue-loader’,
        options: {
          compilerOptions: {
            preserveWhitespace: false
          }
        }
      }
    ]
  },
  // 插件
  plugins: [
    new ProgressBarPlugin(),
    new VueLoaderPlugin()
  ]
};


  
**webpack --config build/webpack.common.js**


生成 commonjs 格式的 js 文件(element-ui.common.js),require 时默认加载的是这个文件。



libraryTarget: ‘commonjs2’


与 webpack.conf.js 不同在于输出 output 的 libraryExport。


前者暴露的是 commonjs2,后者暴露的是 umd。


**webpack --config build/webpack.component.js**


与前两者的 index.js 入口不同,以 components.json 为入口,将每一个组件打包生成一个文件,用于按需加载。


npm run build:utils && npm run build:umd && npm run build:theme 也已经讲过,分别是转译工具方法、转译语言包、生成样式文件。


**13、lint**



“lint”: “eslint src//* test//* packages//* build//* --quiet”


eslint 校验 src、packages 和 build 目录下的文件。


**14、pub**



“pub”: “npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js && sh build/deploy-faas.sh”


npm run bootstrap 下载依赖。


sh build/git-release.sh:主要是检测 dev 分支是否冲突。



#!/usr/bin/env sh

切换到dev分支

git checkout dev

检测本地是否有未提交文件

if test -n “$(git status --porcelain)”; then

输出日志

echo ‘Unclean working tree. Commit or stash changes first.’ >&2;
  exit 128;
fi

检测本地分支是否有误

if ! git fetch --quiet 2>/dev/null; then
  # 输出日志
  echo ‘There was a problem fetching your branch. Run git fetch to see more…’ >&2;
  exit 128;
fi

检测是否有最新提交

if test “0” != “$(git rev-list --count --left-only @‘{u}’…HEAD)”; then
  # 输出日志
  echo ‘Remote history differ. Please pull changes.’ >&2;
  exit 128;
fi

输出日志

echo ‘No conflicts.’ >&2;


  
 sh build/release.sh 脚本完成了以下工作:


1. 合并 dev 分支到 master
2. 修改样式包和组件库的版本号
3. 发布样式包和组件库
4. 提交 master 和 dev 分支到远程仓库


该脚本在发布组件库时可以使用,特别是其中自动更改版本号的功能(每次 publish 时都忘改版本号)。这里提交代码到远程仓库的日志很简单。



#!/usr/bin/env sh
set -e

切换到master

git checkout master

合并dev分支

git merge dev

npx: 使用本地已安装的可执行工具,而不需要配置 scripts

VERSION=npx select-version-cli

更新版本号

read -p “Releasing $VERSION - are you sure? (y/n)” -n 1 -r
echo    # (optional) move to a new line
if [[ R E P L Y =   [ Y y ] REPLY =~ ^[Yy] REPLY= [Yy] ]]
then
  # 输出:压缩版本
  echo "Releasing KaTeX parse error: Expected 'EOF', got '#' at position 18: …RSION ..."     #̲ build   # 编译打包…VERSION npm run dist
 
  # ssr test
  node test/ssr/require.test.js            
 
  # 发布到npm
  # publish theme
  # 输出:压缩theme-chalk版本
  echo “Releasing theme-chalk $VERSION …”
  cd packages/theme-chalk
  # 更改主题包的版本信息
  npm version $VERSION --message “[release] $VERSION”
  # 如果是beta版本则打个beta标签
  if [[ $VERSION =~ “beta” ]]
  then
    npm publish --tag beta
  else
    npm publish
  fi
  cd …/…
 
  # commit
  git add -A
  git commit -m “[build] $VERSION”
  # 更改组件库的版本信息
  npm version $VERSION --message "[release] KaTeX parse error: Expected 'EOF', got '#' at position 12: VERSION"   #̲ publish   # 发布…VERSION
  git checkout dev
  git rebase master
  git push eleme dev
  # 发布组件库
  if [[ $VERSION =~ “beta” ]]
  then
    npm publish --tag beta
  else
    npm publish
  fi
fi


  
 node build/bin/gen-indices.js 生成目录,支持搜索:



‘use strict’;
// 生成目录
const fs = require(‘fs’);
const path = require(‘path’);
// 是一个托管的全文、数字和分面搜索引擎,能够从第一次击键交付实时结果。
const algoliasearch = require(‘algoliasearch’);
// 将Unicode str转换为段字符串,确保在URL或文件名中使用它是安全的。
// https://www.npmjs.com/package/transliteration?activeTab=readme
// demo:
// slugify(‘你好,世界’);
// // ni-hao-shi-jie
const slugify = require(‘transliteration’).slugify;
// 密钥
其实前端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一个复习的路线:(以下体系的复习资料是我从各路大佬收集整理好的)

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

《前端开发四大模块核心知识笔记》

最后,说个题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue2中,对于element-ui组件的二次封装,可以按照以下步骤进行: 1. 需求分析:明确需要封装的element-ui组件,以及需要添加的功能和配置项。 2. 创建父组件:编写父组件的template和script代码,其中template中调用封装组件,script中定义需要传递给封装组件的props属性。 3. 创建封装组件:编写封装组件的template和script代码。在template中使用element-ui组件,并根据需要进行样式和布局的调整。在script中定义props属性,接收父组件传递的值,并监听element-ui组件的事件,触发update事件给父组件。 4. 通过临时变量传递值:由于父组件传递给封装组件的props不能直接作为封装组件的v-model属性传递给element-ui组件,所以需要在封装组件中定义一个临时变量来存储值,并将该变量与element-ui组件进行绑定。 5. 完成打通:在封装组件中监听中间件,接收到element-ui组件的update事件后,再将该事件传递给父组件。 总结来说,Vue2中对于element-ui组件的二次封装,需要创建父组件和封装组件,通过props属性传递值,并在封装组件中监听element-ui组件的事件并触发update事件给父组件。同时,需要使用临时变量来传递值给element-ui组件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue3+ts+element-plus 组件的二次封装-- 页脚分页el-pagination的二次封装](https://blog.csdn.net/cs492934056/article/details/128096257)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值