【前端工程】前端組件化之設計組件庫系統(一)

前言

當業務愈來愈多,我發現很長一段時間,我一直在不一樣的應用程序中寫着相似的組件,或者把一個應用程序中的組件copy到另一個應用程序中,有的時候甚至把一個已經有的組件修改爲適合當下業務的新組件。css

不單單是曾經的我,當咱們的前端團隊愈來愈大,發現內部也有不少和我同樣的人。因爲內部成員沉澱過的組件不夠公開化,其餘人沒法當即知道團隊內部現有組件的沉澱狀況,而不斷重複造組件。前端

很明顯的在組件複用這塊,團隊的問題很大,若是組件沉澱的足夠具備可複用性,團隊內部業務開發效率將獲得很大提高。vue

因此就在思考,有沒有什麼高效的方法,可讓咱們把業務中常常須要複用的組件抽出來,而後能夠可視化,還要附帶具體的組件使用說明文檔?很幸運已經有了storyBook,它完美的知足了我想要的需求。node

storyBook建立組件庫系統

storyBook的一些好處

  • 支持不一樣框架
  • 組件文檔自動化生成
  • 組件可運行看效果同時支持代碼複製
  • 易上手

組件界面以下:
image.pngreact

storyBook搭建組件庫系統

以設置vue組件庫系統爲例webpack

一、初始化項目web

npx -p @storybook/cli sb init --type vue

二、安裝解析Vue文件的相關依賴npm

npm install vue --save 
npm install vue-loader vue-template-compiler @babel/core babel-loader babel-preset-vue --save-dev
//安裝樣式加載器,用於解析vue文件中的樣式部分
npm install -D sass-loader node-sass

安裝樣式加載器以後,須要在main.js中作以下配置:segmentfault

webpackFinal: async (config, { configType }) => {
    // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
    // You can change the configuration based on that.
    // 'PRODUCTION' is used when building the static version of storybook.

    // Make whatever fine-grained changes you need
    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../')
    })

    // Return the altered config
    return config
  }

三、編寫組件
默認會執行.stories.js結尾的文件,因此須要將組件放入此文件中,組件纔會顯示。
image.pngsass

.vue文件和咱們日常寫的vue文件同樣,.stories.js文件內容以下:

import {
  action
} from '@storybook/addon-actions'
import {
  linkTo
} from '@storybook/addon-links'

import ForchangeInput from './ForchangeInput'


export default {
  title: 'Input',
  component: ForchangeInput
}

export const Text = () => ({
  components: {
    ForchangeInput
  },
  template: '<ForchangeInput class="input"></ForchangeInput>',
  methods: {
    action: action('change')
  }
})

四、運行npm run storybook
以自定義的input組件爲例子:

<template>
  <input
    class="input-field"
    ref="input"
    v-bind="$props"
    :value="inputValue"
    @input="changeValue"
    :type="type"
    @keyup="handleKeyUp"
    @focus="handleFocus"
    @blur="handleBlur"
    @change="changeHander"
  />
</template>

<script>
const COMPONENT_NAME = 'enroll-input'
const EVENT_INPUT = 'input'
const EVENT_BLUR = 'blur'
const EVENT_FOCUS = 'focus'
const EVENT_CHANGE = 'change'
const EVENT_KEYUP = 'keyup'
const EVENT_INPUT_CHANGE = 'inputChange'

export default {
  name: COMPONENT_NAME,
  data() {
    return {
      inputValue: this.value,
      isFocus: false,
      isOnComposition: false,
      emittedInput: false
    }
  },

  props: {
    value: [String, Number],
    type: {
      type: String,
      default: 'text'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    placeholder: String,
    readonly: {
      type: Boolean,
      default: false
    },
    autofocus: {
      type: Boolean,
      default: false
    },
    autocomplete: {
      type: [Boolean, String],
      default: false
    }
  },

  watch: {
    value(newValue) {
      this.inputValue = newValue
    }
  },

  mounted() {},

  beforeDestroy() {},

  methods: {
    handleInputChange(e) {
      this.$emit(EVENT_INPUT_CHANGE, e)
    },

    handleKeyUp(e) {
      this.$emit(EVENT_KEYUP, e)
    },

    changeValue(e) {
      let newValue = e.target && e.target.value
      this.$emit(EVENT_INPUT, newValue.trim())
    },

    changeHander(e) {
      this.$emit(EVENT_CHANGE, e)
    },

    handleFocus(e) {
      this.$emit(EVENT_FOCUS, e)
    },

    handleBlur(e) {
      this.$emit(EVENT_BLUR, e)
    }
  }
}
</script>

<style lang="scss" scoped>
.input-field {
  width: 100%;
  background: #fff;
  border: solid 1px #dbdada;
}

input {
  border: none;
  font-size: 28px;
  color: #383333;
  font-weight: normal;
  font-stretch: normal;
  font-style: normal;
  line-height: normal;
  letter-spacing: normal;
  height: 44px;
  text-align: right;
}

input:-ms-input-placeholder {
  font-size: 24px;
  font-weight: normal;
  font-stretch: normal;
  font-style: normal;
  line-height: normal;
  letter-spacing: normal;
  color: #c3c1c1;
}

input:disabled,
textarea:disabled {
  -webkit-text-fill-color: #383333;
  -webkit-opacity: 1;
  color: #383333;
}
</style>

最後運行的組件效果:
在docs選項能夠看到有效果、事例代碼、有自動根據組件的props對象生成的配置參數列表、methods中的方法生成的事件列表。

運行視圖和事例代碼:
image.png

參數:
image.png

這就是storyBook的入門搭建,還有不少能夠挖掘的,能夠幫助咱們更高效率的構建可共享的清晰的組件庫系統。

參考資料:
組件化
storyBook建立組件系統
storyBook

相關文章
相關標籤/搜索