我需要将数据从子组件传递到父(嵌套)组件,我知道我们可以使用 emit
或 store
来做到这一点,但我想知道,还有其他吗方式,以更好的方式做到这一点?
我不想仅仅因为我的父组件向上 6 级而使用 emit
。
最佳答案
商店不一定需要 vuex
或pinia
。它可以是外部 reactive()
,导入到所有使用它的组件中,无论它们之间的关系如何。
将其视为 data: () => ({})
对象,但没有组件。下面是一个示例,其中我创建了一个简单的响应式(Reactive)“store”,并将其注入(inject)到 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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e181b0b2e5c4058405f5a" rel="noreferrer noopener nofollow">[email protected]</a>"></script>
<div id="app">
<parent>
<parent>
<parent>
<parent>
<parent>
<child />
</parent>
</parent>
</parent>
</parent>
</parent>
<pre v-text="store" />
</div>
在真实的应用程序中,您将在文件中定义“store”并导入到使用它的任何组件中。 (例如:
import { reactive } from 'vue'
export const myStore = reactive({
//...stuff
})
anywhere else:
import { myStore } from './path/to/store'
注意:如果您使用的是 Vue2,则可以导入 reactive
来自@vue/composition-api
插件或者您可以使用 Vue.observable()
反而。它提供相同的功能。
即使上述方法有效,您使用它的次数越多,您实际上从使用 pinia
中受益就越多或vuex
,因为它们具有与 vue devtools 集成的巨大好处。让您能够检查、回滚或重放 react 状态的更改。更不用说您还可以在商店上定义操作,因此您不必将它们分散在多个组件中,当您想要从两个或多个不同的组件执行相同的操作时特别有用。
另一个选择是使用 provide/inject专为绕过父/子链而开发。当您想要专门为当前组件的后代而不是其同级组件的后代提供时,它非常有用。例如:
item-1
component
component
child-1
item-2
component
component
child-2
child-3
在上面的例子中,如果你想要child-2
和child-3
继承/更新item-2
但不影响item-1
,那么您将使用 provide
在item-2
和inject
在child-2
和child-3
.
我个人没有使用过注入(inject)/提供,因为我发现与外部商店合作非常强大。即使从理论上讲,我遇到了上述情况。我只使用一家商店,在那里我可以唯一地识别祖先。孙辈使用该标识符来更新商店中适当的祖先。
事实上,我唯一使用emit
的地方位于不可知组件中,它可以有任何父组件,接受一些输入,执行一些操作,然后更新其父组件(例如:上下文)。一个很好的例子是通用表单组件,它不必了解有关父表单的任何信息。
另一个这样的例子是 agonstic 列表渲染器,它同样不关心它们列出的内容。它们将点击操作“发出”到父组件,父组件知道该点击的实际含义。
关于vue.js - 有没有其他方法可以将数据从子组件传递到嵌套父组件(向上 6 层),而不使用 vuejs 中的发出和存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71472149/