用于计算属性的动态“ v模型”-基于路径参数

时间:2019-01-15 11:52:45

标签: javascript vue.js vuex vue-router v-model

我正在构建一个组件,该组件可用于设置各种vuex属性,具体取决于路由中传递的名称。这是它的天真要旨:

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

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

请注意,我将this[$route.params.name]传递给v-model,以使其动态。这适用于设置(组件加载正常),但是在尝试设置值时,出现此错误:

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

我认为这是因为this中的v-model变得不确定(?)

我该如何做?

更新

我也想知道为什么这不起作用(编译错误):

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

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

1 个答案:

答案 0 :(得分:2)

是的,<template>中的所有内容都在this范围内,所以this是未定义的。

v-model只是:value@input的语法糖,因此您可以使用自定义事件和:value的计算属性来处理它。

您还可以将计算属性与getter和setter一起使用;像

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

修改 如果您需要在设置器中执行更多的逻辑,则可以像这样将其分开,使获取器保持简单,并坚持使用一个已计算的属性;

computed: {
  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.commit(...)
  },
  bar(val) {
    this.$store.commit(...)
  }
}