搭建项目:
- 可以通过vue-cli3快速搭建项目:(https://cli.vuejs.org/zh/guide/installation.html)
npm install -g @vue/cli
- 通过vue ui启动图形化界面(图形化搭建项目)
vue ui
启动之后的界面:
创建项目
选择默认的配置
项目目录结构调整
|--- examples // 项目原src目录,改成examples作为示例展示
|--- packages // 新增packages用于存放组件
配置项目以支持新的目录结构
通过了上面的目录调整,我们可能会遇到两个问题:
- 项目的src目录改成examples,导致项目无法运行
- 新增package目录,该目录未加入webpack编译(cli3提供了一个vue.config.js配置文件,是对项目和webpack的配置)
1. 配置项目的入口,修改配置中的pages选项
module.exports = {
// 修改 src 目录 为 examples 目录
pages: {
index: {
entry: 'examples/main.js',
template: 'public/index.html',
filename: 'index.html'
}
},
}
2. 支持对package目录的处理,修改配置中的chainWebpack选项
module.exports = {
// 扩展 webpack 配置,使 packages 加入编译
chainWebpack: config => {
config.module
.rule('js')
.include
.add(__dirname + 'packages')
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
}
所有的vue.config.js的配置:
module.exports = {
// 修改 src 目录 为 examples 目录
pages: {
index: {
entry: 'examples/main.js',
template: 'public/index.html',
filename: 'index.html'
}
},
// 扩展 webpack 配置,使 packages 加入编译
chainWebpack: config => {
config.module
.rule('js')
.include
.add(__dirname + 'packages')
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
}
编写组件
时间轴组件:npm-package-demo(示例)
1. 创建一个新的组件
在 packages 目录下,所有的单个组件都以文件夹的形式存储,所有这里创建一个目录 timeLine/
在 timeLine/ 目录下创建 src/ 目录存储组件源码
在 /timeLine 目录下创建 index.js 文件对外提供对组件的引用。
修改package/timeLine/index.js文件,实现对外提供引用
// 导入组件,组件必须声明 name
import timeLine from './src/index.vue'
// 为组件提供 install 安装方法,供按需引入
timeLine.install = function (Vue) {
Vue.component(timeLine.name, timeLine)
}
// 默认导出组件
export default timeLine
2. 整合所有的组件,对外导出,即一个完整的组件库
// 导入组件
import timeLine from "./timeLine"
// 存储组件列表
const components = [
timeLine
]
// 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
const install = function (Vue) {
// 判断是否安装
if (install.installed) return
// 遍历注册全局组件
components.map(component => Vue.component(component.name, component))
}
// 判断是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
// 导出的对象必须具有 install,才能被 Vue.use() 方法安装
install,
// 以下是具体的组件列表
timeLine
}
编写示例
1. 在main.js中注册组件库:
// 1、在示例中导入组件库
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);
// 本地
// 导入组件库
import timeLine from './../packages/index'
// 注册组件库
Vue.use(timeLine)
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
2. 在app.vue中使用该组件
<template>
<div class="container">
<timeLine
:dicList="dicList"
:timeLineObj="timeLineObj"
:labList="labList"
@addEchart="addEchart"
@changeType="changeType"
@timeChange="timeChange"
></timeLine>
</div>
</template>
<script>
export default {
data () {
return {
dicList:[],
dicDeList:[
{
code: "010005",
createTime: "2020-10-21 13:15:36",
creator: "1",
descCn: "影像报告",
id: 102,
operator: "1",
parentId: 97,
sort: "5",
updateTime: "2020-10-21T05:15:39.000+00:00",
value: "image_report",
cdict: [
{
cdict: null,
code: "010005001",
createTime: "2020-10-21 13:15:36",
creator: "1",
descCn: "影像",
id: 121,
operator: "1",
parentId: 102,
sort: "1",
updateTime: "2020-10-21T05:15:39.000+00:00",
value: "image"
}
]
},
{
code: "010006",
createTime: "2020-10-21 13:15:36",
creator: "1",
descCn: "病理报告",
id: 103,
operator: "1",
parentId: 97,
sort: "6",
updateTime: "2020-10-21T05:15:39.000+00:00",
value: "pathology_report",
cdict: [
{
cdict: null,
code: "010006001",
createTime: "2020-10-21 13:15:36",
creator: "1",
descCn: "病理",
id: 125,
operator: "1",
parentId: 103,
sort: "1",
updateTime: "2020-10-21T05:15:39.000+00:00",
value: "pathology"
}
]
}
],
timeLineObj:{
"2020-09-11": {
"image": {
dateTime: "2020-09-11 02:10:00",
title: "肺部CT"
},
"pathology":{
dateTime: "2020-09-11 02:10:00",
title: '"内镜活检组织"示慢性炎,局灶鳞上皮化生。'
}
}
},
labList:[]
}
},
mounted () {
setTimeout(() => {
this.dicList = this.dicDeList;
}, 2000);
},
components: {
// timeLine: components.timeLine
},
methods: {
addEchart (val) {
console.log(val)
},
changeType (val) {
console.log(val)
},
timeChange (val) {
console.log(val)
}
}
}
</script>
<style lang="less" scoped>
.container {
margin: 20px 50px;
min-height: 800px;
height: 800px;
}
</style>
发布到npm,方便在多个项目中引用
1、package.json 中新增一条编译为库的命令
以下我们在 scripts 中新增一条命令 npm run lib
说明:
–target: 构建目标,默认为应用模式。这里修改为 lib 启用库模式。
–dest : 输出目录,默认 dist。这里我们改成 lib
[entry]: 最后一个参数为入口文件,默认为 src/App.vue。这里我们指定编译 packages/ 组件库目录。
"lib": "vue-cli-service build --target lib --name npm-package-demo --dest lib packages/index.js",
执行编译库命令
npm run lib
2、配置 package.json 文件中发布到 npm 的字段
name: 包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。
version: 版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。
description: 描述。
main: 入口文件,该字段需指向我们最终编译后的包文件。
keyword:关键字,以空格分离希望用户最终搜索的词。
author:作者
private:是否私有,需要修改为 false 才能发布到 npm
license: 开源协议
以下为参考设置
{
“name”: “npm-package-demo”,
“version”: “1.0.0”,
“description”: “基于 Vue 的组件示例”,
“main”: “lib/npm-package-demo.umd.min.js”,
“keyword”: “npm-package-demo”,
“private”: false
}
3、添加 .npmignore 文件,设置忽略发布文件
我们发布到 npm 中,只有编译后的 lib 目录、package.json、README.md才是需要被发布的。所以我们需要设置忽略目录和文件。
和 .gitignore 的语法一样,具体需要提交什么文件,看各自的实际情况。
忽略目录
examples/
packages/
public/
忽略指定文件
vue.config.js
babel.config.js
*.map
4. 登录到npm
首先需要在npm上注册一个账号(npm官网)
- 如果配置了淘宝镜像,先改回npm镜像:
npm config set registry http://registry.npmjs.org
- 在终端执行登录命令,输入用户名、密码、邮箱即可登录。
npm login
5. 发布到npm
执行发布命令,发布组件到npm
npm publish
我这边发布报错了,是因为name在npm上有相同的
现在把package.json中的name改为npm-package-demo-hz,然后重新发布
发布成功了,现在可以在npm上搜索到
引用npm发布的组件包
- 全局注册组件,在main.js:
// 引入npm包
import components from "npm-package-demo-hz";
import 'npm-package-demo-hz/lib/timeline.css';
// 使用vue组册组件
Vue.use(components.timeLine)
- 局部引入组件:
// 引入npm包
import components from "npm-package-demo-hz";
import 'npm-package-demo-hz/lib/timeline.css';
// 局部注册组件
components: {
timeLine: components.timeLine
},
注意:没有引入css会导致样式报错,这里本来想在vue.config.js中配置css的loader的,但是还没有解决,这样就必须引入css的样式文件
参考:
因为项目原因,这边需要把一个组件抽离出来,让多个项目都可以使用这个组件。
参考的文档:
示例的npm包,在github上的地址:
https://github.com/HZhen/npm-package-demo-hz