(一)私有组件库搭建
汇总既有项目中的通用组件
私有组件实例
单条折线图
<line-chart
:seriesName="seriesName"
:seriesData="seriesData"
titleText="内存使用率(%)"
v-if="showGraph"
titleSubText="纯属虚构"
:unit="unit"
></line-chart>
多条折线图
大屏雷达图
<radar-chart
:title="title"
:legendName="legendName"
:indicator="indicator"
:seriesData="seriesData"
></radar-chart>
平滑折线图
<smooth-line-chart
:yAxisCfg="yAxisCfg"
:legendData="legendData"
:seriesData="seriesData"
:unit="unit"
></smooth-line-chart>
地图
<geo-map width="46%"></geo-map>
柱状图
<bar-chart :yAxisData="yAxisData" :seriesData="seriesData"></bar-chart>
在项目中安装方式
npm i vue_backend
在项目中使用方式
import Vue from 'vue'
import Backend from 'vue_backend'
Vue.use(Backend)
直接使用组件
<line-chart
:seriesName="seriesName"
:seriesData="seriesData"
titleText="内存使用率(%)"
v-if="showGraph"
titleSubText="纯属虚构"
:unit="unit"
>
</line-chart>
为什么搭建私有组件库
- 可复用 跨项目可以使用同一套私有组件库
- 方便维护 如需组件调整 只需要修改组件库 不需要跨项目重复修改
添加新组件原则
- 组件应先存在于具体项目中,经过重复验证后再抽象、沉淀到本组件库中
- 不涉及国际化、ajax 请求等业务逻辑
项目构建
1.新建 package.json
cd XXX[项目名]
npm init
2.Storybook for Vue
可以选择自动搭建 storybook 项目也可以使用手动搭建
自动搭建
npx -p @storybook/cli sb init --type vue
手动搭建
- 安装依赖
# 安装storybook
npm install @storybook/vue --save-dev
# 安装vue 以及需要的loader
npm install vue --save
npm install vue-loader vue-template-compiler @babel/core babel-loader babel-preset-vue --save-dev
- 在 package.json 添加启动项
{
"scripts": {
"storybook": "start-storybook"
}
}
- 创建 storybook 的配置文件
import { configure } from '@storybook/vue'
function loadStories() {
require('../stories/index.js')
// You can require as many stories as you need.
}
configure(loadStories, module)
- 创建测试文件 ./stories/elButton.stories.js
// 引入了 element-ui 可以针对 el-button 组件测试项目是否正常
import Vue from 'vue'
import { storiesOf } from '@storybook/vue'
storiesOf('elButton', module)
.add('with text', () => '<el-button>with text</el-button>')
.add('with emoji', () => '<el-button>😀 😎 👍 💯</el-button>')
.add('as a component', () => ({
template: '<el-button :disabled="true">rounded</el-button>'
}))
- 运行查看效果
npm run storybook
提取私有组件
- 创建测试文件 ./stories/changeTime.vue
<template>
<el-dialog
:title="title"
:visible.sync="show"
width="400px"
class="change-time-dialog"
:close-on-click-modal="false"
:before-close="handleClose"
>
<el-form :model="form" ref="form" style="margin-bottom:30px">
<el-form-item style="margin-bottom:0px !important">
<el-date-picker
type="date"
size="medium"
value-format="yyyy-MM-dd"
:placeholder="`请选择${title}`"
v-model="form.time"
style="width:94%"
></el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="handleClose">取消</el-button>
<el-button
size="small"
type="primary"
@click="handleConfirm('form')"
:disabled="disable"
>确定</el-button
>
</div>
</el-dialog>
</template>
<script>
export default {
data() {
return {
show: false,
form: {
time: ''
},
disable: false
}
},
props: {
visible: {
type: Boolean,
default: false
},
time: {
type: String,
default: ''
},
typeTime: {
type: String,
default: 'start'
},
title: {
type: String,
default: ''
},
referTime: {
// 参考时间
type: [Date, String],
default: ''
}
},
mounted() {
this.show = this.visible
this.form.time = this.time
},
methods: {
handleClose() {
this.$refs.form.resetFields()
this.show = false
this.$emit('update:visible', false)
this.$emit('update:time', '')
},
handleConfirm() {
if (this.typeTime === 'start') {
if (
new Date(this.form.time).getTime() >
new Date(this.referTime).getTime()
) {
this.$message.warning('起租时间必须小于等于退租时间')
return
}
}
if (this.typeTime === 'end') {
if (
new Date(this.form.time).getTime() <
new Date(this.referTime).getTime()
) {
this.$message.warning('退租时间必须大于等于起租时间')
return
}
}
this.$emit('changeTime', this.typeTime, this.form.time, this.clearData)
},
clearData() {
this.show = false
this.disable = false
this.$emit('update:visible', false)
}
}
}
</script>
<style lang="scss" scoped>
div.el-form-item__error {
top: 80% !important;
}
.change-time-dialog /deep/ .el-dialog__body {
padding-bottom: 0px !important;
}
</style>
- 创建测试文件 ./stories/changeTime.stories.js
import Vue from 'vue'
import { storiesOf } from '@storybook/vue'
import changeTime from './changeTime'
storiesOf('changeTime', module).add('修改时间', () => ({
components: { changeTime },
template: `<div>
<h4>选择时间:{{ curTime }}</h4>
<el-button @click="handleChangeTime">选择起租时间</el-button>
<change-time :title="changeTimeTitle"
:time.sync="curTime"
v-if="changeTimeVisiable"
:typeTime="changeTimeType"
:referTime="referTime"
ref="changeTime"
:visible.sync="changeTimeVisiable"
@changeTime="changeTime" />
</div>`,
data() {
return {
changeTimeTitle: '起租时间',
curTime: '2019-06-25',
changeTimeType: 'start',
changeTimeVisiable: false,
referTime: ''
}
},
methods: {
changeTime(type, time, fn) {
this.curTime = time
fn()
},
handleChangeTime() {
this.changeTimeVisiable = true
}
}
}))
scss 报错,es6 语法报错
- 解决 css 问题
// 安装相关loader
npm i -D node-sass less-loader css-loader style-loader
配置 webpack.config.js
const path = require('path')
const pathResolve = p => path.resolve(__dirname, '../', p)
module.exports = ({ config, mode }) => {
config.resolve.alias = {
...config.resolve.alias,
'@': pathResolve('stories'),
'~': pathResolve('node_modules')
}
config.module.rules.push({
test: /\.scss$/,
include: path.resolve(__dirname, '../stories'),
use: ['style-loader', 'css-loader', 'sass-loader']
})
config.module.rules.push({
test: /\.less$/,
include: path.resolve(__dirname, '../stories'),
use: ['style-loader', 'css-loader', 'less-loader']
})
if (process.env.NODE_ENV === 'production') {
config.output.filename = 'bundle.[name].js'
config.optimization.splitChunks.automaticNameDelimiter = '.'
config.optimization.runtimeChunk = {
name: entrypoint => `runtime.${entrypoint.name}`
}
}
// console.log(config);
return config
}
- 解决 babel 问题
同上,安装 loader 配置.babelrc 配置文件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。