-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using window.store when creating a story #6726
Comments
Automention: Hey @elevatebart @pksunkara, you've been tagged! Can you give a hand here? |
So I have been continuing work on this, and I am not sure it is a context issue so much as a timing issue. It looks like Could this be correct? |
@CrashyBang could you test that theory with a |
Hey @shilman, Okay that is sort of working (
This is coming from storiesOf("Event List", module).add(
"with valid data",
() => ({
components: {
EventList
},
store: window.store,
data: () => {
return { initalEnabled: true };
},
template: `<event-list :initial-enabled="initalEnabled" />`
})
); NOTE: In the storybook interface NOTE: I will also need to fix the issue regarding the |
Hey @shilman, I keep coming back to this when I have time so sorry for the sporadic posting, I tried to extend on the setTimeout(() => {
storiesOf("Event List", module).add("with valid data", () => {
return {
components: {
EventList
},
store: window.store,
data: () => {
return {
initalEnabled: true
};
},
template: `<event-list :initial-enabled="initalEnabled" />`
}
});
}, 0); But this just gave me the following: In an ideal world I would actually like to do something like this: (async (ready) => {
await ready;
storiesOf("Event List", module).add("with valid data", async () => {
return {
components: {
EventList
},
store: window.store,
data: () => {
return {
initalEnabled: true
};
},
template: `<event-list :initial-enabled="initalEnabled" />`
}
});
})(window.somePromise); Where I also tried messing around with adding a import Vue from 'vue';
Vue.mixin({
data() {
return {
ready: false
}
},
async created() {
await window.components.resourcesLoaded;
this.ready = true;
}
}); And then adding Cheers. |
Still working on this, just having trouble finding the time. |
Okay so I had a bit more of a play with this today. Basically I tried modifying So the new code looked like this:
I also added The issue was when I tried to re-build my storybook the new Let me know what you think, at this point I am just trying to isolate the problem a fix can be made from there and hopefully in such a way that it can go up stream. Cheers. |
Okay making more progress here, I need to be modifying
Into the This meant that I could (async ready => {
await ready;
storiesOf("Event List", module).add(
"with valid data",
() => {
return {
components: {
EventList
},
data: () => {
return {
initalEnabled: true
};
},
template: `<event-list :initial-enabled="initalEnabled" />`
};
}
);
})(window.components.resourcesLoaded); Now this worked, but it could not read import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex); To the storybook |
Okay working further still I now have the following issue rendering components, if I try to render like this: storiesOf("Event List", module).add(
"with valid data",
() => ({
components: {
EventList
},
store: window.store,
data: () => {
return {
initalEnabled: true
};
},
template: `<event-list :initial-enabled="initalEnabled" />`
})
); Nothing works given that nothing has loaded, however if I try to render like this: (async function initStories(ready) {
await ready;
const response = storiesOf("Event List", module).add(
"with valid data",
() => ({
components: {
EventList
},
store: window.store,
data: () => {
return {
initalEnabled: true
};
},
template: `<event-list :initial-enabled="initalEnabled" />`
})
);
console.log(response);
})(window.components.resourcesLoaded); Nothing renders either but the |
After a bit more research I believe I need something like the proposed API in #713 but from what I can tell this was never implemented. I also see there is some conversation happening in #6885 potentially we will see something happen here. UPDATE: Original PR to add this functionality was #1253 but it was never merged. |
how does your component access the store in an app (not storybook)? also via |
you could try the following decorator: function waitForStore() {
return () => ({
data() {
return { store: null };
},
async created() {
this.store = await GET_WINDOW_STORE();
},
render(h) {
if(!this.store) {
return h('span', 'Waiting for store...');
}
return h('story', { store: this.store }); // this may not work, then try the following
return h({ components: { story: this.$options.components.story }, template: '<story></story>', store: this.store });
}
})
}
storiesOf(...).addDecorator(waitForStore()).add(...); |
Hey @backbone87, Components access the store via I will try the suggested decorator as soon as possible! Thanks! |
Hey @backbone87, That works! Thank you so much for that! The only issue I have now is setting up the store on the components I am using in the stories, when loading them on the front end I have a function that sets them up with the store (I know the whole way we are doing this is weird but it fits the use case) like so: initializeComponent = function (config) {
return new Promise(async function (resolve, reject) {
// @NOTE we have to wait for this to resolve before loading any components
// - This is because some components (bootstrap-vue) require the global "Vue"
await components.resourcesLoaded;
const component = await loadComponent(config.url);
const props = config.props || {};
new Vue({
store: window.store,
i18n: window.components.i18n,
render: function (h) {
// @NOTE props will not be reactive
// - https://forum.vuejs.org/t/passing-props-as-object-during-render-should-they-be-reactive/62271
return h(component, {
props: props
});
}
}).$mount(config.element);
return resolve();
});
}; So that is how all the components we load in get their reference to import EventList from "@/components/EventList.vue";
storiesOf("Event List", module)
.addDecorator(waitForStore())
.add("with valid data", () => {
return {
components: {
EventList
},
data: () => {
return {
initalEnabled: true
};
},
template: `<event-list :initial-enabled="initalEnabled" />`
};
}); The |
so you can access the store in the story via |
Hey @backbone87, So this is an issue with my setup, basically I load each component on demand and create the Vue instance as I need it, hence the As you can see as I load each component I pass it a reference to the store at the time: new Vue({
store: window.store,
i18n: window.components.i18n,
render: function (h) {
// @NOTE props will not be reactive
// - https://forum.vuejs.org/t/passing-props-as-object-during-render-should-they-be-reactive/62271
return h(component, {
props: props
});
}
}).$mount(config.element); Basically there is no "global" Vue instance in my project so each component gets handed the store reference as it is instantiated, unfortunately I am not sure how to do this via storybook, I essentially need to pass the EDIT: And no |
From what I can tell, I would need to add the store here but from what I can see there are no hooks that would enable me to do this, I also doubt this is somewhere that the developers would like to add hooks as it would be pretty easy for users to mess things up. |
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks! |
Still working on this one, what I am encountering now though potentially warrants a new issue, so I will close this for now and revisit when I have more time. |
Is there another issue to keep track of this? Since this has been closed already? |
Hey @anipendakur, No there is currently no new issue as I have not had time to revisit this, feel free to open a new issue and reference this one. Cheers! |
Describe the bug
When creating a story I am trying to use the
window.store
as the store (I include a script inpreview-head.html
which sets upwindow.store
so it does exist in theiframe
).Basically I am working on a site that uses decoupled
vue
components built as libraries which communicate data through a globalvuex
store on thewindow
, unfortunately this preventsmapActions
working with storybook because the context ofthis.$store
is wrong.I have tried the following based of this issue and also this post:
Unfortunately the context of
window
is wrong at this point, I also tried setting up the store in the config file withVue.use(Vuex)
but because I register the modules dynamically I couldn't get this to work either as I register them againstwindow.store
when the module is loaded with the following script:To Reproduce
Steps to reproduce the behavior:
store: window.store
when creating a story.Expected behavior
To be able to reference objects on the
iframe
window.System:
Additional context
I am building the decoupled components as outlined here.
The text was updated successfully, but these errors were encountered: