vue cli4构建基于typescript的vue组件并发布到npm
<h2>基于vue cli创建一个vue项目</h2><p> 首先安装最新的vue cli脚手架,</p>
<p> npm install --global @vue/cli</p>
<div class="cnblogs_code">
<pre>npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\@vue\cli\node_modules\fsevents)<span style="color: rgba(0, 0, 0, 1)">:
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform <span style="color: rgba(0, 0, 255, 1)">for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ @vue/cli@4.4.6<span style="color: rgba(0, 0, 0, 1)">
added 1230 packages from 670 contributors in 118.122s</span></span></span></pre>
</div>
<p> 查看安装的vue -V</p>
<div class="cnblogs_code">
<pre>@vue/cli 4.4.6</pre>
</div>
<p> 创建项目:vue create my-project-name(“my-project-name”,这个可以根据需要命名,尽量用英文)</p>
<div class="cnblogs_code">
<pre>Vue CLI v4.<span style="color: rgba(128, 0, 128, 1)">4.6
? Please pick a preset: Manually <span style="color: rgba(0, 0, 255, 1)">select<span style="color: rgba(0, 0, 0, 1)"> features
? Check the features needed <span style="color: rgba(0, 0, 255, 1)">for your project: Babel, TS, Router, Vuex, CSS Pre-<span style="color: rgba(0, 0, 0, 1)">processors, Linter
? Use class-style component syntax?<span style="color: rgba(0, 0, 0, 1)"> Yes
? Use Babel alongside TypeScript (required <span style="color: rgba(0, 0, 255, 1)">for modern mode, auto-detected polyfills, transpiling JSX)?<span style="color: rgba(0, 0, 0, 1)"> Yes
? Use history mode <span style="color: rgba(0, 0, 255, 1)">for router? (Requires proper server setup <span style="color: rgba(0, 0, 255, 1)">for index fallback <span style="color: rgba(0, 0, 255, 1)">in<span style="color: rgba(0, 0, 0, 1)"> production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with node-<span style="color: rgba(0, 0, 0, 1)">sass)
? Pick a linter /<span style="color: rgba(0, 0, 0, 1)"> formatter config: Prettier
?<span style="color: rgba(0, 0, 0, 1)"> Pick additional lint features: Lint on save
? Where <span style="color: rgba(0, 0, 255, 1)">do you prefer placing config <span style="color: rgba(0, 0, 255, 1)">for Babel, ESLint, etc.?<span style="color: rgba(0, 0, 0, 1)"> In dedicated config files
? Save this as a preset <span style="color: rgba(0, 0, 255, 1)">for future projects?<span style="color: rgba(0, 0, 0, 1)"> Yes
? Save preset as: ts_tmpl</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> 创建完成之后,会出现如下提示</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">⚓Running completion hooks...
�Generating README.md...
�Successfully created project my-project-<span style="color: rgba(0, 0, 0, 1)">name.
�Get started with the following commands:
$ cd my-project-<span style="color: rgba(0, 0, 0, 1)">name
$ npm run serve</span></span></span></pre>
</div>
<p> 根据提示执行命令</p>
<div class="cnblogs_code">
<pre>E:\vue_codes>cd my-project-<span style="color: rgba(0, 0, 0, 1)">name
E:\vue_codes\my-project-name><span style="color: rgba(0, 0, 0, 1)">npm run serve
> my-project-name@<span style="color: rgba(128, 0, 128, 1)">0.1.<span style="color: rgba(128, 0, 128, 1)">0 serve E:\vue_codes\my-project-<span style="color: rgba(0, 0, 0, 1)">name
> vue-cli-<span style="color: rgba(0, 0, 0, 1)">service serve
INFOStarting development server...
Starting type checking service...
Using <span style="color: rgba(128, 0, 128, 1)">1<span style="color: rgba(0, 0, 0, 1)"> worker with 2048MB memory limit
<span style="color: rgba(128, 0, 128, 1)">98%<span style="color: rgba(0, 0, 0, 1)"> after emitting CopyPlugin
DONECompiled successfully <span style="color: rgba(0, 0, 255, 1)">in 5304ms 上午11:<span style="color: rgba(128, 0, 128, 1)">13:<span style="color: rgba(128, 0, 128, 1)">54<span style="color: rgba(0, 0, 0, 1)">
No type errors found
Version: typescript <span style="color: rgba(128, 0, 128, 1)">3.9.<span style="color: rgba(128, 0, 128, 1)">7<span style="color: rgba(0, 0, 0, 1)">
Time: 3160ms
App running at:
- Local: http:<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)">localhost:8080/
- Network: http:<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)">192.168.1.95:8080/
<span style="color: rgba(0, 0, 0, 1)">
Note that the development build is not optimized.
To create a production build, run npm run build.</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> 在浏览器输入地址:http://localhost:8080/</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200729130056715-85707561.png" alt=""></p>
<p> 出现如上图所示界面,表示项目创建成功了。</p>
<p> 生成的代码目录结构如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200729130127083-1569212893.png" alt=""></p>
<p> <span style="vertical-align: inherit"><span style="vertical-align: inherit">两个声明文件:<em><span style="vertical-align: inherit"><span style="vertical-align: inherit">shims-vue.d.ts</span></span></em><span style="vertical-align: inherit"><span style="vertical-align: inherit">和<em><span style="vertical-align: inherit"><span style="vertical-align: inherit">shims.tsx.d.ts</span></span></em></span></span></span></span></p>
<p><em><span style="vertical-align: inherit"><span style="vertical-align: inherit"><em><span style="vertical-align: inherit"><span style="vertical-align: inherit"> shims-vue.d.ts</span></span></em>:</span></span></em><span style="vertical-align: inherit"><span style="vertical-align: inherit">由于 TypeScript 默认并不支持 *.vue 后缀的文件,所以在 vue 项目中引入的时候需要创建一个shims-vue.d.ts 文件,放在项目项目对应使用目录下,例如 src/shims-vue.d.ts,用来支持*.vue 后缀的文件</span></span></p>
<p><em><span style="vertical-align: inherit"><span style="vertical-align: inherit"> shims-tsx.d.ts</span></span></em><span style="vertical-align: inherit"><span style="vertical-align: inherit">:<span style="vertical-align: inherit"><span style="vertical-align: inherit">允许.tsx 结尾的文件,在 Vue 项目中编写 jsx 代码</span></span></span></span></p>
<p><code> tsconfig.json:</code>typescript配置文件,主要用于指定待编译的文件和定义编译选项</p>
<p> normalize.css:Normalize.css 是一个可以定制的CSS文件,它让不同的浏览器在渲染网页元素的时候形式更统一。Normalize.css是一种CSS reset的替代方案。</p>
<p> .browserslistrc:这个配置能够分享目标浏览器和nodejs版本在不同的前端工具。这些工具能根据目标浏览器自动来进行配置,Browserslist这个东西单独是没用的,(补充: 在vue官方脚手架中,browserslist字段会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。)</p>
<p> browserslist的配置文件:<br> > 1% 兼容全球使用率大于1%的游览器<br> last 2 versions 兼容每个游览器的最近两个版本<br> not ie <= 8 不兼容ie8及以下<br> 具体可见 browserslist。</p>
<div>
<div> babel.config.js:Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。</div>
postcss.config.js:用于配置将px转化成rem,和自动添加CSS浏览器前缀等。</div>
<div> esnext 是一个 JavaScript 库,可以将 ES6 草案规范语法转成今天的 JavaScript 语法。</div>
<h2>改造项目结构</h2>
<p> 这种组件项目和我们日常的项目还是有很大区别的,由于前面我采用的是vue cli创建的完整模板项目,这里许多东西用不到,我们就将其删掉,最终项目目录结构如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200731133920837-829924049.png" alt=""></p>
<p> examples:是组件使用示例</p>
<p> src/components:是组件源码</p>
<p> package.json代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
"name": "jie-echarts"<span style="color: rgba(0, 0, 0, 1)">,
"version": "0.1.0"<span style="color: rgba(0, 0, 0, 1)">,
<span style="color: rgba(255, 0, 0, 1)">"private": false,
"description": "echarts组件"<span style="color: rgba(0, 0, 0, 1)">,
<span style="color: rgba(255, 0, 0, 1)">"main": "dist/JieEcharts.common.js",
"author": "zouqj<zouyujie@126.com>"<span style="color: rgba(0, 0, 0, 1)">,
"license": "MIT"<span style="color: rgba(0, 0, 0, 1)">,
"scripts"<span style="color: rgba(0, 0, 0, 1)">: {
"serve": "vue-cli-service serve"<span style="color: rgba(0, 0, 0, 1)">,
"build": "vue-cli-service build"<span style="color: rgba(0, 0, 0, 1)">,
"lint": "vue-cli-service lint"<span style="color: rgba(0, 0, 0, 1)">,
<span style="color: rgba(255, 0, 0, 1)">"lib": "vue-cli-service build --target lib --name JieEcharts ./src/index.ts"<span style="color: rgba(0, 0, 0, 1)">
},<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<div style="color: rgba(212, 212, 212, 1); font-family: Consolas, "Courier New", monospace; font-weight: normal; font-size: 14px; line-height: 19px; white-space: pre">
<div style="color: rgba(212, 212, 212, 1); font-family: Consolas, "Courier New", monospace; font-weight: normal; font-size: 14px; line-height: 19px; white-space: pre"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(255, 0, 0, 1)">"repository": {</span></span><br><span style="color: rgba(255, 0, 0, 1)"> "type": "git",</span><br><span style="color: rgba(255, 0, 0, 1)"> "url": "git+https://github.com/zouyujie/vue-components/tree/master/jie-echarts"</span><br><span style="color: rgba(255, 0, 0, 1)"> },</span><br><span style="color: rgba(255, 0, 0, 1)"> "bugs": {</span><br><span style="color: rgba(255, 0, 0, 1)"> "url": "https://github.com/zouyujie/vue-components/issues"</span><br><span style="color: rgba(255, 0, 0, 1)"> },</span><br><span style="color: rgba(255, 0, 0, 1)"> "homepage": "https://github.com/zouyujie/vue-components/tree/master/jie-echarts",</span><br><span style="color: rgba(255, 0, 0, 1)"> "keywords": [</span><br><span style="color: rgba(255, 0, 0, 1)"> "vue",</span><br><span style="color: rgba(255, 0, 0, 1)"> "vuejs",</span><br><span style="color: rgba(255, 0, 0, 1)"> "typescript",</span><br><span style="color: rgba(255, 0, 0, 1)"> "vuecli4.x"</span><br><span style="color: rgba(255, 0, 0, 1)"> ],</span>
</div>
</div>
<pre><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">"dependencies"<span style="color: rgba(0, 0, 0, 1)">: {
"core-js": "^3.6.5"<span style="color: rgba(0, 0, 0, 1)">,
"echarts": "^4.8.0"<span style="color: rgba(0, 0, 0, 1)">,
"ts-loader": "^8.0.1"<span style="color: rgba(0, 0, 0, 1)">,
"vue": "^2.6.11"<span style="color: rgba(0, 0, 0, 1)">,
"vue-class-component": "^7.2.3"<span style="color: rgba(0, 0, 0, 1)">,
"vue-property-decorator": "^8.4.2"<span style="color: rgba(0, 0, 0, 1)">,
"vue-router": "^3.2.0"<span style="color: rgba(0, 0, 0, 1)">,
"vuex": "^3.4.0"<span style="color: rgba(0, 0, 0, 1)">
},
"devDependencies"<span style="color: rgba(0, 0, 0, 1)">: {
"@types/echarts": "^4.6.4"<span style="color: rgba(0, 0, 0, 1)">,
"@typescript-eslint/eslint-plugin": "^2.33.0"<span style="color: rgba(0, 0, 0, 1)">,
"@typescript-eslint/parser": "^2.33.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/cli-plugin-babel": "~4.4.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/cli-plugin-eslint": "~4.4.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/cli-plugin-router": "~4.4.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/cli-plugin-typescript": "~4.4.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/cli-plugin-vuex": "~4.4.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/cli-service": "~4.4.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/eslint-config-prettier": "^6.0.0"<span style="color: rgba(0, 0, 0, 1)">,
"@vue/eslint-config-typescript": "^5.0.2"<span style="color: rgba(0, 0, 0, 1)">,
"eslint": "^6.7.2"<span style="color: rgba(0, 0, 0, 1)">,
"eslint-plugin-prettier": "^3.1.3"<span style="color: rgba(0, 0, 0, 1)">,
"eslint-plugin-vue": "^6.2.2"<span style="color: rgba(0, 0, 0, 1)">,
"node-sass": "^4.12.0"<span style="color: rgba(0, 0, 0, 1)">,
"prettier": "^1.19.1"<span style="color: rgba(0, 0, 0, 1)">,
"sass-loader": "^8.0.2"<span style="color: rgba(0, 0, 0, 1)">,
"typescript": "~3.9.3"<span style="color: rgba(0, 0, 0, 1)">,
"vue-template-compiler": "^2.6.11"<span style="color: rgba(0, 0, 0, 1)">
}
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> 重点注意标红部分的配置。</p>
<p> tsconfig.json</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
"compilerOptions"<span style="color: rgba(0, 0, 0, 1)">: {
"target": "esnext"<span style="color: rgba(0, 0, 0, 1)">,
"module": "esnext"<span style="color: rgba(0, 0, 0, 1)">,
"strict": <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">,
"jsx": "preserve"<span style="color: rgba(0, 0, 0, 1)">,
"importHelpers": <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">,
"moduleResolution": "node"<span style="color: rgba(0, 0, 0, 1)">,
"experimentalDecorators": <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">,
"esModuleInterop": <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">,
"allowSyntheticDefaultImports": <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">,
"sourceMap": <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">,
"baseUrl": "."<span style="color: rgba(0, 0, 0, 1)">,
<span style="color: rgba(255, 0, 0, 1)">"typeRoots": ["/@types", "./node_modules/@types"],
"types": ["webpack-env"<span style="color: rgba(0, 0, 0, 1)">],
"paths"<span style="color: rgba(0, 0, 0, 1)">: {
"@/*": ["src/*"<span style="color: rgba(0, 0, 0, 1)">]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"<span style="color: rgba(0, 0, 0, 1)">]
},
"include"<span style="color: rgba(0, 0, 0, 1)">: [
"src/**/*.ts"<span style="color: rgba(0, 0, 0, 1)">,
"src/**/*.tsx"<span style="color: rgba(0, 0, 0, 1)">,
"src/**/*.vue"<span style="color: rgba(0, 0, 0, 1)">,
"tests/**/*.ts"<span style="color: rgba(0, 0, 0, 1)">,
"tests/**/*.tsx"<span style="color: rgba(0, 0, 0, 1)">
],
"exclude": ["node_modules"<span style="color: rgba(0, 0, 0, 1)">]
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> vue.config.js代码如下:</p>
<div class="cnblogs_code">
<pre>'use strict'<span style="color: rgba(0, 0, 0, 1)">;
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> Template version: 1.3.1<span style="color: rgba(0, 128, 0, 1)">
//<span style="color: rgba(0, 128, 0, 1)"> see http://vuejs-templates.github.io/webpack for documentation.
<span style="color: rgba(255, 0, 0, 1)">
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)">);
<span style="color: rgba(0, 0, 0, 1)">const webpack = require('webpack'</span><span style="color: rgba(0, 0, 0, 1)">);
const path = require('path'<span style="color: rgba(0, 0, 0, 1)">);
const resolve = (dir) =><span style="color: rgba(0, 0, 0, 1)"> path.resolve(__dirname, dir);
module.exports =<span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 修改 src 目录 为 examples 目录
<span style="color: rgba(0, 0, 0, 1)">pages: {
index: {
<span style="color: rgba(255, 0, 0, 1)"> entry: <span style="color: rgba(255, 0, 0, 1)">'examples/main.ts'<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)">,
template: 'public/index.html'<span style="color: rgba(0, 0, 0, 1)">,
filename: 'index.html'<span style="color: rgba(0, 0, 0, 1)">,
},
},
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> vue 通过 file-loader 用版本哈希值和正确的公共基础路径来决定最终的图片路径,再用 url-loader 将小于 4kb 的
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 图片内联,以减少 HTTP 请求的数量。所以我们可以通过 chainWebpack 调整图片的大小限制。例如,我们将
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 图片大小限制设置为 13kb,低于13kb的图片全部被内联,高于13kb的图片会放在单独的img文件夹中。
chainWebpack: (config) =><span style="color: rgba(0, 0, 0, 1)"> {
const imagesRule = config.module.rule('images'<span style="color: rgba(0, 0, 0, 1)">);
imagesRule
.use('url-loader'<span style="color: rgba(0, 0, 0, 1)">)
.loader('url-loader'<span style="color: rgba(0, 0, 0, 1)">)
.tap((options) => Object.assign(options, { limit: 13312<span style="color: rgba(0, 0, 0, 1)"> }));
},
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 设置css: { extract: false },可以强制内联,就不会将css单独打包成一个文件,导致页面没有style
css: { extract: <span style="color: rgba(0, 0, 255, 1)">false<span style="color: rgba(0, 0, 0, 1)"> },
productionSourceMap: <span style="color: rgba(0, 0, 255, 1)">false<span style="color: rgba(0, 0, 0, 1)">,
};</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> 说明:UglifyJS Webpack Plugin插件用来缩小(压缩优化)js文件,修改应用入口文件,examples/main.ts,方便执行npm run serve的时候,可以直接查看组件的示例。</p>
<p> .npmignore可以将一些不需要发布到npm的文件忽略掉,.npmignore配置如下:</p>
<div class="cnblogs_code">
<pre>.*<span style="color: rgba(0, 0, 0, 1)">
package-<span style="color: rgba(0, 0, 0, 1)">lock.json
/.git/
/.vscode/<span style="color: rgba(0, 0, 0, 1)">
tslint.json
tsconfig.json
*<span style="color: rgba(0, 0, 0, 1)">.log
.DS_Store
/dist<span style="color: rgba(0, 0, 0, 1)">
/examples<span style="color: rgba(0, 0, 0, 1)">
/node_modules<span style="color: rgba(0, 0, 0, 1)">
/public<span style="color: rgba(0, 0, 0, 1)">
/src<span style="color: rgba(0, 0, 0, 1)">
/tests
<span style="color: rgba(0, 0, 0, 1)">.browserslistrc
jest.config.js
vue.config.js
# local env files
.env.local
.env.*<span style="color: rgba(0, 0, 0, 1)">.local
# Log files
npm-debug.log*<span style="color: rgba(0, 0, 0, 1)">
yarn-debug.log*<span style="color: rgba(0, 0, 0, 1)">
yarn-error.log*<span style="color: rgba(0, 0, 0, 1)">
# Editor directories and files
.idea
.vscode
.gitignore
.npmignore
.npmrc
*<span style="color: rgba(0, 0, 0, 1)">.suo
*.ntvs*
*<span style="color: rgba(0, 0, 0, 1)">.njsproj
*<span style="color: rgba(0, 0, 0, 1)">.sln
*.sw?</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> components下面</p>
<p> index.ts代码,以插件的形式进行封装,方便全局引用:</p>
<div class="cnblogs_code">
<pre>import jieEcharts from './jie-echarts.vue'<span style="color: rgba(0, 0, 0, 1)">;
(jieEcharts as any).install = (Vue: any) =><span style="color: rgba(0, 0, 0, 1)"> {
Vue.component(jieEcharts.name, jieEcharts);
};
export <span style="color: rgba(0, 0, 255, 1)">default jieEcharts;</span></span></span></pre>
</div>
<p> jie-echarts.vue,是组件源码,代码:</p>
<div class="cnblogs_code">
<pre><template>
<!-- 每一个图表都有自己唯一的id,需要动态传入。 -->
<div :ref="id" :id="id" :class="myclass" :style="style" />
</template>
<script lang="ts"><span style="color: rgba(0, 0, 0, 1)">
import { Component, Vue, Prop, Watch } from "vue-property-decorator"<span style="color: rgba(0, 0, 0, 1)">;
import Echarts from "echarts"<span style="color: rgba(0, 0, 0, 1)">;
@Component({
name: "jie-echarts"<span style="color: rgba(0, 0, 0, 1)">
})
export <span style="color: rgba(0, 0, 255, 1)">default<span style="color: rgba(0, 0, 0, 1)"> class extends Vue {
@Prop({ <span style="color: rgba(0, 0, 255, 1)">default: "myCharts" }) private id!<span style="color: rgba(0, 0, 0, 1)">: string;
@Prop({ <span style="color: rgba(0, 0, 255, 1)">default: "100%" }) private width!<span style="color: rgba(0, 0, 0, 1)">: string;
@Prop({ <span style="color: rgba(0, 0, 255, 1)">default: "200px" }) private height!<span style="color: rgba(0, 0, 0, 1)">: string;
@Prop({ <span style="color: rgba(0, 0, 255, 1)">default: "echarts-line" }) private myclass!<span style="color: rgba(0, 0, 0, 1)">: string;
@Prop() private options!<span style="color: rgba(0, 0, 0, 1)">: object;
@Prop({ <span style="color: rgba(0, 0, 255, 1)">default: <span style="color: rgba(0, 0, 255, 1)">false }) private loading!: <span style="color: rgba(0, 0, 255, 1)">boolean<span style="color: rgba(0, 0, 0, 1)">;
private MyEcharts: any = <span style="color: rgba(0, 0, 255, 1)">null; <span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> echarts实例
<span style="color: rgba(0, 0, 0, 1)">
created() {
console.log("this.options :>> ", <span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.options);
}
mounted() {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.InitCharts();
}
get style() {
<span style="color: rgba(0, 0, 255, 1)">return<span style="color: rgba(0, 0, 0, 1)"> {
height: <span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.height,
width: <span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.width
};
}
@Watch("options", { deep: <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)"> })
onChangeOption(newVal: string, oldVal: string) {
<span style="color: rgba(0, 0, 255, 1)">if (<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts) {
<span style="color: rgba(0, 0, 255, 1)">if<span style="color: rgba(0, 0, 0, 1)"> (newVal) {
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> console.log(JSON.stringify(newVal))
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts.setOption(newVal, <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">);
} <span style="color: rgba(0, 0, 255, 1)">else<span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts.setOption(oldVal, <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">);
}
setTimeout(() =><span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts.resize();
});
} <span style="color: rgba(0, 0, 255, 1)">else<span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.InitCharts();
}
}
@Watch("height"<span style="color: rgba(0, 0, 0, 1)">)
onChangeHeight(val: string) {
<span style="color: rgba(0, 0, 255, 1)">if<span style="color: rgba(0, 0, 0, 1)"> (val) {
<span style="color: rgba(0, 0, 255, 1)">this.height =<span style="color: rgba(0, 0, 0, 1)"> val;
}
<span style="color: rgba(0, 0, 255, 1)">if (<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts) {
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts.setOption(<span style="color: rgba(0, 0, 255, 1)">this.options, <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">);
} <span style="color: rgba(0, 0, 255, 1)">else<span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.InitCharts();
}
}
@Watch("loading"<span style="color: rgba(0, 0, 0, 1)">)
onChangeLoading(val: <span style="color: rgba(0, 0, 255, 1)">boolean<span style="color: rgba(0, 0, 0, 1)">) {
<span style="color: rgba(0, 0, 255, 1)">if (val == <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">) {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.showLoading();
}
<span style="color: rgba(0, 0, 255, 1)">if (val == <span style="color: rgba(0, 0, 255, 1)">false<span style="color: rgba(0, 0, 0, 1)">) {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.hideLoading();
}
}
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)">-----------------------method----------------------
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 组件初始化
<span style="color: rgba(0, 0, 0, 1)">private InitCharts() {
const dom: any = <span style="color: rgba(0, 0, 255, 1)">this.$refs[<span style="color: rgba(0, 0, 255, 1)">this.id] as HTMLDivElement; <span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> document.getElementById(this.id);
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts =<span style="color: rgba(0, 0, 0, 1)"> Echarts.init(dom);
<span style="color: rgba(0, 0, 255, 1)">if (<span style="color: rgba(0, 0, 255, 1)">this.loading == <span style="color: rgba(0, 0, 255, 1)">true<span style="color: rgba(0, 0, 0, 1)">) {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.showLoading();
}
<span style="color: rgba(0, 128, 0, 1)">/*<span style="color: rgba(0, 128, 0, 1)">*
* 此方法适用于所有项目的图表,但是每个配置都需要在父组件传进来,相当于每个图表的配置都需要写一遍,不是特别的省代码,主要是灵活度高
* echarts的配置项,你可以直接在外边配置好,直接扔进来一个this.option
<span style="color: rgba(0, 128, 0, 1)">*/
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts.clear(); <span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 适用于大数据量的切换时图表绘制错误,先清空在重绘
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts.setOption(<span style="color: rgba(0, 0, 255, 1)">this.options, <span style="color: rgba(0, 0, 255, 1)">true); <span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 设置为true可以是图表切换数据时重新渲染
<span style="color: rgba(0, 0, 0, 1)">setTimeout(() =></span><span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts.resize();
});
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> 当窗口变化时随浏览器大小而改变
<span style="color: rgba(0, 0, 0, 1)"> window.addEventListener("resize", () =></span><span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts.resize();
});
<span style="color: rgba(0, 0, 255, 1)">this.MyEcharts.on("click", (params: any) =><span style="color: rgba(0, 0, 0, 1)"> {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.mapClick(params);
});
}
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)">组件单击事件
<span style="color: rgba(0, 0, 0, 1)">private mapClick(params: any) {
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> console.log(params, 999999);
<span style="color: rgba(0, 0, 0, 1)"> const data =</span><span style="color: rgba(0, 0, 0, 1)"> {
color: params.color,
data: params.data,
dataIndex: params.dataIndex,
seriesIndex: params.seriesIndex,
chartType: params.componentSubType
};
<span style="color: rgba(0, 0, 255, 1)">this.$parent.$emit("chartParams"<span style="color: rgba(0, 0, 0, 1)">, JSON.stringify(data));
<span style="color: rgba(0, 0, 255, 1)">if (params.seriesType == "map"<span style="color: rgba(0, 0, 0, 1)">) {
<span style="color: rgba(0, 0, 255, 1)">this.$emit("mapValue"<span style="color: rgba(0, 0, 0, 1)">, params.name);
} <span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 0, 1)">
<span style="color: rgba(0, 0, 255, 1)">this.$emit("eclick"<span style="color: rgba(0, 0, 0, 1)">, params);
}
private showLoading() {
<span style="color: rgba(0, 0, 255, 1)">if (<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts) {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts.showLoading({
text: "loading"
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> color: '#4cbbff',
<span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)"> textColor: '#4cbbff',
<span style="color: rgba(0, 0, 0, 1)"> });
}
}
private hideLoading() {
<span style="color: rgba(0, 0, 255, 1)">if (<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts) {
<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">.MyEcharts.hideLoading();
}
}<br> beforeDestroy() {<br> window.removeEventListener("resize", () => {<br> this.MyEcharts.resize();<br> });<br> }
}
</script>
<style lang="scss" scoped><span style="color: rgba(0, 0, 0, 1)">
.echarts-<span style="color: rgba(0, 0, 0, 1)">line {
height: 100%<span style="color: rgba(0, 0, 0, 1)">;
}
</style></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> @types目录下:</p>
<p> component.d.ts代码:</p>
<div class="cnblogs_code">
<pre>import Vue from 'vue'<span style="color: rgba(0, 0, 0, 1)">;
export class VanComponent {
static name: string;
static install(vue: <span style="color: rgba(0, 0, 255, 1)">typeof Vue): <span style="color: rgba(0, 0, 255, 1)">void<span style="color: rgba(0, 0, 0, 1)">;
}</span></span></span></span></pre>
</div>
<p> 说明:@types是npm的一个分支,当我们把npm包发上去,npm包就会托管到服务器,供大家下载,但是ts为了代码的可复用性,要申明一些静态类型文件,那些文件就是*.d.ts</p>
<p> shims-vue.d.ts代码:</p>
<div class="cnblogs_code">
<pre>declare module "*.vue"<span style="color: rgba(0, 0, 0, 1)"> {
import Vue from "vue"<span style="color: rgba(0, 0, 0, 1)">;
export <span style="color: rgba(0, 0, 255, 1)">default<span style="color: rgba(0, 0, 0, 1)"> Vue;
}</span></span></span></span></pre>
</div>
<p> App.vue,组件引入演示界面,代码:</p>
<div class="cnblogs_code">
<pre><template>
<div id="app">
<jie-echarts :options="echartsOptions"></jie-echarts>
</div>
</template>
<script lang="ts"><span style="color: rgba(0, 0, 0, 1)">
import { Component, Vue, Watch, Prop } from "vue-property-decorator"<span style="color: rgba(0, 0, 0, 1)">;
import jieEcharts from "../src/index"<span style="color: rgba(0, 0, 0, 1)">;
@Component({
components: {
jieEcharts
}
})
export <span style="color: rgba(0, 0, 255, 1)">default<span style="color: rgba(0, 0, 0, 1)"> class TestJieEchartsPreview extends Vue {
protected echartsOptions =<span style="color: rgba(0, 0, 0, 1)"> {
xAxis: {
type: "category"<span style="color: rgba(0, 0, 0, 1)">,
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"<span style="color: rgba(0, 0, 0, 1)">]
},
yAxis: {
type: "value"<span style="color: rgba(0, 0, 0, 1)">
},
series: [
{
data: ,
type: "line"<span style="color: rgba(0, 0, 0, 1)">
}
]
};
}
</script>
<style lang="scss"><span style="color: rgba(0, 0, 0, 1)">
#app {
font-family: Avenir, Helvetica, Arial, sans-<span style="color: rgba(0, 0, 0, 1)">serif;
-webkit-font-<span style="color: rgba(0, 0, 0, 1)">smoothing: antialiased;
-moz-osx-font-<span style="color: rgba(0, 0, 0, 1)">smoothing: grayscale;
text-<span style="color: rgba(0, 0, 0, 1)">align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-<span style="color: rgba(0, 0, 0, 1)">weight: bold;
color: #2c3e50;
&.router-link-exact-<span style="color: rgba(0, 0, 0, 1)">active {
color: #42b983;
}
}
}
</style></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> 执行npm run serve,运行结果如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200731134613168-700978222.png" alt=""></p>
<h2>发布到NPM</h2>
<div> 1.去https://www.npmjs.com/注册一个账号</div>
<div> 2.登录邮箱,点击激活连接</div>
<div><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200731132303812-1520119638.png" alt="">
<p> 3.执行npm login,进行登录</p>
<div class="cnblogs_code">
<pre>PS E:\vue_codes\my-project-name><span style="color: rgba(0, 0, 0, 1)"> npm login
Username: zouyujie
Password:
Email: (<span style="color: rgba(0, 0, 255, 1)">this IS public) zouyujie@126.com</span></span></pre>
</div>
<p> 如果你是使用的淘宝镜像,注意啊要先切换到npm官网镜像,切换方式:npm config set registry https://registry.npmjs.org/</p>
<p> 4.执行命令 npm publish,进行发布,如果出现如下图所示错误:</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200731132444824-1015226247.png" alt=""></p>
<p> 说明邮箱没有绑定成功,点击https://www.npmjs.com/email-edit,进行绑定,然后重新执行npm publish,运行结果如下:</p>
</div>
<div>
<div class="cnblogs_code">
<pre>PS E:\vue_codes\my-project-name><span style="color: rgba(0, 0, 0, 1)"> npm publish
npm notice
npm notice package: jie-echarts@0.1.0<span style="color: rgba(0, 0, 0, 1)">
npm notice === Tarball Contents ===<span style="color: rgba(0, 0, 0, 1)">
npm notice 632B dist/index.<span style="color: rgba(0, 0, 0, 1)">html
npm notice 4.3kB dist/favicon.<span style="color: rgba(0, 0, 0, 1)">ico
npm notice 66B babel.config.<span style="color: rgba(0, 0, 0, 1)">js
npm notice 965.0kB dist/js/chunk-vendors.80f39f1d.<span style="color: rgba(0, 0, 0, 1)">js
npm notice 6.3kB dist/js/index.f9222971.<span style="color: rgba(0, 0, 0, 1)">js
npm notice 1.4kB package.<span style="color: rgba(0, 0, 0, 1)">json
npm notice 327B README.<span style="color: rgba(0, 0, 255, 1)">md<span style="color: rgba(0, 0, 0, 1)">
npm notice === Tarball Details ===<span style="color: rgba(0, 0, 0, 1)">
npm notice name: jie-echarts
npm notice version: 0.1.0<span style="color: rgba(0, 0, 0, 1)">
npm notice package size:341.3<span style="color: rgba(0, 0, 0, 1)"> kB
npm notice unpacked size: 978.0<span style="color: rgba(0, 0, 0, 1)"> kB
npm notice shasum: 2b65bfa887ba4677dc95a36a4b0403ebfecc9fde
npm notice integrity: sha512-RwSE3lC8N3wZT[...]b1b9cvJ8UtL/w==<span style="color: rgba(0, 0, 0, 1)">
npm notice total <span style="color: rgba(0, 0, 255, 1)">files: 7<span style="color: rgba(0, 0, 0, 1)">
npm notice
+ jie-echarts@0.1.0</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p> 至此,npm发布成功。</p>
<p> 然后我们去npm上,查看我们发布的npm包,</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200731132619434-169405683.png" alt=""></p>
<p> 如果能看到如下图所示界面:</p>
<p><img src="https://img2020.cnblogs.com/blog/413851/202007/413851-20200731132657788-1887990657.png" alt=""></p>
<p> 说明已发布成功。</p>
<p><strong> 注意:</strong>每次重新发布都要记得<span style="color: rgba(255, 0, 0, 1)">修改一下版本号</span>,否则会发布失败。发布成功后,你的npm邮箱都会受到一封npm组件发布成功的邮件通知。</p>
<p> npm上地址:https://www.npmjs.com/package/jie-echarts</p>
<h2>安装jie-echarts</h2>
<p> npm i jie-echarts</p>
</div>
</div>
<div id="MySignature" role="contentinfo">
<div align="left"><div style="color: #111111"><table style="vertical-align: top">
<tbody><tr>
<td id="tdSign">博客地址:</td><td>http://www.cnblogs.com/jiekzou/</td>
<td rowspan="2"></td>
</tr>
<tr>
<td>博客版权:</td><td>本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。<br>如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!<br>再次感谢您耐心的读完本篇文章。 </td>
</tr>
<tr><td>其它:</td><td>
.net-QQ群4:<span style="color: green">612347965</span>
java-QQ群:<span style="color: green">805741535</span>
H5-QQ群:<span style="color: green">773766020</span><br>
<div>我的拙作
《Vue3.x+TypeScript实践指南》
《ASP.NET MVC企业级实战》
《H5+移动应用实战开发》
《Vue.js 2.x实践指南》
《JavaScript实用教程 》
《Node+MongoDB+React 项目实战开发》
已经出版,希望大家多多支持!</div></td></tr>
</tbody></table></div>
</div>
<p style=" margin-bottom:-13px;padding-top: 15px;"><img src="https://images.cnblogs.com/cnblogs_com/jiekzou/780174/t_240929014358_%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20240929094331.png" style=" border:2px solid #ddd;border-radius:20px;" height="326" width="235"></p><br><br>
来源:https://www.cnblogs.com/jiekzou/p/13424352.html
頁:
[1]