HuckRidgeSW / hvue

A GopherJS & go/wasm binding for Vue.js
MIT License
49 stars 10 forks source link

Added 'Store' component option, to be able to inject Vuex to Vue #6

Closed mame82 closed 4 years ago

mame82 commented 6 years ago

As described here https://vuex.vuejs.org/guide/state.html, Vuex provides a mechanism to "inject" the store (a global single source of truth, closely interacting with Vue) into all child components from the root component.

This involves setting an additional option on Vue creation like this:

const app = new Vue({
  el: '#app',
  // provide the store using the "store" option.
  // this will inject the store instance to all child components.
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

In order to achieve this, I'd added an additional ComponentOption hvue.Store (used on NewVM not on NewComponent.

Best regards, thanks for your great project. As stated on Twitter, it is much more capable than hopherjs-vue.

HuckRidgeSW commented 6 years ago

In "the best of all possible worlds", we'd write a full wrapper for Vuex the same way hvue is a wrapper for Vue.js, but this seems like a good interim measure until that world / library shows up. Thanks!

mame82 commented 6 years ago

In "the best of all possible worlds", we'd write a full wrapper for Vuex the same way hvue is a wrapper for Vue.js, but this seems like a good interim measure until that world / library shows up. Thanks!

I was doing exactly that, closely following your concepts of interfacing between gopherjs and JS. What I have currently working:

Why I don't invest more time to implement the missing functionality:

The main reason I'm not gonna finish the Vuex bindings, is my real use case: I need to hold complex (deeply nested) state data in a "single source of truth", while having it accessible to Vue components, at the same time. I ended up with Vuex, because it is the first thing you find for this use case. Now that my code is written in Go, not in pure JS generates several problems with Vuex: 1) Vuex doesn't like deep nested data, as you basically have to provide a mutation for everything you wan't to change from JavaScript world in order to track changes with Vue devtools. Changing the data directly from Go and exposing it to JavaScript as single source of truth (Global variable) works far better. Vue updates everything perfectly when the data changes (using your hvue bindings). 2) Using Vuex means everything state related must exist in the JavaScript world. This again means, if you need to access this state data in pure go again (which is most likely in my case), it has to support externalize/internalize. This is hard for me to achieve. A good example are structs containing fields of type []interface{}. In case you try to handle this in a pure JS based state, like Vuex requires, the problem gets obvious: This data gets lost during internalization to JS, even if the []interface{} is part of a struct with a *js.Object field and "js-tagged".

So there're several problems.

Anyway, I uploaded my code to github, maybe you like to work with it. I don't spent further time on this, for the mentioned reasons. Unfortunately I couldn't include a example of how to use the code currently, as everything is part of a private project, right now.

I'd like to point you to one thing here: https://github.com/mame82/mvuex/blob/master/helper.go#L33

I'm using this function to cast JavaScript objects to Gopherjs structs, with well defined types. It is very close to your hvue implementation, but differs in one thing: It follows pointers into nested structs ... maybe you have a use for it. Thx for your project, once more

HuckRidgeSW commented 4 years ago

Closing. Have had no time to work on this PR or hvue itself in far too long. Seems fairer to close it. Thank you for your interest.