gpt4 book ai didi

vue.js - 如何让 Vuex 商店与 Storybook 一起使用?

转载 作者:行者123 更新时间:2023-12-03 06:36:13 26 4
gpt4 key购买 nike

我有一个组件故事,需要由我的 Vuex 商店中的 ACTION 执行 API 调用。但是,Storybook 找不到该商店:Unhandled promise rejection TypeError: "this.$store is undefined" .

我尝试通过 created 访问商店和 mounted Vue 生命周期钩子(Hook),但每个都返回 undefined .

我的 Vuex 商店在我的应用程序中正常工作。

我在故事书上奔跑 5.0.1和 vuex 3.1.1 .

这是我的故事书config.js :

// Taken from https://davidwalsh.name/storybook-nuxt & https://github.com/derekshull/nuxt-starter-kit-v2/blob/master/.storybook/config.js
import { addParameters, configure } from '@storybook/vue';
import { withOptions } from '@storybook/addon-options';
import { setConsoleOptions } from '@storybook/addon-console';
import { create } from '@storybook/theming';
import Vue from 'vue';
import VueI18n from 'vue-i18n';

// Vue plugins
Vue.use(VueI18n);

setConsoleOptions({
panelExclude: [],
});

// Option defaults:
addParameters({
options: {
/**
* show story component as full screen
* @type {Boolean}
*/
isFullScreen: false,
/**
* display panel that shows a list of stories
* @type {Boolean}
*/
showNav: true,
/**
* display panel that shows addon configurations
* @type {Boolean}
*/
showPanel: true,
/**
* where to show the addon panel
* @type {String}
*/
panelPosition: 'bottom',
/**
* sorts stories
* @type {Boolean}
*/
sortStoriesByKind: false,
/**
* regex for finding the hierarchy separator
* @example:
* null - turn off hierarchy
* /\// - split by `/`
* /\./ - split by `.`
* /\/|\./ - split by `/` or `.`
* @type {Regex}
*/
hierarchySeparator: /\/|\./,
/**
* regex for finding the hierarchy root separator
* @example:
* null - turn off multiple hierarchy roots
* /\|/ - split by `|`
* @type {Regex}
*/
hierarchyRootSeparator: /\|/,
/**
* sidebar tree animations
* @type {Boolean}
*/
sidebarAnimations: true,
/**
* enable/disable shortcuts
* @type {Boolean}
*/
enableShortcuts: true,
/**
* theme storybook, see link below
*/
theme: create({
base: 'light',
brandTitle: '',
brandUrl: '',
// To control appearance:
// brandImage: 'http://url.of/some.svg',
}),
},
});

const req = require.context('../src/components', true, /\.story\.js$/)

function loadStories() {
req.keys().forEach((filename) => req(filename))
}

configure(loadStories, module);

这是我的组件的故事:

import { storiesOf } from '@storybook/vue';
import { withReadme } from 'storybook-readme';
import { withKnobs } from '@storybook/addon-knobs';
import HandoffMainView from './HandoffMainView.vue';
import readme from './README.md';

storiesOf('HandoffMainView', module)
.addDecorator(withReadme([readme]))
.addDecorator(withKnobs)
.add('Default', () => {
/* eslint-disable */
return {
components: { HandoffMainView },
data() {
return {
isLoading: true,
component: {
src: '',
data: [],
},
};
},
template: '<handoff-main-view :component="component" />',
};
});

这是我的组件:

<template>
<main class="o-handoff-main-view">
<div class="o-handoff-main-view__content">
<div
:class="[
'o-handoff-main-view__background',
background ? `o-handoff-main-view__background--${background}` : false
]"
>
<loader
v-if="isLoading"
:color='`black`'
class="o-handoff-main-view__loader"
/>
<div
v-else
class="o-handoff-main-view__ui-component"
:style="getUiComponentStyle"
>
<img
:src="uiComponent.src"
alt=""
>
<handoff-main-view-layer-list
:layers="uiComponent.data"
/>
</div>
</div>
</div>
<div class="o-handoff-main-view__controls">
<handoff-main-view-zoom-handler
:default-zoom-level="zoomLevel"
:on-change="updateZoomLevel"
/>
</div>
</main>
</template>

<script>
import { mapActions } from 'vuex';
import Loader from '../../01-atoms/Loader/Loader.vue';
import HandoffMainViewZoomHandler from '../HandoffMainViewZoomHandler/HandoffMainViewZoomHandler.vue';
import HandoffMainViewLayerList from '../HandoffMainViewLayerList/HandoffMainViewLayerList.vue';

export default {
components: {
Loader,
HandoffMainViewZoomHandler,
HandoffMainViewLayerList,
},
props: {
background: {
type: String,
default: 'damier',
},
component: {
type: Object,
required: true,
},
},
data() {
return {
isLoading: true,
zoomLevel: 1,
uiComponent: {
src: null,
}
};
},
mounted() {
this.setUiComponentImage();
},
methods: {
...mapActions('UiComponent', [
'ACTION_LOAD_SIGNED_URLS'
]),
async setUiComponentImage() {
const uiComponentImg = new Image();
const signedUrls = await this.ACTION_LOAD_SIGNED_URLS([this.component.id]);
uiComponentImg.onload = () => {
this.isLoading = false;
};
uiComponentImg.src = this.uiComponent.src;
},
},
};
</script>

最佳答案

我打赌在你的应用程序的某个地方,可能是 main.js ,你正在做类似的事情:

import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
state,
mutations,
getters,
});
然后,在创建 Vue 应用程序时,您调用 new Vue({store, i18n...}) .
你已经在你的 config.js 中使用“i18n”模块来锻造 Vue。 .您还需要在那里导入 Vuex 和商店。

现在,必须在 Storybook 设置中导入您的商店 - 或模拟它 - 可能是您的组件太大或与您的商店过于耦合的味道。
通常,故事书更倾向于显示显示具有专用功能的内容(表单控件、事物列表...)的组件。此类组件通常通过 Prop 和事件与应用程序的其余部分进行通信。让我们称之为表现组件。
相反,与 store 通信的组件通常是 View 或页面,它们协调状态并与后端对话,并为前者提供数据。
我认为您应该在故事书展示上仅显示演示组件,并避免谈论其中的全局模块。至少,我相信这是故事书背后的精神,也是故事书的主要用途。这可能是原因,因为您没有找到太多关于如何在故事书中模拟您的商店的文档:我认为,故事书项目通常不会首先连接到 vuex。

关于vue.js - 如何让 Vuex 商店与 Storybook 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56682493/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com