vue 包装另一个组件,传递 props 和事件
[英] vue wrap another component, passing props and events
本文介绍了vue 包装另一个组件,传递 props 和事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如何编写我的组件来包装另一个 vue 组件,同时我的包装组件获得一些额外的道具?我的包装模板组件应该是:
<v-table></v-table><!-- 将 prop1 和 prop2 之外的所有 props 传递给 v-table --></wrapper-component>
和包装器道具:
道具:{prop1:字符串,prop2:字符串}
这里我想包装一个表格组件,并将传递给包装器的所有道具和事件传递给表格组件,另外还有两个额外的道具prop1
和prop2
.在 vue 中执行此操作的正确方法是什么?事件也有解决方案吗?
解决方案
将要包装的组件放入包装器组件的模板中,添加 v-bind="$attrs" v-on="$listeners"
到该组件标记,然后将内部组件(以及可选的 inheritAttrs: false
)添加到包装器组件的配置对象中.
Vue 的文档似乎没有在指南或任何内容中涵盖这一点,但是 $ 的文档attrs、$listeners 和 inheritAttrs 可以在 Vue 的 API 文档.此外,在将来搜索此主题时可能会对您有所帮助的术语是Higher-OrderComponent" (HOC) - 与您使用的包装器组件"基本相同.(这个词是我最初发现 $attrs 的方式)
例如...
<模板><div class="wrapper-component"><v-table v-bind="$attrs" v-on="$listeners"></v-table>
模板><脚本>从'./BaseTable'导入表导出默认{组件:{'v-table':表},inheritAttrs: false//可选}
编辑:或者,您可能希望使用 动态组件通过is
属性,所以你可以传入要包装的组件作为 prop(更接近高阶组件的想法),而不是始终是相同的内部组件.例如:
<模板><div class="wrapper-component"><component :is="wraps" v-bind="$attrs" v-on="$listeners"></component>
模板><脚本>导出默认{inheritAttrs: false,//可选道具:['包裹']}
编辑 2:我错过的 OP 原始问题的一部分是通过除一两个之外的所有道具.这是通过在包装器上显式定义 prop 来处理的.引用 $attrs
的文档:
<块引用>
包含未被识别(和提取)为 props 的父作用域属性绑定(类和样式除外)
例如,example1
在下面的代码片段中被识别和提取为一个道具,因此它不会作为被传递的 $attrs
的一部分包含在内.
Vue.component('wrapper-component', {模板:`<div class="wrapper-component"><component :is="wraps" v-bind="$attrs" v-on="$listeners"></component>
`,//注意:example1"是在包装器上明确定义的,而不是通过 $attrs 传递给嵌套组件道具:['包裹','example1']})Vue.component('帖子', {模板:`<div><div>帖子组件</div><div v-text="example1"></div><div v-text="example2"></div><div v-text="example3"></div>
`,道具: ['example1', 'example2', 'example3'],})新的 Vue({el: '#app',模板:`<wrapper-component wraps="posts"示例 1="示例 1"示例 2="示例 2"示例 3="示例 3"></wrapper-component>`,})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></脚本><div id="app"></div>
How can I write my component to wrap another vue component, while my wrapper component get some extra props? My wrapper template component should be:
<wrapper-component>
<v-table></v-table> <!-- pass to v-table all the props beside prop1 and prop2 -->
</wrapper-component>
and the wrapper props:
props: {
prop1: String,
prop2: String
}
Here I want to wrap a table component, and pass to the table component all the props and events that were passed to the wrapper, beside two extra props prop1
and prop2
. What is the correct way of doing this in vue?
And is there a solution for events too?
解决方案
Place the component you wish to wrap into the template of the wrapper component, add v-bind="$attrs" v-on="$listeners"
to that component tag, then add the inner component (and, optionally, inheritAttrs: false
) to the wrapper component's config object.
Vue's documentation doesn't seem to cover this in a guide or anything, but docs for $attrs, $listeners, and inheritAttrs can be found in Vue's API documentation. Also, a term that may help you when searching for this topic in the future is "Higher-Order Component" (HOC) - which is basically the same as your use of "wrapper component". (This term is how I originally found $attrs)
For example...
<!-- WrapperComponent.vue -->
<template>
<div class="wrapper-component">
<v-table v-bind="$attrs" v-on="$listeners"></v-table>
</div>
</template>
<script>
import Table from './BaseTable'
export default {
components: { 'v-table': Table },
inheritAttrs: false // optional
}
</script>
Edit: Alternatively, you may want to use dynamic components via the is
attribute so you can pass in the component to be wrapped as a prop (closer to the higher-order component idea) instead of it always being the same inner component. For example:
<!-- WrapperComponent.vue -->
<template>
<div class="wrapper-component">
<component :is="wraps" v-bind="$attrs" v-on="$listeners"></component>
</div>
</template>
<script>
export default {
inheritAttrs: false, // optional
props: ['wraps']
}
</script>
Edit 2: The part of OP's original question that I missed was passing all props EXCEPT one or two. This is handled by explicitly defining the prop on the wrapper. To quote the documentation for $attrs
:
Contains parent-scope attribute bindings (except for class and style) that are not recognized (and extracted) as props
For example, example1
is recognized and extracted as a prop in the snippet below, so it doesn't get included as part of the $attrs
being passed down.
Vue.component('wrapper-component', {
template: `
<div class="wrapper-component">
<component :is="wraps" v-bind="$attrs" v-on="$listeners"></component>
</div>
`,
// NOTE: "example1" is explicitly defined on wrapper, not passed down to nested component via $attrs
props: ['wraps', 'example1']
})
Vue.component('posts', {
template: `
<div>
<div>Posts component</div>
<div v-text="example1"></div>
<div v-text="example2"></div>
<div v-text="example3"></div>
</div>
`,
props: ['example1', 'example2', 'example3'],
})
new Vue({
el: '#app',
template: `
<wrapper-component wraps="posts"
example1="example1"
example2="example2"
example3="example3"
></wrapper-component>
`,
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
这篇关于vue 包装另一个组件,传递 props 和事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!