简体   繁体   English

为什么 vue v-for 在数据更改时不重新渲染子组件?

[英]why vue v-for doesn't rerender child component when data change?

parent父母

export default {
  name: "App",
  components: {ChildComponent},
  data: function() {
    return {
      itemList: []
    };
  },
  methods: {
    fetchData() {
      callApi().then(res => { this.itemList= res; })
    }
  }
};

<template>
      <ol>
        <template v-for="(item) in itemList">
          <li :key="item.id">
            <child-component :item="item"></card>
          </li>
        </template>
      </ol>
</template>

child孩子

export default {
  name: "ChildComponent",
  props: {
    item: { type: Object }
  },
  data: function() {
    const {
      name,
      address,
      .......
    } = this.item;
    return {
      name,
      address,
      ......
    };
  },
};
</script>

child get the item props which is an object. child 获取作为对象的项目道具。

I'm confused why the itemList point to another array, but the child doesn't update?我很困惑为什么 itemList 指向另一个数组,但孩子没有更新?

is it because key doesnt change?是因为密钥没有改变吗? (but other data changed..) (但其他数据发生了变化..)

thanks谢谢

It is because of this part of your code:这是因为您的代码的这一部分:

const {
  name,
  address,
} = this.item;
return {
  name,
  address,
};

What it does it copies name and address from item and return them.它的作用是从项目中复制nameaddress并返回它们。 It happens only once in your code while component is created.在创建组件时,它只会在您的代码中发生一次。 If after that your prop item change, your data doesn't copy it and still returns the first values.如果在那之后您的道具item发生了变化,您的数据不会复制它并仍然返回第一个值。

Solution: If you don't change name or address in a child component, just use a prop解决方案:如果你不更改子组件中的nameaddress ,只需使用一个道具

this.item.name in a script or {{ item.name }} in a template脚本中的 this.item.name 或模板中的 {{ this.item.name {{ item.name }}

It is already reactive so your component will update when prop changes.它已经是响应式的,因此您的组件将在 prop 更改时更新。

It is because the data function is called only once on the creation of the component.这是因为data函数只在创建组件时调用一次。

The recommended way to get data that depend on other data is to use computed .获取依赖于其他数据的数据的推荐方法是使用computed

export default {
  name: "ChildComponent",
  props: {
    item: { type: Object }
  },
  computed: {
    name() {
      return this.item.name;
    },
    address() {
      return this.item.address;
    }
  }
};

https://v2.vuejs.org/v2/guide/computed.html#Basic-Example https://v2.vuejs.org/v2/guide/computed.html#Basic-Example

Not sure what you do in your child component but this is enough to do and should react to your parent component changes.不确定您在子组件中做了什么,但这已经足够了,并且应该对您的父组件更改做出反应。 Basically the idea is to use the prop.基本上这个想法是使用道具。 I made some tweaks also.我也做了一些调整。

export default {
  name: "App",
  components: {ChildComponent},
  data: function() {
    return {
      itemList: []
    };
  },
  methods: {
    fetchData() {
      callApi().then(res => { this.itemList= res; })
    }
  }
};

<template>
      <ol>
        <li v-for="(item) of itemList" :key="item.id">
          <card :item="item"></card>
        </li>
      </ol>
</template>


export default {
  name: "ChildComponent",
  props: {
    item: { 
      type: Object,
      required: true
    }
  }
};
</script>

<template>
  <div>
    {{ item.name }} {{ item.address }}
  </di>
</template>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM