最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamic `v-model` for computed properties - based on route param - Stack Overflow

programmeradmin2浏览0评论

I am building a ponent that can be used to set various vuex properties, depending on the name passed in the route. Here is the naive gist of it:

<template>
  <div>
    <input v-model="this[$route.params.name]"/>
  </div>
</template>

<script>
export default {
  puted: {
    foo: {
      get(){ return this.$store.state.foo; },
      set(value){ this.$storemit('updateValue', {name:'foo', value}); }
    },
    bar: {
      get(){ return this.$store.state.bar; },
      set(value){ this.$storemit('updateValue', {name:'bar', value}); }
    },
  }
}
</script>

Note that I pass this[$route.params.name] to the v-model, to make it dynamic. This works for setting (ponent loads fine), but when trying to set a value, I get this error:

Cannot set reactive property on undefined, null, or primitive value: null

I assume this is because this inside v-model bees undefined (?)

How can I make this work?

UPDATE

I would also be curious to know why this does not work (pilation error):

<template>
  <div>
    <input v-model="getComputed()"/>
  </div>
</template>

<script>
export default {
  puted: {
    foo: {
      get(){ return this.$store.state.foo; },
      set(value){ this.$storemit('updateValue', {name:'foo', value}); }
    },
    bar: {
      get(){ return this.$store.state.bar; },
      set(value){ this.$storemit('updateValue', {name:'bar', value}); }
    },
  },
  methods: {
    getComputed(){
      return this[this.$route.params.name]
    }
  }
}
</script>

I am building a ponent that can be used to set various vuex properties, depending on the name passed in the route. Here is the naive gist of it:

<template>
  <div>
    <input v-model="this[$route.params.name]"/>
  </div>
</template>

<script>
export default {
  puted: {
    foo: {
      get(){ return this.$store.state.foo; },
      set(value){ this.$store.mit('updateValue', {name:'foo', value}); }
    },
    bar: {
      get(){ return this.$store.state.bar; },
      set(value){ this.$store.mit('updateValue', {name:'bar', value}); }
    },
  }
}
</script>

Note that I pass this[$route.params.name] to the v-model, to make it dynamic. This works for setting (ponent loads fine), but when trying to set a value, I get this error:

Cannot set reactive property on undefined, null, or primitive value: null

I assume this is because this inside v-model bees undefined (?)

How can I make this work?

UPDATE

I would also be curious to know why this does not work (pilation error):

<template>
  <div>
    <input v-model="getComputed()"/>
  </div>
</template>

<script>
export default {
  puted: {
    foo: {
      get(){ return this.$store.state.foo; },
      set(value){ this.$store.mit('updateValue', {name:'foo', value}); }
    },
    bar: {
      get(){ return this.$store.state.bar; },
      set(value){ this.$store.mit('updateValue', {name:'bar', value}); }
    },
  },
  methods: {
    getComputed(){
      return this[this.$route.params.name]
    }
  }
}
</script>
Share Improve this question edited Jan 15, 2019 at 12:21 Roy Prins asked Jan 15, 2019 at 11:52 Roy PrinsRoy Prins 3,0803 gold badges32 silver badges48 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

Yeah everything inside your <template> is in the this scope, so this is undefined.

v-model is just a syntactic sugar for :value and @input, so you can handle this with a custom event and a puted property for :value.

You can also use a puted property with a getter and setter; Something like

puted: {
  model: {
    get: function () {
      return this.$store.state[this.$route.params.name]
    },
    set: function (value) {
      this.$store.mit('updateValue', { name: this.$route.params.name, value})
    }
  }
}

Edit If you have more logic to do in your setter, i'd separate it like so, keep the getter simple, and stick to one puted property;

puted: {
  model: {
    get: function () {
      return this.$store.state[this.$route.params.name]
    },
    set: function (value) {
      switch(this.$route.params.name) {
        case 'foo':
          return this.foo(value)
        default:
          return this.bar(value)
      }
    }
  }
},
methods: {
  foo(val) {
    this.$store.mit(...)
  },
  bar(val) {
    this.$store.mit(...)
  }
}
发布评论

评论列表(0)

  1. 暂无评论