【问题标题】:VueJS: Analyze content of a slot with components before they are mountedVueJS:在安装组件之前分析插槽的内容
【发布时间】:2017-09-29 10:52:59
【问题描述】:

假设我们有一个组件<my-cp :list="list"></my-cp>

使用这种模板:

<div class="container">
  <slot></slot> 
  <my-cp2 v-for="li in list" :my-data="li.data"></my-cp2>
</div>

我的问题:是否可以使用列表作为数组或使用 HTML 来初始化我的组件 my-cp

我的意思是有两种可能性。在这种情况下,HTML 将如下所示:

<my-cp>
  <my-cp2 my-data="foo">
  <my-cp2 my-data="bar">
</my-cp>

我试图在挂载之前分析插槽的内容,但似乎只有在子组件已经挂载后才能访问该元素。

【问题讨论】:

  • 如果有人提供了默认的槽内容作为后备,您的意思是要使用槽内容吗?
  • 没错!感谢您的翻译:)
  • 对不起,没有“将默认设置作为后备”,而是“作为后备”。我的意思是该插槽没有默认内容,但如果提供了内容,则应将其用作后备

标签: vue.js vuejs2 vue-component


【解决方案1】:

将您的默认内容放入组件中的插槽。如果用户添加插槽内容,他们的内容将显示。否则,将显示槽内容。

<div class="container">
  <slot>
    <my-cp2 v-for="li in list" :my-data="li.data"></my-cp2>
  </slot> 
</div>

这是example

编辑

经过cmets的进一步讨论,我相信我明白你想要做什么。据我了解,为了向未来的读者澄清,@Nabab 希望能够使用来自属性的数据或来自组件插槽中 HTML 中呈现的组件的数据来初始化他的组件。此外,组件应该能够修改现有数据以将更多项目添加到其列表中。

您可以使用渲染函数来做到这一点。

Vue.component("my-cp",{
  props:["list"],
  data(){
    return {
      internalList: this.list
    }
  },
  render(h){
    let workingList = []

    // Examine the default slot, and if there are any parse
    // them and add the data to the workingList
    if (this.$slots.default){
      for (node of this.$slots.default)
        // May want to check here if the node is a myCp2,
        // otherwise, grab the data
         workingList.push(node.componentOptions.propsData.myData)
    }

    // Add any items that came from the property/internal data
    workingList = workingList.concat(this.internalList)

    // Create a list of myCp2 vnodes with the correct data
    const list = workingList.map(n => h(myCp2, {props:{myData:n}}))

    // Create a button to add list items
    const btn = h("button", {on:{click:() => this.internalList.push({bar: true})}}, "Add")

    //Render
    return h("div", [list, btn])
  },
})

这是example

【讨论】:

  • 是的,但是安装后我将无法在列表中添加元素。目标是将 v-for 保留在列表中。该插槽仅用于初始化,但一旦安装,我希望通过将新元素推送到列表数组中来保持添加新元素的可能性。
  • @Nabab 您的意思是在某些情况下,您可能不会将list 作为属性,而是想从插槽的内容中对其进行初始化?
  • 就是这样
  • @Nabab 让我考虑一下。您可以使用this.$slots.default 访问插槽中的内容(如果它不是命名插槽)。从那里您可以查看节点,但我希望您最终会自己解析它。
  • @Nabab 我已经更新了答案。我认为这可以按您想要的方式工作。
猜你喜欢
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2018-08-25
相关资源
最近更新 更多