<!--
 * @Author: 41
 * @Date: 2022-05-02 20:45:25
 * @LastEditors: 41
 * @LastEditTime: 2022-05-04 22:18:06
 * @Description: 
-->
[toc]
# 1.用脚手架生成vue项目
```bash
npm install -g @vue/cli
# OR
yarn global add @vue/cli
```
- 可以使用`vue --version`查看版本号
- 创建一个心得项目`vue create kamen-ui`
***

之后就可以用下面得代码运行项目了
```bash
cd kamen-ui
yarn serve
# OR
npm run serve
```
# 2.项目结构小改变
- `components`放在外面
- `src`改名字为`examples`(注意，这里有bug,之后要改配置文件)
- 配置`vue.config.js`文件，重新配置文件入口！！！
```js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  pages: {
    index: {
      entry: 'examples/main.js',
      template: 'public/index.html',
      filename: 'index.html'
    }
  }
})
```
# 3.跑通一个组件demo
- 在`components`下面创建`css`和`lib`
- 1.`css`中创建`demo.scss`
- 2.创建`lib/demo/src/main.vue`然后编写
- 3.在`examples/main.js`中引入并`component`注册(这里scss报错，安装一下scss，注意版本号问题！很八嘎！)【这里直接用4的方法！】
- 4.为了方便，我们在`src`中写一个`index.js`,然后直接`use`这个就好了，会自动调用里面的`install`
```js
import Demo from './src/main.vue'

Demo.install = function (Vue) {
  Vue.component(Demo.name, Demo)
}

export default Demo
```
- 5.在`main.js`中`use`
```js
import { createApp } from 'vue'
import App from './App.vue'
import '../components/css/demo.scss'
import Demo from '../components/lib/demo/index' //***
let Vue = createApp(App)// ***
Vue.use(Demo)// ***
Vue.mount('#app')
```
- 6.在`App.vue`中使用demo组件，就可以看到组件了！
# 4.开发一个卡片组件
## 4.1设计组件
- 复用->通用性
- 这里还是省略吧，分析繁琐

|参数|说明|类型|是否必要|默认值|
|---|---|---|---|---|
|width    |卡片宽度    |Number     |false|-|
|imgSrc   |图片资源地址|String      |true|-|
|imgHeight|图片高度    |Number     |false|-|
|summary  |卡片概述    |String/Slot|false|-|
|footer   |卡片底部    |Slot       |false|-|
## 4.2编写html结构和样式代码
- 同3，我们创建好一个新组件的结构
- 不同的是，main.vue的结构多一点，多了一个props的编写先
- 在编写scss的时候，我们可以用`&`来简写
- 注意`:style`赋值和`v-if`，`slot`的使用吧,这些和平时写一个组件是一样的
## 4.3测试组件
- 注意一下插槽的使用就可以了！
- 图片资源可以放到`public`里面,方便测试！
- 比如指定插槽的名字
```js
  <m-card imgSrc="touxiang.png" summary="国王排名" width="170">
    <template v-slot:footer>
      <div class="footer">
        <div class="level">100人追番</div>
        <div class="price">烂尾番</div>
      </div>
    </template>
  </m-card>
```
- 不指定会放到默认插槽里面

# 5.Webpack打包js为umd模块(开始组件库的打包了！)
## 5.1了解webpack
- 打包组件库需要很多自定义的配置！(默认的打包可能满足不了我们的需求)
  - entry
  - output
  - loader 
  - plugin
  - mode
## 5.2编写配置文件
- 我们新建一个`webpack.component.js`文件(这里配置list的方法很巧妙)
```js
const glob = require('glob')
const list = {}
async function makeList (dirPash, list) {
  const files = glob.sync(`${dirPash}/**/index.js`) //获取文件下的所有文件路径
  // console.log('files:', files);
  for (let file of files) {
    const component = file.split(/[/.]/)[2]  // 取出组件名
    // console.log(component);
    list[component] = `./${file}`            // 组件名-组件路径的赋值
  }
}
makeList('components/lib', list)
// console.log(list);
module.exports = {
  entry: list,
  output: {
    filename: '[name].umd.js',  // 使用umd模块 card.umd.js
    path: 'dist',
    library: 'mui',
    libraryTarget: 'umd'
  },
}
```
***
- 配置vue.loader之前要先下载loader`npm i vue-loader -D`
```js
const { VueLoaderPlugin } = require('vue-loader')
// ...
  plugins: [
    new VueLoaderPlugin(),
  ],
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader'
          }
        ]
      }
    ]
  }
// ...
```
***
- package里面编写命令(使用后yes，安装`webpack-cli`)
```js
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "build:js": "webpack --config ./webpack.component.js"
  },
```
***
- 发现错误，配置webpack要使用绝对路径
```js
const path = require('path')
  output: {
    filename: '[name].umd.js',  // 使用umd模块 card.umd.js
    path: path.resolve(__dirname, 'dist'), // 改的这里
    library: 'mui',
    libraryTarget: 'umd'
  },
```
- 之后运行命令会有一个warning，是因为我们没有设置mode字段，我们设置一下
## 5.3完成了按需加载，可以加载全部吗？
- 在`component/lib`文件下新建`index.js`
```js
import Demo from './demo'
import Card from './card'
const components = {
  Demo,
  Card
}
const install = function (Vue) {
  if (install.installed) return  // 避免重复安装
  Object.keys(components).forEach(key => {
    Vue.component(components[key].name, components[key])
  })
}
const API = {
  install
}
export default API
```

# 6.前端模块化
## 为什么要进行模块化？
业务复杂，所以切分
全局函数(污染，命名冲突)---对象封装(解决命名冲突，内部状态可以被外部改写)---匿名函数自调用(数据私有，闭包暴露)---now！
- 现代模块化规范，以文件为模块，有自己的作用域
  - CommonJS(适用于服务端)
    - 文件作用域
    - 缓存
    - 同步加载(会阻塞脚本,不适用于浏览器)
  - AMD(适用于浏览器)
    - 文件作用域
    - 非同步加载
  - UMD(前后端跨平台的模块化解决方案)
    - 1.先判断是否支持Node.js模块格式(exports是否存在)，存在则使用Node.js模块格式
    - 2.再判断是否支持AMD(define是否存在)，存在则使用AMD方式加载模块
    - 3.前两个都不存在，则将模块公开到全局

# 7.使用Gulp打包CSS
## 7.1分开压缩
- 新建`gulpfile.js`
```js
const gulp = require('gulp')
const sass = require('gulp-sass') // sass->css
const minifyCSS = require('gulp-minify-css')
gulp.task('sass', async function () {
  return gulp.src('components/css/**/*.scss')
    .pipe(sass())
    .pipe(minifyCSS())
    .pipe(gulp.dest('dist/css'))
})
```
- 安装`npm i gulp gulp-sass gulp-minify-css -D`
- 安装`npm i sass -d`
- 然后`sass`引用变成这样！
```js
const sass = require('gulp-sass')(require('sass'))
```
## 7.2一起压缩
- `index.scss`
```js
@import './card.scss';
@import './demo.scss';
```
# 总结命令，避免两次调用命令
`"build": "yarn build:js && yarn build:css"`

# 8.发布到npm
## 8.1注册和修改package配置
- 在npm官网注册账号登录！用户的package可以查看自己发表的库
- 更改package配置
  - 删掉`"private": true,`因为要公开！
  - 添加description等字段如下
```js
  "description": "41的组件库哦！",
  "main": "dist/index.umd.js",
  "keywords": [
    "kamen",
    "41",
    "vue",
    "ui"
  ],
  "author": "kamenrider41",
  "file": [
    "dist",
    "components"
  ],
```
## 8.2修改readme文件
- 省略一下，直接看readme文件就可以了！

## 8.3登录发布
- `npm login`登录，输入账户密码邮箱
- `npm publish`发布，这个会根据8.1的配置发布

# 9.测试发布后的组件库


# 10.搭建组件库文档站点(vue版本冲突，所以重开一个仓库写组件库文档了！)
## 10.1VuePress介绍
Vue驱动的静态网站生成器
- 简洁至上
- Vue驱动
- 高性能
## 10.2 使用
- `npm install -D vuepress`
- `mkdir docs`
- `echo '# Hello VuePress' > docs/README.md`
- 添加两条命令
```js
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
```
- 本地启动服务器
```js
yarn docs:dev
```
- 创建`componentDocs`文件夹，下面放组件的md文件
- 创建`.vuepress`文件夹，下面`public`放静态资源，`config.js`是配置，`components`是会用到的`vue`文件
- 这样就可以在`Docs`的组件`md`文件中使用`components`中的`vue`组件了(因为会全局挂载)
