在這個單元我們使用官網的教學搭配Vue的框架,STEP BY STEP的撰寫Component及Stories。
官網教學參考:Vue
# Create our application, using a preset that contains jest:
$ vue create vue-taskbox --preset chromaui/vue-preset-learnstorybook
$ cd vue-taskbox
# Add Storybook:
$ npx sb init
依照需要,在開發時期你可以會執行三種模式
# 執行 Unit Test
$ npm run test:unit
# 執行 Storybook
$ npm run storybook
# 執行專案網頁
$ npm run serve
因為這個單元是專注於開發 Single Component,所以目前我們只要執行 Storybook。
範例提供的CSS:請按此
把這個CSS檔案下載到專案,路徑為 assets/index.css
把CSS檔案加入App.Vue中
<style>
@import "./assets/index.css";
</style>
$ npx degit chromaui/learnstorybook-code/public/font src/assets/font
$ npx degit chromaui/learnstorybook-code/public/icon src/assets/icon
官網教學參考:Vue
在這個範例中,關鍵的元件是Task,每種狀態的Task都有其代表的意思,用Checkbox來表示是否完成任務,用Pin Button(圖上星星符號)來做重要任務置頂,以及中間要顯示Task的文字。經過分析後,Task元件需要二個props
<template>
<div class="list-item">
<input type="text" :readonly="true" :value="this.task.title" />
</div>
</template>
<script>
export default {
name: "task",
props: {
task: {
type: Object,
required: true,
default: () => ({})
}
}
};
</script>
// src/components/Task.stories.js
import { action } from "@storybook/addon-actions";
import Task from "./Task";
export default {
title: "Task",
// Our exports that end in "Data" are not stories.
excludeStories: /.*Data$/
};
export const actionsData = {
onPinTask: action("onPinTask"),
onArchiveTask: action("onArchiveTask")
};
export const taskData = {
id: "1",
title: "Test Task",
state: "Task_INBOX",
updated_at: new Date(2019, 0, 1, 9, 0)
};
const taskTemplate = `<task :task="task" @archiveTask="onArchiveTask" @pinTask="onPinTask"/>`;
// default task state
export const Default = () => ({
components: { Task },
template: taskTemplate,
props: {
task: {
default: () => taskData
}
},
methods: actionsData
});
// pinned task state
export const Pinned = () => ({
components: { Task },
template: taskTemplate,
props: {
task: {
default: () => ({
...taskData,
state: "TASK_PINNED"
})
}
},
methods: actionsData
});
// archived task state
export const Archived = () => ({
components: { Task },
template: taskTemplate,
props: {
task: {
default: () => ({
...taskData,
state: "TASK_ARCHIVED"
})
}
},
methods: actionsData
});
目前Storybook運行畫面
接下來要做一些調整,讓Storybook只顯示components
目錄下的stories
還有讓Storybook也可以套用到全域的CSS
// .storybook/main.js
module.exports = {
stories: ['../src/components/**/*.stories.js'],
addons: ['@storybook/addon-actions', '@storybook/addon-links'],
};
// .storybook/preview.js
import '../src/assets/index.css';
因為是修改.storybook
config設定檔案,調整完成後記得要重啟Storybook
目前運行畫面
發現只會顯示components
底下的Stories,也套用到全域的CSS了
<!--src/components/Task.vue-->
<template>
<div :class="taskClass">
<label class="checkbox">
<input
type="checkbox"
:checked="isChecked"
:disabled="true"
name="checked"
/>
<span class="checkbox-custom" @click="$emit('archive-task', task.id)" />
</label>
<div class="title">
<input
type="text"
:readonly="true"
:value="this.task.title"
placeholder="Input title"
/>
</div>
<div class="actions">
<a @click="$emit('pin-task', task.id)" v-if="!isChecked">
<span class="icon-star" />
</a>
</div>
</div>
</template>
<script>
export default {
name: "task",
props: {
task: {
type: Object,
required: true,
default: () => ({
id: "",
state: "",
title: ""
})
}
},
computed: {
taskClass() {
return `list-item ${this.task.state}`;
},
isChecked() {
return this.task.state === "TASK_ARCHIVED";
}
}
};
</script>
現在我們可以在Storybook上看到元件的所有的對應狀態啦!
目前運行畫面
整個元件建置的過程,並沒有啟動專案本身的運行環境,僅僅只有啟動Storybook!
這也就表示在元件建置階段的時候我們只要關心元件的開發就可以了!
tag: simple-component https://git.io/JURMH
接下來的單元會將Task元件組合成更大的元件TaskList,也是只要啟動Storybook就可以完成。
Angular 會在 Composite component 完成後的下個單元。
Storybook Intro - Get started:Vue
Storybook Intro - Simple Component:Vue