我如何编写我的组件来包装另一个vue组件,而我的包装器组件可以获得一些额外的props ?我的包装器模板组件应该是:

<wrapper-component>
   <v-table></v-table> <!-- pass to v-table all the props beside prop1 and prop2 -->
</wrapper-component>

还有包装props :

props: {
  prop1: String,
  prop2: String
}

这里我想包装一个表组件,并将传递给包装器的所有props 和事件传递给表组件,另外还有两个props prop1prop2.在vue中这样做的正确方式是什么?

推荐答案

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

Vue的文档似乎没有在指南或任何东西中涵盖这一点,但$attrs$listenersinheritAttrs的文档可以在Vue's API documentation中找到.另外,在将来搜索这个主题时,一个可能有助于您的术语是"Higher-Order Component"(HOC)——这与您使用的"包装器组件"基本相同.(这个术语是我最初发现$attrs的方式)

例如

<!-- 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:或者,你可能希望通过is attribute使用dynamic components,这样你就可以将要包装的组件作为props 传递进来(更接近高阶组件的概念),而不是始终是同一个内部组件.例如:

<!-- 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:OP最初的问题中,我错过了除了一两个props 以外的所有props .这是通过在包装器上显式定义props 来处理的.要引用$attrs的文档:

包含未被识别(和提取)为props 的父作用域属性绑定(类和样式除外)

例如,在下面的代码片段中,example1被识别并提取为一个props ,因此它不会作为$attrs的一部分被包含.

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.js相关问答推荐

如何使用 vueJS 上的 ref( ) 函数创建二维数组定义?

如何使用 Vite 从公共目录导入 JSON 文件?

如何将字符串中的
解析为 VUE.js 中的 html 标记

禁用 vue-cli webpack 编码图像 base64

Vue:需要禁用页面上的所有输入

VueJS:向左,元素的顶部位置?

如何修复跨域读取阻塞 (CORB) 阻止了 MIME 类型应用程序/json 的跨域响应问题?

在 v-for 的情况下如何从 v-model 输入更新 Vuex 存储

W3C 验证和 Vue 的 HTML 绑定语法

将 props 传递给 Vue 组件中的元素属性

在渲染组件之前从 api 获取数据

如何使用 vuex 删除项目?

Nuxt:显示静态文件夹中的本map像

从 Axios 响应中解析 XML,推送到 Vue 数据数组

Select 下拉列表中的复选框后如何清除 v-autocomplete(多个)搜索输入?

Vue 组件中的组件渲染函数中可能存在无限更新循环警告

将登录页面包含在单页应用程序中是否不安全?

VueJS 2 在多个组件上debounce

单击时交换组件

Vue-i18n - 无法读取未定义的属性配置