访问子Vue组件数据功能中的道具?

时间:2019-05-15 12:23:03

标签: javascript vue.js

我有以下子组件。道具是从父级中的输入选择器更新的。为什么level: this.globalForm.level不更新孩子的level

父母:

<template>
  <div>
    <div class="form-container">
      <select class="form-control" v-model="level">
        <option v-for="level in options" v-bind:key="level">{{ level }}</option>
      </select>
      <button @click="submit()">Create</button>
    </div>
    <child v-bind:globalForm="globalForm"/>
  </div>
</template>

    <script>
inputFiled;
export default {
  data() {
    return {
      level: "",
      globalForm: {
        level: ""
      },
      options: ["level1", "level2", "level3"]
    };
  },
  components: {
    child
  },
  methods: {
    submit() {
      this.globalForm.level = this.level;
    }
  },
  watch: {
    level() {
      this.globalForm.level = this.level;
    }
  }
};
</script>

孩子:

<template>
  <div class="form-container">
      <option v-for="level in options" v-bind:key="level">{{ level }}</option>
  </div>
</template>

<script>
export default {
  props: { globalForm: Object },
  data() {
    return {
      options: ["level1","level2","level3",],
      level: this.globalForm.level //this does not update the child's level component
    };
  }
};
</script>

1 个答案:

答案 0 :(得分:1)

TLDR

level应该是孩子的计算属性,以便您可以检测道具的变化。您正在level函数中设置data,因此对prop的更新永远不会使其变为level

下面您将找到我想达到的目标的最小示例。

Vue.config.productionTip = false;
Vue.component('parent', {
  template: `
  <div class="parent">
    <b>PARENT</b>
    <div class="form-container">
      <select class="form-control" v-model="level">
        <option v-for="level in options" v-bind:key="level">{{ level }}</option>
      </select>
      <button @click="submit()">Create</button>
    </div>
    <child v-bind:globalForm="globalForm"/>
  </div>
  `,
  data: () => ({
    level: "",
    globalForm: {
      level: ""
    },
    options: ["level1", "level2", "level3"]
  }),
  methods: {
    submit() {
      this.globalForm.level = this.level;
    }
  }
});

Vue.component('child', {
  template: `
  <div class="form-container child">
      <p><b>Child</b></p>
      Level: {{ level }}
  </div>
  `,
  props: {
    globalForm: Object
  },
  computed: {
    level() {
      return  this.globalForm.level;
    }
  }
});

new Vue({
  el: "#app"
})
.parent {
  background-color: darkgray;
  padding: .5em;
  border: solid 1px black;
}
.child {
  background-color: lightgray;
  padding: .5em;
  border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <parent></parent>
</div>

更多详细说明

我将处理您的代码中的几个错误。

在您的子组件中

初始化组件时,this函数内部没有data,因此this.globalForm是不确定的。再现控制台时会在控制台中引发错误。

data() {
    return {
      options: ["level1","level2","level3",], // this looks like duplicated code from the parent
      level: this.globalForm.level // throws error
    };
 }

要解决该错误,您可以从vm的参数中获取data上下文。但这不是您问题的解决方案

data(vm) { // note vm
    return {
      level: vm.globalForm.level // note vm
    };
 }

真正的问题是level: this.globalForm.level 仅运行一次,在组件初始化中,因此级别为undefinedglobalForm道具更改时,level已被初始化,并且不会更改(数据返回一个新对象,因此对该道具的引用会丢失)。

您希望将level转换为computed property,以便可以检测到prop的更改并返回内部值。请参见上面的代码段。