vue 包装另一个组件,传递 props 和事件 [英] vue wrap another component, passing props and events

查看:21
本文介绍了vue 包装另一个组件,传递 props 和事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何编写我的组件来包装另一个 vue 组件,同时我的包装组件获得一些额外的道具?我的包装模板组件应该是:

<v-table></v-table><!-- 将 prop1 和 prop2 之外的所有 props 传递给 v-table --></wrapper-component>

和包装器道具:

道具:{prop1:字符串,prop2:字符串}

这里我想包装一个表格组件,并将传递给包装器的所有道具和事件传递给表格组件,另外还有两个额外的道具prop1prop2.在 vue 中执行此操作的正确方法是什么?事件也有解决方案吗?

解决方案

将要包装的组件放入包装器组件的模板中,添加 v-bind="$attrs" v-on="$listeners" 到该组件标记,然后将内部组件(以及可选的 inheritAttrs: false)添加到包装器组件的配置对象中.

Vue 的文档似乎没有在指南或任何内容中涵盖这一点,但是 $ 的文档attrs$listenersinheritAttrs 可以在 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屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆