Я пытаюсь создать повторно используемый компонент, содержащий текстовое поле и флажок. Этот компонент будет использоваться несколько раз для изменения некоторого состояния. Поэтому я не могу напрямую указать, какая часть состояния внутри компонента.

<template>
  <v-layout>
    <v-text-field placeholder="Name ..." v-model="name"></v-text-field>
    <v-checkbox label="Frozen" v-model="frozen"></v-checkbox>
  </v-layout>
</template>

<script>
export default {
  name: "InstanceHeader",
  props: [ 'name', 'frozen' ],
}
</script>

И тогда я использую его следующим образом.

<instance-header
  :name="$store.state.myobj.name"
  :frozen="$store.state.myobj.isfrozen" />

Так что это, очевидно, не передает данные обратно. Я попытался следовать этому, который я изменил вызов, чтобы передать только «имя» в качестве v-модели, и изменил текстовое поле, чтобы иметь точно такие же @input и v-model из опоры. На самом деле это никак не изменило мой магазин Vuex.

Очевидно, это работает, если я изменю v-модель внутри повторно используемого компонента на $store.state.myobj.name, но тогда ее нельзя будет повторно использовать для других аспектов Vuex.

<template>
  <v-layout>
    <v-text-field placeholder="Name ..." :value="value" @input="$emit('input', $event.target.value)">
    <v-checkbox label="Frozen" v-model="frozen"></v-checkbox>
  </v-layout>
</template>

<script>
export default {
  name: "InstanceHeader",
  props: [ 'value' ],
  data () => { return { frozen: false } } // ignored for now
}
</script>

Затем вызовите

<instance-header v-model="$store.state.myobj.name" />

Это также не изменяет состояние.

Я читаю о событиях, которые, согласно документации Vuejs, являются правильными, чтобы передать эту информацию обратно родителю, и я уверен, что на этот вопрос где-то есть ответ, но я не могу его найти.

Я бы хотел, чтобы единственным источником правды для моего состояния был Vuex в $store.state, но я хочу иметь возможность редактировать это состояние с помощью компонентов, которые не обязательно знают, какую часть состояния они изменяют для повторного использования. . В основном так же, как атрибут v-model в любом поле ввода.

0
mmachenry 16 Дек 2019 в 20:01

1 ответ

Вы должны обернуть свой реквизит магазина следующим образом:

computed: {
  fullName: {
    // getter
    get: function () {
      return this.$store.state.myobj.name
    },
    // setter
    set: function (newValue) {
      this.$store.commit('setName', newValue)
    }
  }
}

Использовать так:

<instance-header v-model="fullName" />
0
Anatoly 17 Дек 2019 в 00:02
Хм... вы предлагаете поместить вычисляемый фрагмент внутри моего компонента? Это будет напрямую ссылаться на $store.state.myobj изнутри компонента.
 – 
mmachenry
17 Дек 2019 в 01:18
В чем разница между <instance-header :name="$store.state.myobj.name" :frozen="$store.state.myobj.isfrozen" /> и computed: { fullName: { // getter get: function () { return this.$store.state.myobj.name }, // setter set: function (newValue) { this.$store.commit('setName', newValue) } } } Оба используют прямую ссылку на $store.state.myobj в вашем компоненте
 – 
Anatoly
17 Дек 2019 в 20:47