Динамическая `v-модель` для вычисляемых свойств - на основе параметра маршрута - PullRequest
0 голосов
/ 15 января 2019

Я создаю компонент, который можно использовать для установки различных свойств 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 становится неопределенным (?)

Как я могу сделать эту работу?

UPDATE

Мне также было бы интересно узнать, почему это не работает (ошибка компиляции):

<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 голосов
/ 15 января 2019

Да, все внутри вашего <template> находится в области действия this, поэтому this не определено.

v-model - это просто синтаксический сахар для :value и @input, поэтому вы можете обработать это с помощью пользовательского события и вычисляемого свойства для :value.

Вы также можете использовать вычисляемое свойство с геттером и сеттером; Что-то вроде

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(...)
  }
}
...