Hello,
I'm working on a GraphQL client called greed that I haven't open sourced yet. Its framework/library agnostic and wanted to create some vue bindings for it. I want to base the bindings off the same signature that I got working with react which is:
container(
greed,
defaults,
queries,
mutations
)(component);
// Using a decorator
@container(
greed,
defaults,
queries,
mutations
)
someComponent
greed: greedInstance- is the greed instance you want to use
defaults: ?function - are the default data for the component to render
queries: ?function - are the queries you can run when some user input occurs
mutations: ?function - are the mutations you can run when some user input occurs
component: Component - the component to enhance
The container essentially enhances whatever component it receives with data needed to render and methods that can be executed to run queries and mutations when some user input occurs in the application.
However given that there are different types of templates vs components in vue i'm not sure how to go about injecting/enhancing vue components/templates. I'm not very familiar with vue which is why I wanted some feedback and direction on how best to accomplish this with vue. Any help and guidance would be really appreciated.
You don't need to worry about templates at all. The template is basically just the render function.
In Vue, a component is in most cases defined as a plain options object:
export default {
data () { ... },
created () { ... },
computed: { ... },
methods: { ... }
}
You basically modify/patch this options object in your enhancer function.
Alternatively, Vue plugins can apply a global mixin that injects lifecycle hooks into all components. In the lifecycle hooks you check for a custom options field (e.g. graphql or greed):
const greedPlugin = Vue => {
Vue.mixin({
beforeCreate () {
if (this.$options.greed) {
// ... initialize stuff
}
}
})
}
Vue.use(greedPlugin)
new Vue({
greed: {
queries,
mutations
}
})
You can consult vue-rx which is implemented this way.
Closing since this is a question, but you can continue the discussion in this thread.
Thank you so much @yyx990803 ! Will get started on this tomorrow morning :)
@yyx990803 I've seen in a few of your examples on the vue site, and other articles that data fetch that for the most part you know ahead of time what property in the state the fetch function is going to update. However how would you spread the newly acquired data into the data object?
in react this is how I accomplished this:
this.setState(() => ({...state}))
In view you can set a single property by doing:
self.commits = JSON.parse(xhr.responseText)
I've tried to do the following, in created()even though I knew it wouldn't work but just to get the idea across:
this.data = {...this.data, ...data};
I know I could set a property on the data object called data and then place all the data within the nested data object and let the user do this.data.commits. I don't want to resist from nesting 😅
when I say I want to spread over the data object I mean this one:
data: function () {
return {// <---- this data object I want to spread over and update in created()
branches: ['master', 'dev'],
currentBranch: 'master',
commits: null
}
}
I just got it working. @yyx990803 can you add me on twitter so I can send you a dm with a link to the code so maybe you can review it and give me some tips on things I may not have done the _Vue Way_
my twitter handle is @kennetpostigo
How about making a public repo and link it here? I am sure the community will give you lots of feedback.
Also, from my understanding, if you want to hook into Vue with GraphQL, the better choice is to hook into Vuex, since it is the prebuilt state management system for Vue. Did you do that by chance?
Also, I hope you are aware that this problem has been solved, albeit not with Vuex, but with the Redux system that Apollo provides. Just wanted to point that out, not that possible you are reinventing a wheel already made. 😄
Scott
Hi @smolinari !
How about making a public repo and link it here? I am sure the community will give you lots of feedback.
I have a monorepo i'm going to make public as soon as I finish all the bindings to the frameworks/libs.
Also, from my understanding, if you want to hook into Vue with GraphQL, the better choice is to hook into Vuex, since it is the prebuilt state management system for Vue. Did you do that by chance?
I don't want to depend on a specific state management libraries because often times teams and individuals choose different options for different reasons that makes sense for their use case. I did however provide a way to let state management libraries hook into the client and handle data through actions.
Also, I hope you are aware that this problem has been solved, albeit not with Vuex, but with the Redux system that Apollo provides. Just wanted to point that out, not that possible you are reinventing a wheel already made. 😄
I'm aware that apollo is available however the client i'm working on is focused on minimizing size similar to projects like preact (currently the core and vue bindings stand at 2kb), as well as developer experience by keeping it simple and unopinionated so that it can work well with all your tools and not step on any of their toes.
Well, your project sounds interesting. Looking forward to seeing it.
Scott
Most helpful comment
You don't need to worry about templates at all. The template is basically just the render function.
In Vue, a component is in most cases defined as a plain
optionsobject:You basically modify/patch this options object in your enhancer function.
Alternatively, Vue plugins can apply a global mixin that injects lifecycle hooks into all components. In the lifecycle hooks you check for a custom options field (e.g.
graphqlorgreed):You can consult vue-rx which is implemented this way.
Closing since this is a question, but you can continue the discussion in this thread.