javascript - How to "Avoid mutating a prop directly" in a recursive component
问题描述
I understand the concept: the child works on its own copy of the prop data, and when it's changed it it can $emit
that change so the parent can update itself.
However, I'm dealing with a recursive tree structure, e.g. a filesystem, is a good analogy.
[
{ type: 'dir', name: 'music', children: [
{ type: 'dir', name: 'genres', children: [
{ type: 'dir', name: 'triphop', children: [
{ type: 'file', name: 'Portishead' },
...
]},
]}
]}
]}
I have a recursive component called Thing
that takes a childtree
prop and looks a bit like this:
<template>
<input v-model="tree.name" />
<thing v-for="childtree in tree.children" :tree="childtree" ></thing>
</template>
Modifying a name is obviously going to modify the prop directly, which is to be avoided, and Vue emits a warning about it.
However, the only way I can see to avoid that would be for each component to do a deep copy of childtree
; then $emit
a copy of our copy and have a @input
(or such) copy it back to the original; all the way up the tree, which would then change the props all the way down the tree causing another deep copy of everything!
That feels like it's going to be really inefficient on a tree of any size.
Is there a better way? I know you can trick Vue into not issuing the error/warning example jsfiddle.
解决方案
Fix for your problem is passing just event from the child component. https://jsfiddle.net/kv1w72pg/2/
<input @input="(e) => $emit('input', e.target.value)" />
That being said I highly suggest you use other solution such as:
- Vuex,
- Event bus
It will make code clear and ensure one source of truth.
Edit: In the case of recursive inheritance, using provide inject would be easier: https://jsfiddle.net/s0b9fpr8/4/
This way you provide a function that can change the state of base component to all children components (function must be injected).
推荐阅读
- python - 如何将默认(3.x python)Google Colab 环境更改为 2.x python?
- python - 熊猫分组数据帧的最大值返回空白断言错误
- c++ - CMake 没有创建 Makefile(尝试安装 GODDeSS-Package)
- javascript - click 事件总是在父元素上触发,尽管在子元素上调用了 stopPropation()
- json - 如何在 Typescript 中保持代码 DRY 的同时解析多个 Json 文件?
- excel - 尝试使用间接创建动态命名范围
- java - 我想将我的 java 14 应用程序部署到 Heroku,但我遇到了 java 版本的一些问题
- matrix - 基于矩阵在Prolog中打印二叉树
- java - Java 控制台应用程序 jar - 处理异常并在 Windows 命令 prmpt 中继续
- algorithm - 求算法的时间复杂度