Storybook是一款開源的元件開發工具,它可以執行在主程式之外,因此開發者可以用它來獨立開發UI元件,或者用它來快速構建ui元件檔案。
目前Storybook支援的框架有:
可以看到,Storybook的功能是相當豐富的。本文將以Vue為例,從零開始搭建一個自己的Storybook。
首先自己建立一下資料夾,storybook-demo。
官方檔案中給的安裝方式有2種,第一種是自動化安裝,有點類似vue的腳手架,它會自動將環境設定好,開發者無需手動初始化相關組態檔。
npx -p @storybook/cli sb init --type vue
第二種是可以手動進行設定,讀者可以參照官網的教學來進行安裝。附送地址:https://storybook.js.org/docs/guides/guide-vue/。
但是筆者經過嘗試,使用官方的方法安裝的時候會缺少部分依賴導致執行失敗,下面將介紹一下筆者自己使用的安裝方法。
首先,安裝vue腳手架,然後初始化專案:
vue create storybook-demo
選擇babel和css預處理, 並且在第三部選擇安裝node-sass,這幾項是必須的,其他可根據需要進行選擇。
腳手架安裝完成後,刪除無關檔案,並在根目錄下新建.storybook、stories資料夾,在.storybook下新建以下檔案:addons.js、main.js、config.js、webpack.config.js。完成之後目錄如下:
下面再進行storybook的相關安裝。
安裝storybook for vue:
npm install @storybook/vue --save-dev
在根目錄下找到package.json檔案並設定引導:
{
"scripts": {
"storybook": "start-storybook"
}
}
當然,你也可以在後面跟上-p port來設定預設埠號,如:
{
"scripts": {
"storybook": "start-storybook -p 6006"
}
}
在根目錄下新建.storybook資料夾,並在裡面新建main.js檔案,進行相關設定:
module.exports = {
stories: [’…/stories/**/*.stories.js’, ‘…/stories/*.stories.js’]
};
這樣系統就會自動解析src目錄下的*.stories.js、*.stories.ts檔案了。
之後,在根目錄下新建src資料夾,在裡面新建index.stories.js檔案並編寫自己的元件:
import Vue from 'vue';
import MyButton from './Button.js';
export default { title: 'Button' };
export const withText = () => '<my-button>with text</my-button>';
export const withEmoji = () => '<my-button>😀 😎 👍 💯</my-button>';
export const asAComponent = () => ({
components: { MyButton },
template: '<my-button :rounded="true">rounded</my-button>'
});
Button.js(由於這裡沒有安裝vue檔案的解析依賴,所以只能用js檔案來進行代替,如果想引入vue來代替js,可自行安裝相關loader):
export default {
name: 'my-button',
data() {
return {
buttonStyles: {
border: '1px solid #eee',
borderRadius: 3,
backgroundColor: '#FFFFFF',
cursor: 'pointer',
fontSize: 15,
padding: '3px 10px',
margin: 10,
},
};
},
template: `
<button :style="buttonStyles" @click="onClick">
<slot></slot>
</button>
`,
methods: {
onClick() {
console.log('click');
this.$emit('click');
},
},
};
這樣,一個簡單的storybook就搭建完成了。在命令列輸入:
就會自動開啟剛才的storybook。
通過上面的搭建可以看到,我們自己搭建的storybook與一開始的看到的圖片簡直就是買家秀和賣家秀的區別。這是因為在storybook中,它提供了很多外掛供開發者使用,開發者可以使用addons給每個story增加額外的功能,如使用檔案、檢視原始碼、檢視事件等,使每個story的功能更加豐富。
storybook自帶的addons已足夠使用,當然官方也提供了相關api可以讓開發者編寫自己的addon,具體實現可移步到官方檔案中進行檢視。
官方自帶的addons可參考:
https://storybook.js.org/addons/
https://github.com/storybookjs/storybook/tree/master/addons
當然,使用addons之前必須先到https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md檢視相關addon是否支援當前框架,比如說info外掛就只支援react但是不支援vue,之前筆者還在這裡研究了半天為什麼info一直設定失敗。
下面介紹幾個筆者自己用過的addon以及設定方法,其他addon可照貓畫虎,根據官方檔案給的引數進行設定即可。
安裝:
npm i @storybook/addon-storysource --save-dev
設定:
.storybook/main.js
const path = require("path");
module.exports = {
stories: ["../stories/**/*.stories.js", "../stories/*.stories.js"],
addons: [
{
name: "@storybook/addon-storysource",
options: {
rule: {
// test: [/\.stories\.jsx?$/], This is default
include: [path.resolve(__dirname, "../stories")], // 找到自己存放stories的資料夾
},
loaderOptions: {
prettierConfig: { printWidth: 80, singleQuote: false },
},
},
},
],
};
其中,loaderOptions的預設值為:
{
printWidth: 100,
tabWidth: 2,
bracketSpacing: true,
trailingComma: 'es5',
singleQuote: true,
}
在.storybook/addons.js裡面進行外掛註冊:
import '@storybook/addons';
import '@storybook/addon-storysource'
到這裡就可以了,重新執行一下看一下結果:
安裝:
npm install --save-dev storybook-readme
註冊:
.storybook/addons.js
import 'storybook-readme/register';
設定:
這裡可分為全域性設定和區域性設定,全域性設定可以在.storybook/config.js裡面進行相關設定,區域性設定可在制定的*.stories.js檔案裡進行設定。區別如下:
全域性設定需呼叫以下方法:
import { addDecorator } from '@storybook/vue';
import { addReadme, configureReadme } from 'storybook-readme';
configureReadme({
// ...some code
});
addDecorator(addReadme);
區域性設定:
import { storiesOf } from "@storybook/vue";
import MyButton from "./MyButton.vue";
import ButtonReadme from "./MyButton.md";
storiesOf("Demo", module)
.addParameters({
readme: {
codeTheme: "duotone-sea",
content: ButtonReadme,
sidebar: ButtonReadme,
}
})
.add("Button", () => {
return {
components: {
MyButton,
},
template: `<my-button type="primary">My Button</my-button>`,
};
});
由於這個addon是沒有官方檔案的,筆者花了好長時間才找到一個開原始檔,可移步到https://github.com/tuchk4/storybook-readme進行參考,裡面也有相關demo可以檢視。
稍微解釋一下里面各方法引數的作用:
configureReadme({
/**
* Wrapper for story. Usually used to set some styles
* React: React.ReactNode
* Vue: Vue component
*/
// 元件區域的預處理,相當於在元件展示的時候外面套上一層div,元件作為插槽插入到這個div裡面,在這裡可以設定div的樣式,如果是使用vue的話可以以vue元件格式插入,下面同理
StoryPreview
/**
* Wrapper for content and sidebar docs. Usually used to set some styles
* React: React.ReactNode
* Vue: Vue component
*/
// 檔案部分的樣式,即外掛裡面的content
DocPreview/**
* Wrapper for header docs. Usually used to set some styles
* React: React.ReactNode
* Vue: Vue component
*/
HeaderPreview/**
* Wrapper for footer docs. Usually used to set some styles
* React: React.ReactNode
* Vue: Vue component
*/
FooterPreview
/**
* Header docs in markdown format
*/
header: '',
/**
* Footer docs in markdown format
*/
footer: '',
});
不理解preview的可以看一下上圖,比如header的內容就為「使用者互動元件demo」,headerPreview就是下面那層border,如果有將readme註冊到addons.js裡面,在綠色方框裡還會有一個readme選項,可以檢視檔案。
在給特定story新增readme的時候,可以看到可以新增兩個檔案,如:
storiesOf("Demo", module)
.addParameters({
readme: {
codeTheme: "duotone-sea",
content: ButtonReadme,
sidebar: ButtonReadme,
}
})
.add("Button", () => {
return {
components: {
MyButton,
},
template: `<my-button type="primary">My Button</my-button>`,
};
});
其中,這裡可能會有讀者不理解。裡面是content是對應圖中紅色方框的內容,sidebar則是對應綠色方框裡的內容(如果有註冊),codeTheme是md檔案的樣式,可自行設定。
這裡還有一個小技巧,就是在編寫content的時候,可以在檔案中插入以下程式碼:
這段程式碼可以控制我們的元件要在檔案的哪個部分出現。如果不填寫,則預設會先顯示檔案內容,再顯示元件內容。所以我們最好在檔案的最前面先新增上述程式碼,先將我們的元件展示出來,再進行檔案編寫。
這就是筆者目前用過的兩個addon了,其他addons讀者可以自己嘗試,可以讓自己的storybook更加個性化,功能更加完善。