首页 > 解决方案 > 有什么方法可以将范围插槽从模板缩短到带有道具的组件?

问题描述

我在组件中使用命名和作用域插槽。

以下工作完美无缺:

<template #name="s">
    <table-cell :value="s.item.name" />
</template>

但我希望这样的事情也能奏效:

<table-cell #name="s" :value="s.item.name" />

它没有给我任何编译错误,但也没有呈现。运行时抛出错误“s”未定义。

这样的事情可能吗?

标签: vue.js

解决方案


属性存在于父函数作用域中,但作用域插槽的子元素在新函数作用域中传递参数。我不知道答案,但也很好奇,所以尝试了 Vue 的模板编译来理解。

模板:

<table-row>
  <table-cell #name="s" :value="s.item.name">{{ s.item.name }}</table-cell>
</table-row>

编译渲染函数:

function anonymous() {
  with (this) {
    return _c(
      "table-row",
      [
        _c("table-cell", {
          attrs: { value: s.item.name }, // attributes use parent scoope
          scopedSlots: _u([
            {
              key: "name",
              fn: function (s) {         // children get the new function scope
                return [_v(_s(s.item.name))];
              },
            },
          ]),
        }),
      ],
      1
    );
  }
}

如果您使用包装在 a 中的模板<template>

<table-row>
  <template #name="s">
    <table-cell :value="s.item.name">{{ s.item.name }}</table-cell>
  </template>
</table-row>

编译渲染函数:

function anonymous() {
  with (this) {
    return _c("table-row", {
      scopedSlots: _u([
        {
          key: "name",
          fn: function (s) {
            return [
              // entire table-cell is rendered inside slot scope
              _c("table-cell", { attrs: { value: s.item.name } }, [
                _v(_s(s.item.name)),
              ]),
            ];
          },
        },
      ]),
    });
  }
}

推荐阅读