UI工具之Storybook

Overview

今天科普一個(gè)有趣的前端開源工具——Stroybook匈子,一個(gè) UI 的可視化容器,可以視作組件庫的 wiki。

Storybook is an open source tool for developing UI components in isolation for React, Vue, and Angular. It makes building stunning UIs organized and efficient.

效果如下所示:左側(cè)組件導(dǎo)航;右側(cè)是組件細(xì)節(jié),還可以做一些可視化操作留凭。

Story

基本用法

我這里以 VUE 項(xiàng)目為例,簡(jiǎn)單介紹一下如何在項(xiàng)目里集成 storybook赌莺。
官方給出了一個(gè)極簡(jiǎn)的集成方法冰抢,只要在根目錄的命令行敲下如下一行就行了。(本文結(jié)束)

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

如上自動(dòng)化集成方式太過精簡(jiǎn)艘狭,讓人不知所措挎扰,所以我還是介紹一下手工集成的方式翠订。

添加依賴

先在 devDependencies 里添加@storybook

yarn add @storybook/vue -D

官方文檔里還會(huì)要求我們添加許多額外的依賴,但是現(xiàn)代的 vue 項(xiàng)目基本是用 vue-cli 腳手架生成的遵倦,它已經(jīng)添加了足夠多的 dev 依賴尽超。一般來說是 storybook 的服務(wù)已經(jīng)可以直接啟動(dòng)了的,當(dāng)然之后顯示失敗的話也會(huì)提示你缺少了某幾個(gè)依賴梧躺,大家可以根據(jù)提示添加依賴似谁。 babel-preset-vue是最高頻的缺失,可能是這個(gè)庫好多年沒更新了掠哥,現(xiàn)在的腳手架已經(jīng)把它忘了巩踏。如果確實(shí)沒有,就照例添加即可续搀。

yarn add babel-preset-vue -D

創(chuàng)建 config.js 文件

storybook 自然也有配置文件塞琼,我們?cè)诟夸浝锝ㄒ粋€(gè).storybook/config.js文件。這里吐槽一下前端的配置文件禁舷,實(shí)在是太多太多了彪杉,根目錄里基本全是這類東西了。多到我們組里開發(fā)了一年多的小朋友牵咙,還沒認(rèn)清所有派近。

然后在該配置文件里寫上如下內(nèi)容:

// .storybook/config.js
import { configure } from '@storybook/vue';

configure(require.context('../src/components', true, /\.stories\.js$/), module);

配置挺直白的,就是讓 storybook 服務(wù)找到src/components文件夾下所有.stories.js結(jié)尾的文件洁桌。這里的每一個(gè) story渴丸,都會(huì)指向一個(gè) vue component,就把它當(dāng)做該組件的說明即可另凌。

寫一個(gè)組件

我們?cè)?src/components 下寫一個(gè)自己的組件——MyButton.vue曙强。

<!- MyButton.vue ->
<template>
    <button class="button-style" @click="onClick">
        <slot></slot>
    </button>
</template>

<script>
export default {
    name: 'my-button',
    methods: {
    onClick() {
      console.log('Hello World!');
    },
  },
}
</script>

<style scoped>
.button-style {
    border-radius: 35% 10%;
    color: #FFF;
    background-color: #00bcd4;
    font-size: 2em;
    line-height: 1.2em;
    margin: 1em 1em;
    cursor: pointer;
}
</style>

組件很簡(jiǎn)單,就是封裝了原生 button tag:加了點(diǎn)樣式途茫,并且當(dāng)點(diǎn)擊它時(shí)控制臺(tái)能打出Hello World!

編寫 stories

stories 其實(shí)可以隨意放置,我這里就 follow 項(xiàng)目里 jest 的風(fēng)格溪食,把 stories 也放在了組件旁邊囊卜。

src/components
 ├── MyButton.vue
 ├── MyButton.stories.js
 └── MyButton.spec.js

@story/vue,其實(shí)就是在 js 文件里寫了個(gè)無狀態(tài)的 vue 組件错沃,寫法也很簡(jiǎn)單:引用組件栅组,注冊(cè)組件,模版封裝枢析。結(jié)束玉掸!

// MyButton.stories.js
import MyButton from './MyButton.vue';

export default { title: 'My-Button' };

export const Component = () => ({
    components: { MyButton },
    template: '<my-button>my button</my-button>'
  });

運(yùn)行 storybook

Storybook 的服務(wù)其實(shí)就是 webpack-dev-server,開發(fā)時(shí)可以熱加載醒叁,很方便編寫 stories 和 vue 組件本身司浪。我們給服務(wù)設(shè)置個(gè)端口泊业,比如 6006,開始運(yùn)行:

yarn start-storybook -p 6006

不出意外的話啊易,chrome 會(huì)自己打開localhost:6006吁伺。瀏覽器如下所示。左側(cè)列出了組件導(dǎo)航租谈,名字就是MyButton.stories.jstitle篮奄;右側(cè)是真實(shí)組件的樣式,點(diǎn)擊后割去,@click事件觸發(fā)窟却,打印出Hello World!

My Button

如果你想打包成靜態(tài)資源發(fā)布,也很容易:

yarn build-storybook

默認(rèn)會(huì)在根目錄會(huì)創(chuàng)建一個(gè).out文件夾呻逆,里面就是所有靜態(tài)資源了夸赫。

插件系統(tǒng)

主線劇情就到此為止了,但是 storybook 遠(yuǎn)不止于此页慷,它自帶一種叫 addon 的插件系統(tǒng)憔足。(不要問我,addon 和 plugin 的區(qū)別)酒繁。

我們可以自己寫一個(gè)簡(jiǎn)單的 addon滓彰, 比如顯示組件父親的 border。
還記得上面的.storybook/config.js文件嗎州袒?我們的 addon 就是在里面調(diào)用addDecorator揭绑,給所有的 story 包一層div,并顯示 border:

//.storybook/config.js

import { configure, addDecorator } from '@storybook/vue';

configure(require.context('../src/components', true, /\.stories\.js$/), module);

addDecorator(() => ({
    template:`
      <div style="border:solid;">
        <story/>
      </div>`
  }))

看一下結(jié)果郎哭,border 顯示出來了他匪。

Parent Border

當(dāng)然上面只是一個(gè)示例,現(xiàn)實(shí)意義不大夸研,我自己組里開發(fā)的時(shí)候用到 vuetify邦蜜,所以一般都會(huì)給所有控件包一層<v-app></v-app>,不然可能顯現(xiàn)不出 v 組件效果來亥至。

更多的時(shí)候悼沈,我們是直接集成社區(qū)里提供的 addon,比如@storybook/addon-knobs——用于調(diào)試 vue 的動(dòng)態(tài)變量姐扮。

還是一步一步來絮供,先裝個(gè)依賴:

yarn add @storybook/addon-knobs -D

接著在.storybook文件夾下創(chuàng)建addons.js文件,并引入依賴

// .storybook/addons.js
import '@storybook/addon-knobs/register';

然后啟動(dòng)服務(wù)茶敏,看到?jīng)]壤靶?下面多了個(gè)Knobs的 tab:

Knobs

之后把 knobs 添加到每一個(gè) story 就可以了。我們稍許修改一下代碼惊搏,通過storiesOf形式注冊(cè) story:

// MyButton.sotries.js
import { storiesOf } from '@storybook/vue';
import { withKnobs, text } from '@storybook/addon-knobs';

import MyButton from './MyButton.vue';

const components = () => ({
  components: { MyButton },
  props: {
    text: {
      default: text('Text', 'my button')
    }
  },
  template: `<MyButton>{{ text }}</MyButton>`
})

storiesOf('My-Button')
.add('components', components)
.addDecorator(withKnobs);

Knobs 根據(jù) story 的 props 生成 mock 數(shù)據(jù)贮乳,并雙向綁定對(duì)象組件的變量忧换,效果如下:

Knobs Button

小結(jié)

這期科普了一個(gè)比較有趣的開發(fā)工具——Storybook,它可以很方便地幫助我們組織基礎(chǔ) UI 控件塘揣。不同的前端開發(fā)可以通過很直觀的方式復(fù)用對(duì)方的組件包雀,以期減少冗余代碼。此外亲铡,我個(gè)人覺得編寫 Story——可視化組件的最大意義還是在于可測(cè)試才写;我們組之前的組件業(yè)務(wù)侵入太重,組件本身很難編寫單元測(cè)試奖蔓,因此前端的測(cè)試覆蓋率一直非常低≡薏荩現(xiàn)在想想,可能是我們本身就寫錯(cuò)組件了吆鹤,組件并非頁面厨疙,應(yīng)該能獨(dú)立展示,不該包含太多業(yè)務(wù)疑务。我現(xiàn)在在項(xiàng)目里強(qiáng)制加入 Storybook 也是希望能改善之前的困局沾凄。

相關(guān)

文章同步發(fā)布于an-Onion的Github。碼字不易知允,歡迎點(diǎn)贊撒蟀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市温鸽,隨后出現(xiàn)的幾起案子保屯,更是在濱河造成了極大的恐慌,老刑警劉巖涤垫,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姑尺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蝠猬,警方通過查閱死者的電腦和手機(jī)切蟋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榆芦,“玉大人敦姻,你說我怎么就攤上這事∑缧樱” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵迷守,是天一觀的道長(zhǎng)犬绒。 經(jīng)常有香客問我,道長(zhǎng)兑凿,這世上最難降的妖魔是什么凯力? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任茵瘾,我火速辦了婚禮,結(jié)果婚禮上咐鹤,老公的妹妹穿的比我還像新娘拗秘。我一直安慰自己,他們只是感情好祈惶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布雕旨。 她就那樣靜靜地躺著,像睡著了一般捧请。 火紅的嫁衣襯著肌膚如雪凡涩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天疹蛉,我揣著相機(jī)與錄音活箕,去河邊找鬼。 笑死可款,一個(gè)胖子當(dāng)著我的面吹牛育韩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闺鲸,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筋讨,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了翠拣?” 一聲冷哼從身側(cè)響起版仔,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎误墓,沒想到半個(gè)月后蛮粮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谜慌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年然想,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欣范。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡变泄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出恼琼,到底是詐尸還是另有隱情妨蛹,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布晴竞,位于F島的核電站蛙卤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颤难,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一神年、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧行嗤,春花似錦已日、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至既琴,卻和暖如春占婉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背甫恩。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工逆济, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人磺箕。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓奖慌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親松靡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子简僧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 安裝vue腳手架: Node.js>=8.9沒有vue-cli3的先安裝一下: 安裝完后查看版本: 創(chuàng)建項(xiàng)目: 選...
    helloyoucan閱讀 10,685評(píng)論 0 7
  • 前言 最近掐指一算發(fā)現(xiàn)本月還有篇技術(shù)博文沒寫~,雖然隨便拿一篇日常積累的文章锅锨,或者把最近重構(gòu)的一些點(diǎn)拿出來講都可以...
    臨水照影233閱讀 11,993評(píng)論 0 7
  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實(shí)用庫 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 element★...
    嘗了又嘗閱讀 1,151評(píng)論 0 1
  • 原文鏈接對(duì)于一名前端開發(fā)者牺弄,必須面對(duì)的就是組件化開發(fā)。我做Angular開發(fā)已經(jīng)有些日子了届案,也曾為自己的項(xiàng)目開發(fā)過...
    Laura_hu閱讀 10,318評(píng)論 0 4
  • 目錄 第一章 介紹第二章 設(shè)計(jì)機(jī)制第三章 JNI類型和數(shù)據(jù)結(jié)構(gòu)第四章 JNI函數(shù)(1)第四章 JNI函數(shù)(2)第四...
    駱駝騎士閱讀 6,927評(píng)論 0 58