首页 > 解决方案 > Vue - 更新子组件而不更新父组件。最好的方法?

问题描述

我是 Vue 的新手,我正在尝试动态创建一个 Div 列表,每个 Div 都有 X 个子 Div。还将在不同点添加、编辑或删除儿童。

div 的数据最初通过一个名为的结构化数组到达pageObjects

var pageObjects = [
  {
    id: "1",
    title: "Page 1",
    subpages: [
      {
        id: "2_1",
        title: "Page 2 Subpage 1"
      },
      {
        id: "2_2",
        title: "Page 2 Subpage 2"
      }
    ]
  },
  {
    id: "2",
    title: "Page 2",
    subpages: [
      {
        id: "2_1",
        title: "Page 2 Subpage 1"
      },
      {
        id: "2_2",
        title: "Page 2 Subpage 2"
      }
    ]
  }
];

我可以使用自定义 Vue 组件轻松创建父 div 和子 div:

//init the container
var pagescontainer = new Vue({
  el: '#pagescontainer',
  data: {
    pageObjects
  }
});

Vue.component('page-component', {
  template: `
    <div v-bind:id="'page' + page.id">
      This is a parent div with title {{page.title}} 
      <subpage-component v-for="subpage in page.subpages" v-bind:subpage="subpage" />
    </div>
  `,
  props: {
    page: Object
  }
});

Vue.component('subpage-component', {
  template: `
    <div v-bind:id="'subpage' + subpage.id">
      This is a sub page with title {{ subpage.title }}
    </div>`,
  props: {
    subpage: Object
  }
});

然后可以通过 HTML 创建所有父母和孩子:

<div id="pagescontainer">
  <page-component v-for="page in pageObjects" :page="page"/>
</div>

这可行 - 但我不知道编辑子数据或动态添加新子数据的最佳实践。我可以更改pageObject数组,它会更新所有当前内容,但必须有更好的方法 - 为所有父母和 div 编辑整个数组,只是为了更改一个子 div 的一部分,这似乎过度且效率低下。另外,我不能仅通过从数组中删除子项来添加/删除子项。

为了独立编辑子 div 的内容,我尝试将“数据”变量和方法直接添加到子页面组件:

Vue.component('subpage-component', {
  template: `
    <div v-bind:id="'subpage' + subpage.id">
      This is a sub page with title {{ subpage.title }}
    </div>
  `,
  props: {
    subpage: Object
  },
  data: {
    title: "some title here"
  },
  methods: {
    updateSubPageHtml: function (_title) {
      console.log(this);
      console.log("updating title to " + _title);
      this.title = _title;
    }
  }
});

但是当我运行它时,我收到以下错误:

ReferenceError:未定义标题。

有人可以建议一种更好的方法来动态地向父母添加/编辑/删除孩子吗?

标签: javascriptvue.jsvuejs2parent-child

解决方案


首先data应该始终是一个函数,它返回一个对象而不仅仅是一个对象。

您通常可以只替换整个 pageObjects 数组。Vue 仍然会将生成的 html 与虚拟 DOM 进行比较,并且只更改实际需要的内容。您也可以使用您提供的 ID 直接更改页面和子页面。全局执行此操作,您可以$emit在父组件中使用和更改状态,或者将 Vuex 集成到您的项目中。

编辑数组后,Vue 不会重新渲染具有相同属性值的组件。


推荐阅读