自定义组件中没有发生变异?

时间:2017-10-05 11:40:31

标签: vue.js vuejs2 vue-component vuex

首先,这是我目前的结构

CHILD COMPONENT

// HTML
<v-select
 v-bind:items="selectItems"
 v-model="selectedItemModel"
 label="Category"
 item-value="text"
></v-select>
<v-text-field
 label="Enter Value"
 type="number"
 v-model="compValModel"
></v-text-field>

// JS
props: {
 selectItems: {
  type: Array,
  required: true
 },
 selectedItem: {
  type: String
 },
 compVal: {
  type: Number
 },
}
date () {
 return {
  selectedItemModel: this.selectedItem,
  compValModel: this.compVal
 }
}

PARENT COMPONENT

// HTML

<component :selecItems="selectItems" :selectedItem="selectOneItem" 
:compVal="compOneVal"></component>

<component :selecItems="selectItems" :selectedItem="selectTwoItem" 
:compVal="compTwoVal"></component>

// JS
data () {
 return {
  selectItems: [some array]
 }
},
computed: {
 selectedOneItem: {
  get () {
    return this.$store.state.selectedOneItem
  },
  set (value) {
    this.$store.commit('selectedOneItem', value)
  }
 },
 selectedTwoItem: {
  get () {
    return this.$store.state.selectedTwoItem
  },
  set (value) {
    this.$store.commit('selectedTwoItem', value)
  }
 },
 compValOne: {
  get () {
    return this.$store.state.compValOne
  },
  set (value) {
    this.$store.commit('compValOne', value)
  }
 },
 compValTwo: {
  get () {
    return this.$store.state.compValTwo
  },
  set (value) {
    this.$store.commit('compValTwo', value)
  }
 }
}

Store

\\ STATE
compOneVal: 0,
compValTwo: 0,
selectedOneItem: null,
selectedTwoItem: null

\\ GETTER
compOneVal: (state) => state.compOneVal
compTwoVal: (state) => state.compTwoVal
selectedOneItem: (state) => state.selectedOneItem
selectedTwoItem: (state) => state.selectedTwoItem

\\ MUTATION
compOneVal (state, v) {
 state.compOneVal = v
},
compTwoVal (state, v) {
 state.compTwoVal = v
},
selectedOneItem (state, v) {
 state.selectedOneItem = v
},
selectedTwoItem (state, v) {
 state.selectedTwoItem = v
}

什么工作?

当我不使用组件结构时,并将html显式放在父组件中。一切都很完美。

什么不起作用?

当我使用组件结构时,所有输入和选择的变异都没有发生。它只有初始状态值。

那我在这里做错了什么?为什么事情在没有组件结构但没有组件结构的情况下工作?

2 个答案:

答案 0 :(得分:1)

您有几个语法错误:

  • 您在子组件的代码中传递了selecItems道具,它应该是selectItems
  • 您的子组件中有一个date函数,应该是data

但根本问题是您没有修改父组件上的计算属性。您只需将它们传递给子组件即可。如果您希望变量在父范围内更改以响应子组件中的某些事件,则您需要从子组件中为该事件发出事件并在父组件中侦听该事件。 / p>

通常,您可以使用子组件标记上的v-model directive来执行此操作。这样,当从子节点发出input事件时,父节点上的属性将自动更新(无需显式侦听父节点中的@input事件)。

但是,由于您显然正在尝试将两个单独的值绑定到子组件(selectedItemcompVal),因此当子项上的相关数据属性发生更改时,您应该发出两个单独的事件: / p>

props: {
  selectItems: {
    type: Array,
    required: true
  },
  selectedItem: {
    type: String
  },
  compVal: {
    type: Number
  },
}
data() {
  return {
    selectedItemModel: this.selectedItem,
    compValModel: this.compVal
  }
},
watch: {
  selectedItemModel(value) {
    this.$emit('selectedItemInput', value);
  },
  compValModel(value) {
    this.$emit('compValInput', value);
  }
}

然后,在父级上侦听这些事件并更新相应的属性:

<component 
  :selecItems="selectItems" 
  :selectedItem="selectOneItem" 
  :compVal="compOneVal"
  @selectedItemInput="selectOneItem = $event"
  @compValInput="compOneVal = $event"
></component>

现在,只要子组件的selectedItemModelcompValModel数据属性发生更改,父级的相应属性就会更新,触发各自的计算属性set方法,从而更新商店。

答案 1 :(得分:0)

除了@thanksd提到的拼写错误(selecItems而不是selectItems

我会向您提供一些可以提供帮助的文档推荐的提示

  1. 使用操作来触发突变,而不是直接提交。
  2. 您的状态应使用您希望的类型进行初始化,例如:空数组,对象或字符串
  3. 如果要访问子组件的商店值,请直接执行(访问子组件中的商店)。除非确实需要,否则传递道具,例如:您可能希望传递与商店中的值不同的值或在父级上使用相同的值
  4. 如果你有吸气剂,也许使用mapGetters可能是更好的选择。除此之外,mapActions。因此,您可以在组件中使用商店中的直接值,而无需始终使用this.$store