有没有其他方法可以将数据从子组件传递到嵌套的父组件(6级以上),而不使用vuejs中的发射和存储



我需要将数据从子组件传递到父组件(嵌套(,我知道我们可以用emitstore来实现这一点,但我想知道,还有其他方法可以更好地实现这一目标吗?

我不想仅仅因为我的父组件是6级以上就使用emit

Store不需要是vuexpinia。它可以是一个外部reactive(),在使用它的所有组件中导入,而不管它们之间的关系如何。

把它想象成一个data: () => ({})对象,但没有组件。这里有一个例子,我正在创建一个简单的反应"存储">,并将其注入App和Child(6级深度(。

const { createApp, reactive, defineComponent } = Vue;
const store = reactive({
foo: 'bar'
})
const app = createApp({
setup: () => ({ store })
});
app.component('parent', defineComponent({
template: '<div class="parent">Parent<br><slot></slot></div>'
}));
app.component('child', defineComponent({
setup: () => ({ store }),
template: '<input v-model="store.foo">'
}));
app.mount('#app')
.parent .parent {
padding-left: 1rem;
}
input {
margin-left: 1rem;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app">
<parent>
<parent>
<parent>
<parent>
<parent>
<child />
</parent>
</parent>
</parent>
</parent>
</parent>
<pre v-text="store" />
</div>

同样的事情,在Vue2:中

const store = Vue.observable({
foo: 'bar'
})
Vue.component('parent', {
template: '<div class="parent">Parent<br><slot /></div>'
});
Vue.component('child', {
computed: {
store: () => store
},
template: '<input v-model="store.foo">'
});
new Vue({
computed: {
store: () => store
}
}).$mount('#app')
.parent .parent {
padding-left: 1rem;
}
input {
margin-left: 1rem;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<div id="app">
<parent>
<parent>
<parent>
<parent>
<parent>
<child />
</parent>
</parent>
</parent>
</parent>
</parent>
<pre v-text="store" />
</div>

在一个真正的应用程序中;存储";在文件中定义,并在使用该文件的任何组件中导入。(例如:

import { reactive } from 'vue'
export const myStore = reactive({
//...stuff
})
anywhere else: 
import { myStore } from './path/to/store'

注意:如果您使用的是Vue2,您可以从@vue/composition-api插件导入reactive,也可以使用Vue.observable()。它提供了相同的功能。

即使上述方法有效,您使用得越多,使用piniavuex的实际好处就越多,因为它们与vue devtools集成会带来巨大好处。让您能够检查、回滚或回放对反应状态的更改。更不用说,您还可以在商店中定义操作,这样就不必将它们分散在多个组件上,当您想从两个或多个不同的组件执行相同的操作时,这一点尤其有用。


另一个选项是使用专门为绕过父/子链而开发的提供/注入。当您希望专门为当前零部件的子体提供,但不为其同级零部件的后代提供时,它非常有用。例如:

item-1
component
component
child-1
item-2
component
component
child-2
child-3

在上述情况下,如果您希望child-2child-3继承/更新item-2,但不影响item-1,那么您将在item-2中使用provide,在child-2child-3中使用inject

我个人还没有使用过注入/提供,因为我发现与外部商店合作非常强大。即使在理论上,我也有这样的情况。我使用一个单独的商店,在那里我可以唯一地识别祖先。孙子女使用该标识符来更新存储中相应的祖先。

事实上,我使用emit的唯一地方是在不可知组件中,它可以有任何父级,接受一些输入,执行一些操作,然后更新它们的父级(例如:上下文(。一个很好的例子是通用表单组件,它们不必知道任何关于父表单的信息。
另一个这样的例子是agostic列表呈现器,它同样不在乎它们列出了什么。他们";发射";对父组件的单击操作,它知道单击的实际含义。

您可以为此目的使用eventBus。这是一个工作演示。

最新更新