javascript - Pass prop as module name when mapping to namespaced module - Stack Overflow

I'm trying to pass the store module namespace via props to a ponent. When I try and map to getters

I'm trying to pass the store module namespace via props to a ponent. When I try and map to getters with the prop, it throws this error,

Uncaught TypeError: Cannot convert undefined or null to object

If I pass the name as a string it works.

This Works

<script>
export default {

  props: ['store'],

  puted: {
    ...mapGetters('someString', [
      'filters'
    ])
  }
}
</script>

This does not work

this.store is defined
this.store typeof is a String

<script>
  export default {

    props: ['store'],

    puted: {
      ...mapGetters(this.store, [
        'filters'
      ])
    }
  }
</script>

I'm trying to pass the store module namespace via props to a ponent. When I try and map to getters with the prop, it throws this error,

Uncaught TypeError: Cannot convert undefined or null to object

If I pass the name as a string it works.

This Works

<script>
export default {

  props: ['store'],

  puted: {
    ...mapGetters('someString', [
      'filters'
    ])
  }
}
</script>

This does not work

this.store is defined
this.store typeof is a String

<script>
  export default {

    props: ['store'],

    puted: {
      ...mapGetters(this.store, [
        'filters'
      ])
    }
  }
</script>
Share Improve this question asked Mar 3, 2017 at 17:27 MrGoodMrGood 5455 silver badges21 bronze badges 3
  • Did you ever find a solution to this? – delucasvb Commented Nov 29, 2018 at 14:34
  • Here I am June 2020 looking at my old question to see if It was answered. Still no solution. – MrGood Commented Jun 18, 2020 at 22:02
  • Looking for a solution to this as well. Created another topic as well to hopefully get some traction stackoverflow./questions/64287347/… – Josh Commented Oct 13, 2020 at 14:59
Add a ment  | 

4 Answers 4

Reset to default 1

I used this style utilising beforeCreate to access the variables you want, I used the props passed into the ponent instance:

import { createNamespacedHelpers } from "vuex";
import module from '@/store/modules/mymod';

export default {
  name: "someComponent",
  props: ['namespace'],
  beforeCreate() { 
    let namespace = this.$options.propsData.namespace;
    const { mapActions, mapState } = createNamespacedHelpers(namespace);

    // register your module first
    this.$store.registerModule(namespace, module);

    // now that createNamespacedHelpers can use props we can now use neater mapping
    this.$options.puted = {
      ...mapState({
        name: state => state.name,
        description: state => state.description
      }),

      // because we use spread operator above we can still add ponent specifics
      aFunctionComputed(){ return this.name + "functions";},
      anArrowComputed: () => `${this.name}arrows`,
    };

    // set up your method bindings via the $options variable
    this.$options.methods = {
      ...mapActions(["initialiseModuleData"])
    };
  },

  created() {
    // call your actions passing your payloads in the first param if you need
    this.initialiseModuleData({ id: 123, name: "Tom" });
  }
}

I personally use a helper function in the module I'm importing to get a namespace, so if I hadmy module storing projects and passed a projectId of 123 to my ponent/page using router and/or props it would look like this:

import { createNamespacedHelpers } from "vuex";
import projectModule from '@/store/project.module';

export default{
  props['projectId'], // eg. 123
  ...
  beforeCreate() {

    // dynamic namespace built using whatever module you want:
   let namespace = projectModule.buildNamespace(this.$options.propsData.projectId); // 'project:123'

   // ... everything else as above with no need to drop namespaces everywhere
   this.$options.puted = {
      ...mapState({
        name: state => state.name,
        description: state => state.description
      })
   }
  }
}

Hope you find this useful.

I tackled this problem for hours, too. Then I finally came up with one idea.

  • Add attachStore function in a child vue ponent. A function nama is not important. Any name is ok except vue reserved word.

    export default {
      :
      attachStore (namespace) {
        Object.assign(this.puted, mapGetters(namespace, ['filters']))
      }
    }
    
  • When this vue ponent is imported, call attachStore with namespace parameter. Then use it at parent ponents attributes.

    import Child from './path/to/child'
    
    Child.attachStore('someStoresName')
    
    export default {
      name: 'parent',
      ponents: { Child }
      :
    }
    

The error you're encountering is being thrown during Vue/Vuex's initialization process, this.store cannot be converted because it doesn't exist yet. I haven't had to work with namespacing yet, and this is untested so I don't know if it will work, but you may be able to solve this problem by having an intermediary like this:

<script>
  export default {

    props: ['store'],

    data {
        namespace: (this.store !== undefined) ? this.store : 'null',
    },

    puted: {
      ...mapGetters(this.namespace, [
        'filters'
      ])
    }
  }
</script>

That ternary expression will return a string if this.store is undefined, if it isn't undefined then it will return the value in this.store.

Note that there is also a discussion about this on Vue's Github page here: https://github./vuejs/vuex/issues/863

Until Vue formally supports it, I replaced something like

...mapState({
  foo: state => state.foo
})

with

foo () {
  return this.$store.state[this.namespace + '/foo'] || 0
}

Where namespace is passed to my child ponent using a prop:

props: {
  namespace: { type: String, required: true }
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744294022a4567172.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信