【问题标题】:Accessing props in child vue component data function?在子 vue 组件数据函数中访问道具?
【发布时间】:2019-10-02 14:16:01
【问题描述】:

我有以下子组件。道具是从父项中的输入选择器更新的。为什么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>

【问题讨论】:

  • 子组件在父组件中渲染在哪里?我在父级中看不到 &lt;child :globalForm='globalForm'&gt; &lt;/child&gt; 之类的东西
  • 对此感到抱歉。我更新了谢谢

标签: javascript vue.js


【解决方案1】:

TLDR

level 应该是孩子的计算属性,以便您可以检测道具的变化。您在 data 函数中设置了 level,因此对 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>

更详细的解释

我将检查您的代码中的几个错误。

在您的子组件中

初始化组件时,thisdata 函数中不可用,因此this.globalForm 将未定义。重现时控制台报错。

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

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

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

真正的问题是level: this.globalForm.level 只运行一次,在你的组件初始化中,所以级别是undefined。当globalForm 属性发生变化时,level 已经被初始化并且不会改变(数据返回一个新对象,所以对属性的引用丢失了)。

您希望将level 转换为computed property,以便可以检测到对道具的更改并返回内部值。参见上面的代码 sn-p。

【讨论】:

    猜你喜欢
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 2019-05-23
    • 2020-06-15
    • 2021-05-04
    • 2018-08-03
    相关资源
    最近更新 更多