vue.js - 如何封装/包装 VueJS 组件?

标签 vue.js vuejs2 vue-component

大家好,请原谅我的英语:-)

我有一个可以采用动态槽的 Vue 组件(槽的名称取决于 props)。

我在多个地方使用它,并且某些插槽始终存在。

为了避免冗余,我正在寻找一种方法来创建一个“包装”最终组件的组件,以允许我仅定义附加插槽。

如果有一种“明显”的方法来实现它,我可能会错过它:-)

代码示例

没有“包装组件”

<b-table
  show-empty
  small
  hover
  
  [...some others and always present props...]

  :items="aDataVarThatWillChangeBasedOnTheContext"

  [...some others and uniq props...]
>
  <template slot="same-1">
   A slot that will always be present with the same content (for example, a checkbox in the first column)
  </template>

  <template slot="same-2">
   A slot that will always be present with the same content (for example, some action buttons in the last column)
  </template>

  [...some others and always present slots...]
  
  <template slot="not-the-same">
   A slot that is only used in this context (for example, a duration based on a row timestamp and a timestamp picked by the user)
  </template>

  [...some others and uniq slots...]
</b-table>

使用“包装组件”

<my-b-table
  :items="aDataVarThatWillChangeBasedOnTheContext"
>
  <template slot="not-the-same">
   A slot that is only used in this context (for example, a duration based on a row timestamp and a timestamp picked by the user)
  </template>
</my-b-table>

注意:动态槽名称是不可预测的。 如果我突然需要一个“foo”列,我应该能够传递一个“foo”槽(在我的例子中还有一个“HEAD_foo”槽)

一些研究

我读到here那:

They’re (the functionnal components) also very useful as wrapper components. For example, when you need to:

  • Programmatically choose one of several other components to delegate to
  • Manipulate children, props, or data before passing them on to a child component

“在将子组件、 Prop 或数据传递给子组件之前对其进行操作”似乎正是我所需要的。

我查看了渲染函数,但很多东西似乎都没有实现,比如 v-model,而且我很难弄清楚如何传递动态槽...

提前感谢您的回答!

up:2018年3月7日我仍然不知道如何解决这个案例

最佳答案

找到了一个月前我不太清楚的答案。

(“动态”在这里意味着“不是由组件显式声明,而是由父组件给出”)

包装组件

Props 和作用域槽可以通过 createElement 函数的 options 对象动态给出。

“简单”槽可以通过 createElement 函数的 childs 数组动态给出。

包装组件

除非组件具有功能,否则 Prop 不能是动态的。

插槽始终可以动态检索。

仅当组件不起作用时才能检索作用域插槽。

结论

不可能同时拥有动态 Prop 和作用域插槽...

但是可以声明所有需要的 Prop ,然后使用“非功能”组件作为包装器和包装。


如何

从非功能组件中检索

var component = Vue.component('component-name', {
  props: ['name', 'of', 'the', 'props'],
  
  // [...]
  
  aMethod: function () {
    this._props // all the declared props
    this.$slots // all the slots
    this.$scopedSlots // all the scoped slots
  }
});

从功能组件中检索

var component = Vue.component('component-name', {
  functional: true,

  render: function (createElement, context) {
    context.props // all the props
    context.children // all the slots as an array
    context.slots() // all the slots as an object
  }
});

赋予子组件

var component = Vue.component('component-name', {
  render: function (createElement) {
    return createElement(
      childComponent,
      {
        props: propsToGive,
        scopedSlots: scopedSlotsToGive
      },
      [
        // non-scoped slots to give
        createElement('slot-tag-name', {slot: 'slot-name'})
      ]
    );
  }
});

引用文献

https://v2.vuejs.org/v2/guide/render-function.html

https://v2.vuejs.org/v2/guide/render-function.html#createElement-Arguments

https://v2.vuejs.org/v2/guide/render-function.html#Functional-Components


沙盒

https://jsfiddle.net/5umk7p52/

关于vue.js - 如何封装/包装 VueJS 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48807290/

相关文章:

javascript - 以编程方式启动 vue-cli-service serve 时控制 webpack 的冗长程度

javascript - Nuxt Firebase 身份验证中间件

javascript - Bootstrap Vue perPage 用于自定义列或行

css - 如何将选择按钮放置在节目时间表扩展面板的右侧?

javascript - 如何使用 VueJS 或 JavaScript 在多维数组中进行搜索

javascript - 如何为 Chart.js 日期标签设置语言环境?

javascript - 如何在 vue.js 2 上使用 keyup 禁用点?

java - 如何在 Jooby 应用程序上正确设置 CORS

javascript - vue-router:防止参数更改时的路由

javascript - Vue.js 模块构建