返回
npm install @storybook/vue --save-dev
Make sure that you have vue, vue-loader, vue-template-compiler, @babel/core, babel-loader and babel-preset-vue in your dependencies as well, because we list these as a peer dependencies:
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": "start-storybook -p 9001 -c .storybook"
"build-storybook": "build-storybook -c .storybook -o .storybook.out"
import {
configure,
addParameters,
addDecorator
} from '@storybook/vue';
import {
INITIAL_VIEWPORTS
} from '@storybook/addon-viewport';
// import '@storybook/addon-console';
import {
setConsoleOptions
} from '@storybook/addon-console';
// addDecorator((storyFn, context) => withConsole()(storyFn)(context));
setConsoleOptions({
options: {
hierarchyRootSeparator: /\|/, //标题分类
},
panelExclude: [],
});
const newViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
styles: {
width: '600px',
height: '963px',
},
},
kindleFireHD: {
name: 'Kindle Fire HD',
styles: {
width: '533px',
height: '801px',
},
},
};
addParameters({
//配置背景色选项
backgrounds: [{
name: 'white',
value: 'white',
default: true
},
{
name: 'facebook',
value: '#3b5998'
},
{
name: 'yellow',
value: 'yellow'
},
],
//自定义视图大小
viewport: {
viewports: {
...INITIAL_VIEWPORTS,
...newViewports
},
}
});
function importAll(r) {
r.keys().forEach(r)
}
//待处理的 storybook文件
function loadStories() {
importAll(require.context("../stories", true, /\.story\.js$/));
importAll(require.context("../src/components", true, /\.story\.js$/));
}
configure(loadStories, module);
import '@storybook/addon-notes/register'; //添加备注
import '@storybook/addon-storysource/register';//显示源码
import '@storybook/addon-knobs/register';//显示props字段并可以更改
import '@storybook/addon-backgrounds/register';//设置背景色
import '@storybook/addon-viewport/register';//设置自定义屏幕
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import {
storiesOf
} from '@storybook/vue';
import {
linkTo
} from '@storybook/addon-links';
import MyButton from './Button.vue';
import {
withKnobs,
text,
number,
boolean,
array,
select,
color,
date,
button
} from '@storybook/addon-knobs';
import Vue from 'vue';
Vue.component('MyButton', MyButton);
storiesOf('Addon|Notes', module)
.add('Default', () => ({
template: '<MyButton>addon notes</MyButton>'
}), {
notes: 'You can write anything about this component'
})
storiesOf('Addon|Links', module)
.add('Go to Compents|Button', () => ({
template: `<MyButton :rounded="true" @click-btn="click">addon Links</MyButton>`,
methods: {
click(val){
console.log('click---'+val)
linkTo('Compents|Button','custom button')
}
},
}))
storiesOf('Addon|Backgrounds', module)
.add('Default', () => ({
template: '<MyButton>addon backgrounds</MyButton>'
}), {
notes: 'with emoji-----backgrounds',
backgrounds: [{
name: 'grey',
value: '#eeeeee',
default: true
}]
})
storiesOf('Addon|Viewport', module)
.add('Default', () => ({
template: '<MyButton :rounded="true">addon viewport</MyButton>'
}), {
viewport: {
defaultViewport: 'iphonex'
}
})
storiesOf('Addon|Knobs', module)
.addDecorator(withKnobs)
.add('All knobs', () => {
const fruits = {
Apple: 'apples',
Banana: 'bananas',
Cherry: 'cherries',
};
button('Arbitrary action', 'You clicked it!');
return {
props: {
name: {
default: text('Name', 'Jane')
},
stock: {
default: number('Stock', 20, {
range: true,
min: 0,
max: 30,
step: 5,
}),
},
fruit: {
default: select('Fruit', fruits, 'apples')
},
price: {
default: number('Price', 2.25)
},
colour: {
default: color('Border', 'deeppink')
},
today: {
default: date('Today', new Date('Jan 20 2017 GMT+0'))
},
// this is necessary, because we cant use arrays/objects directly in vue prop default values
// a factory function is required, but we need to make sure the knob is only called once
items: {
default: (items => () => items)(array('Items', ['Laptop', 'Book', 'Whiskey']))
},
nice: {
default: boolean('Nice', true)
},
},
data: () => ({
dateOptions: {
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC'
},
}),
computed: {
stockMessage() {
return this.stock ?
`I have a stock of ${this.stock} ${this.fruit}, costing $${this.price} each.` :
`I'm out of ${this.fruit}${this.nice ? ', Sorry!' : '.'}`;
},
salutation() {
return this.nice ? 'Nice to meet you!' : 'Leave me alone!';
},
formattedDate() {
return new Date(this.today).toLocaleDateString('en-US', this.dateOptions);
},
style() {
return {
'border-color': this.colour,
};
},
},
template: `
<div style="border: 2px dotted; padding: 8px 22px; border-radius: 8px" :style="style">
<h1>My name is {{ name }},</h1>
<h3>today is {{ formattedDate }}</h3>
<p>{{ stockMessage }}</p>
<p>Also, I have:</p>
<ul>
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
<p>{{ salutation }}</p>
</div>
`,
};
});
Create a .storybook/webpack.config.js file. 查看默认的webpack配置
Edit it’s contents:
module.exports = async ({ config }) => console.dir(config.plugins, { depth: null }) || config;
Then run storybook:即可查看默认的webpack配置
yarn storybook --debug-webpack
增加less
const path = require('path');
// Export a function. Accept the base config as the only param.
module.exports = async ({
config,
mode
}) => {
// `mode` 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: /\.less$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
include: path.resolve(__dirname, '../'),
});
//配置查看代码源码
config.module.rules.push({
test: /\.story\.jsx?$/,
loaders: [require.resolve('@storybook/addon-storysource/loader')],
include: [path.resolve(__dirname, '../src'), path.resolve(__dirname, '../stories')],
enforce: 'pre',
});
// Return the altered config
return config;
};
mkdir storybook-vue
cd storybook-vue/
npm init -y
npx -p @storybook/cli sb init --type vue
npm run storybook
需要安装部分缺失插件
npm i -D vue-loader @storybook/addon-storysource
npm i vue