vue组件库和组件文档生成

vue组件库和组件文档生成公司现役组件库项目 公共资源或者新老项目切换仓库调整 src 目录结构 src App vue main js packages 新建此文件夹用来存放组件 index js 组件入口 button vue 新增一个 button 组件 记得带上 name icon 新增一个 icon 组件 记得带上 namepackages index js 所有组件的入口 import

公司现役组件库项目,公共资源或者新老项目切换仓库

调整 src 目录结构

|--src |-- App.vue |-- main.js |-- packages // 新建此文件夹用来存放组件 |-- index.js // 组件入口 |-- button.vue // 新增一个button组件,记得带上name |-- icon // 新增一个icon组件,记得带上name 

packages/index.js

// 所有组件的入口 import Button from './button.vue' import Icon from './icon.vue' // 全局注册 const install = Vue => { 
    Vue.component(Button.name, Button) Vue.component(Icon.name, Icon) } // 防止使用者直接以方式引入 if (typeof window.Vue !== 'undefined') { 
    install(Vue) // 直接通过script方式引入组件 } export default { 
    install } 

测试组件

import okrUi from './packages/index' Vue.use(okrUi) 

app.vue 直接使用

<okr-icon> 
     okr-icon> <okt-btn> 
      okt-btn> 

接下来就简单了,只要在 packages 中新增组件就可以,在 index.js 中注册即可

关于发布

okr-ui 目录下新建.npmignore

src // 源码不发 public // 公用资源不发 test // 测试代码不发 

package.json

 "private": false, // 私有的改成false "version": "0.1.0", // 版本必须每次不一样 

测试组件

https://vue-test-utils.vuejs.org/zh/installation/testing-single-file-components-with-karma.html

Karma 是一个启动浏览器运行测试并生成报告的测试运行器。 Mocha 框架撰写测试,同时用 chai 作为断言库。

  • 安装依赖
    npm install --save-dev @vue/test-utils karma karma-chrome-launcher karma-mocha karma-sourcemap-loader karma-spec-reporter karma-webpack mocha

  • 安装 chai
    npm install --save-dev karma-chai


    官方的配置案例

var webpackConfig = require('./webpack.config.js') module.exports = function(config) {     config.set({     frameworks: ['mocha'], files: ['test//*.spec.js'], // 匹配所有的spec文件 preprocessors: {     '/*.spec.js': ['webpack', 'sourcemap'] }, webpack: webpackConfig, reporters: ['spec'], browsers: ['ChromeHeadless'] // 打开一个无头的浏览器, 单纯用Chrome会闪动 }) } 

组件打包

  • 打包后所有的组件都在 umd.min.js 中
    "main":"./dist/okr-ui.umd.min.js"

生成组件文档

使用 vuepress

  • 根目录下新建 doc 文件夹

    初始化
    npm init -y
    安装 vuepress
    npm i vuepress -D
    配置 packages.json 新增 script








 "docs:dev":"vuepress dev docs", "docs:build":"vuepress build docs" 

配置 vue-press

  1. doc 根目录下新建 docs(固定)
  2. docs 下新建 README.md(固定)
  3. docs 下新建 components 用于存放组件描述文件(固定)
  4. components 下新建 button.md(此处以 button 组件为例)

    README.md(内容格式固定)

--- home: true actionText: 欢迎 → actionLink: /components/button // 以button为例 features: - title: okr组件库 // 名称 details: okr组件库,用公共组件存放,新老项目过度组件存放 // 组件库描述 --- 

跑起来的内容是不是很熟悉???但是比较丑是不是?

美化组件库文档界面

  1. 在 docs 下新建文件夹.vuepress
  2. 在.vuepress 中新增配置文件 config.js
module.exports = { 
    title: 'okr-ui', // 网站标题 description: 'okr公共组件库', // 网站描述 dest: './build', // 设置输出目录 port: '8088', // 端口 themeConfig: { 
    // 主题配置 nav: [ { 
    text: '主页', link: '/' } // 导航条 ], sidebar: { 
    // 侧边栏配置 '/components/': [ { 
    collapsable: true, // 默认折叠 children: ['button'] } ] } } } 
  1. 在.vuepress 文件里新建 styles 文件夹,并在 styles 中新建文件 palette.styl(固定)
$codeBgColor = #fafafa $accentColor=#3eaf7c $textColor=#2c3e50 $borderColor=#eaecef $arrowBgColor=#ccc $badgeTipColor=#42b983 $badgeWarningColor=darken(#ffe564,35%) $badgeErrorColor=#da5961 .content pre { 
    margin: 0 !important; } .theme-default-content:not(.custom) { 
    max-width: 1000px !important; } 
  1. .vuepress 目录下新建 enhanceApp.js(固定)入口定义文件

    enhanceApp.js

import Vue from 'vue' import Element from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import hljs from 'highlight.js' import 'highlight.js/styles/googlecode.css' // 自定义指令 Vue.directive('highlight', function (el) {     let blocks = el.querySelectorAll('pre code') blocks.forEach(block => {     hljs.highlightBlock(block) }) }) export default ({     Vue, options, router, siteData }) => {     Vue.use(Element) // 变更,解决build异常问题提 Vue.mixin({     mounted() {     import('okr-ui') .then(function (m) {     Vue.use(m.default) }) .then(() => {     import('okr-ui/dist/okr-ui.css') // 组件库样式 }) } }) } 
  • okr-ui 没有安装怎么引用?
    • 去 okr-ui 根目录执行npm link 此命令是将该项目链接到全局
    • 然后在 docs 的文件中npm link okr-ui 此命令是将全局注册的 okr-ui 拉进来进行使用
    • 经过以上两步就能免发布使用了

测试

  1. .vuepress 下新建 components,此文件加下皆为全局组件
  2. 新建 button 文件夹/button 文件夹/test.vue
  3. 在 docs 根目录下的 conponents 的 button.md 进行测试

    button.md

    这样就会去.vuepress 组件中找到 button/test.vue 组件(固定写法)

运行命令 npm run docs:dev

  • corejs 丢失 npm i core-js@2
  • okr-ui 找不到???注意你的组件库中 package.json 中 main 属性有没有指定文件?

测试真实组件库中的组件

  • 还记得刚才在 doc 文档库中已经引入了 okr-ui 了对吧,已经引用了吧?直接测试组件吧
  • 比如我们在 okr-ui 中写了 okr-btn 这个按钮组件吧?

    docs/.vuepress/components/button/test.vue

    看页面是不是有了?

<template> <div> <okt-btn></okt-btn> </div> </template> 

实现类似于 element-ui 组件库的文档体验

在 .vuepress 下 components 中新建组件文档展示模板 demo-block.vue

<template> <div class="demo-block" :class="[blockClass, { hover: hovering }]" @mouseenter="hovering = true" @mouseleave="hovering = false" ref="demoBlockContainer" > <div style="padding:24px"> <slot name="source"></slot> </div> <div class="meta" ref="meta"> <div class="description" v-if="$slots.default"> <slot></slot> </div> <div class="highlight"> <slot name="highlight"></slot> </div> </div> <div class="demo-block-control" ref="control" @click="isExpanded = !isExpanded"> <transition name="arrow-slide"> <i :class="[iconClass, { hovering: hovering }]"></i> </transition> <transition name="text-slide"> <span v-show="hovering">{ 
   { 
    controlText }}</span> </transition> </div> </div> </template> <style lang="scss"> .demo-block { 
    border: solid 1px dashed; border-radius: 3px; transition: 0.2s; &.hover { 
    box-shadow: 0 0 8px 0 rgba(232, 237, 250, 0.6), 0 2px 4px 0 rgba(232, 237, 250, 0.5); } code { 
    font-family: Menlo, Monaco, Consolas, Courier, monospace; } .demo-button { 
    float: right; } .source { 
    padding: 24px; } .meta { 
    background-color: #fafafa; border-top: solid 1px #eaeefb; overflow: hidden; height: 0; transition: height 0.2s; } .description { 
    padding: 20px; box-sizing: border-box; border: solid 1px #ebebeb; border-radius: 3px; font-size: 14px; line-height: 22px; color: #666; word-break: break-word; margin: 10px; background-color: #fff; } p { 
    margin: 0; line-height: 26px; } ::v-deep code { 
    color: #5e6d82; background-color: #e6effb; margin: 0 4px; display: inline-block; padding: 1px 5px; font-size: 12px; border-radius: 3px; height: 18px; line-height: 18px; } } .highlight { 
    pre { 
    margin: 0; code { 
    color: black !important; } } code.hljs { 
    margin: 0; border: none; max-height: none; border-radius: 0; line-height: 1.8; color: black; &::before { 
    content: none; } } } .demo-block-control { 
    border-top: solid 1px #eaeefb; height: 44px; box-sizing: border-box; background-color: #fff; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; text-align: center; margin-top: -1px; color: #d3dce6; cursor: pointer; &.is-fixed { 
    position: fixed; bottom: 0; width: 868px; } i { 
    font-size: 16px; line-height: 44px; transition: 0.3s; &.hovering { 
    transform: translate(-40px); } } > span { 
    position: absolute; transform: translate(-30px); font-size: 14px; line-height: 44px; transition: 0.3s; display: inline-block; } &:hover { 
    color: #409eff; background-color: #f9fafc; } & .text-slide-enter, & .text-slide-leave-active { 
    opacity: 0; transform: translate(10px); } .control-button { 
    line-height: 26px; position: absolute; top: 0; right: 0; font-size: 14px; padding-left: 5px; padding-right: 25px; } } </style> <script type="text/babel"> export default { 
    name: 'DemoBlock', data() { 
    return { 
    hovering: false, isExpanded: false, fixedControl: false, scrollParent: null, langConfig: { 
    'hide-text': '隐藏代码', 'show-text': '显示代码', 'button-text': '在线运行', 'tooltip-text': '前往jsfiddle.net 运行此示例' } } }, props: { 
    jsfiddle: Object, default() { 
    return { 
   } } }, methods: { 
    scrollHandler() { 
    const { 
    top, bottom, left } = this.$refs.meta.getBoundingClientRect() this.fixedControl = bottom > document.documentElement.clientHeight && top + 44 <= document.documentElement.clientHeight }, removeScrollHandler() { 
    this.scrollParent && this.scrollParent.removeEventListener('scroll', this.scrollHandler) } }, computed: { 
    lang() { 
    return this.$route.path.split('/')[1] }, blockClass() { 
    return `demo-${ 
     this.lang} demo-${ 
     this.$router.currentRoute.path.split('/').pop()}` }, iconClass() { 
    return this.isExpanded ? 'el-icon-caret-top' : 'el-icon-caret-bottom' }, controlText() { 
    return this.isExpanded ? this.langConfig['hide-text'] : this.langConfig['show-text'] }, codeArea() { 
    return this.$refs['demoBlockContainer'].getElementsByClassName('meta')[0] }, codeAreaHeight() { 
    if (this.$refs['demoBlockContainer'].getElementsByClassName('description').length > 0) { 
    return ( this.$refs['demoBlockContainer'].getElementsByClassName('description')[0].clientHeight + this.$refs['demoBlockContainer'].getElementsByClassName('highlight')[0].clientHeight + 20 ) } return this.$refs['demoBlockContainer'].getElementsByClassName('highlight')[0].clientHeight } }, watch: { 
    isExpanded(val) { 
    this.codeArea.style.height = val ? `${ 
     this.codeAreaHeight + 1}px` : '0' if (!val) { 
    this.fixedControl = false this.$refs.control.style.left = '0' this.removeScrollHandler() return } setTimeout(() => { 
    this.scrollParent = document.querySelector('.page-component__scroll > .el-scrollbar__warp') this.scrollParent && this.scrollParent.addEventListener('scroll', this.scrollHandler) this.scrollHandler() }, 200) } }, mounted() { 
    console.log(this.$refs.demoBlockContainer) this.$nextTick(() => { 
    console.log(this.$refs['demoBlockContainer']) let highlight = this.$refs['demoBlockContainer'].getElementsByClassName('highlight')[0] if (this.$refs['demoBlockContainer'].getElementsByClassName('description').lenght === 0) { 
    highlight.style.width = '100%' highlight.borderRight = 'none' } }) }, beforeDestroy() { 
    this.removeScrollHandler() } } </script> 

重新运行代码,是不是体验很棒??

代码地址

:sunhailiang/publish-ui.git

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225169.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午9:56
下一篇 2026年3月17日 上午9:57


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号