当前位置: 首页 > 知识库问答 >
问题:

javascript - vue3 父级传给子组件render函数时的scopeId和父级不一致?

宇文和昶
2024-01-20

父级:

<template>  <comp :r="r" /></template><script>import { defineComponent, h, withCtx, getCurrentInstance } from 'vue'import Comp from './Comp.vue'export default defineComponent({  components: { Comp },  setup() {    const ins = getCurrentInstance()    return {      r: () => h('span', { class: 'span' }, '哈哈')      // r: withCtx(() => h('span', { class: 'span' }, '哈哈'), ins)    }  },})</script><style scoped>.span {  color: blue;}</style>

子组件:

<script>import { defineComponent, h } from 'vue'export default defineComponent({  name: 'Comp',  props: { r: Function },  setup(props) {    return () => h('div', { class: 'comp' }, props.r())  },})</script><style scoped>.comp {  color: red}</style>

如果使用withCtx(() => h('span', { class: 'span' }, '哈哈'), ins)是可以让spanscopeId和父级一致,但是这样必须在每个使用了子组件的父级里写一遍,太麻烦还容易漏,官方文档根本没写这东西

所以有没有一种方式,能通过修改子组件,父级不需要传其他乱七八糟的比如instance之类的给子组件,就能达到说子组件接收的render函数始终使用传入者的scopeId

共有2个答案

贝洲
2024-01-20

实在要在子组件做那就只能用非标方式,直接从vnode上拿值写入,
return () => h('div', { class: 'comp',[getCurrentInstance().parent.type.__scopeId]: '' }, props.r())
从命名上也知道这是个私有属性,最好是不要用

陈昂熙
2024-01-20

这是一个涉及Vue 3组件递归渲染的问题,其关键在于Vue的render函数在渲染子组件时并不会保留或使用其自身的scopeId

在你的例子中,父组件的r函数返回了一个span元素,这个元素被渲染到了子组件中。然而,由于这个span元素是在子组件的setup函数中创建的,所以它的scopeId是子组件的,而不是父组件的。

要解决这个问题,一种可能的解决方案是使用Vue的withCtx函数来创建一个具有正确scopeId的函数。然而,你提到这种方法需要在每个使用了子组件的父级里写一遍,这确实是一个问题。

另一种可能的解决方案是修改子组件,使其能够接收一个带有正确scopeId的函数,而不是在父组件中创建这个函数。这可以通过在子组件的props中添加一个新的prop来实现,这个prop接收一个函数,然后在子组件的setup函数中使用这个函数来创建需要渲染的元素。

下面是一个修改后的子组件示例:

<script>import { defineComponent, h } from 'vue'export default defineComponent({  name: 'Comp',  props: {     r: Function,     render: Function   },  setup(props) {    return () => h('div', { class: 'comp' }, props.render(props.r))  },})</script>

然后,在父组件中,你可以这样使用这个子组件:

<template>  <comp :r="r" :render="render" /></template><script>import { defineComponent, h } from 'vue'import Comp from './Comp.vue'export default defineComponent({  components: { Comp },  setup() {    return {      r: () => h('span', { class: 'span' }, '哈哈'),      render: (createNode) => createNode(() => '哈哈')    }  },})</script>

在这个修改后的例子中,父组件传递了一个名为render的prop给子组件。这个prop接收一个函数,然后在子组件中创建一个新的元素,这个新元素的scopeId与子组件的相同。这样就解决了你的问题。

 类似资料:
  • 问题内容: 我将PHP和mySQL与Idiorm结合使用。那可能不相关。 我的PHP数组 这是父母与子女之间的关系。 0是根父级。 示例:根父级0有孩子33,孩子33有孩子27,孩子27有孩子71。 如果需要解决此问题,可以更改此数组结构。 我的分层结果 像这样,但作为一个数组… 信息 深度未知,可以无限。我尝试了foreach,但可能不是这样。 我自己的想法 一些递归功能? 一些while循环?

  • 有一个父组件 A,上面有两个子组件,B 和 C。 在子组件 B 上有一个子组件 D,其中 D 里面有一个 textarea 在子组件 C 上有一个按钮,点击这个按钮获取 D 里面 textarea 的值。 我尝试的两个方案 方案一:可以通过直接操作 dom 来解决 方案二:通过 D 将 textarea 的值传递给 B,然后由 B 传给 A,再有 A 传给 C,但总是传不成功。 请问我的这个需求,

  • 问题内容: 我有两个组成部分: 第一个是父组件,它是通常的React组件。 第二个是孩子,它是功能组件。 我想将 Titles 的值(处于子状态)传递给父Component。这是我的 子组件 代码: 这是我的 父组件 : 这看起来很容易,但这是我第一次使用功能组件。你能帮我吗 ? 问题答案: React就是关于在组件树中向下流动的数据。如果您希望能够显示和/或修改彼此之间的共享状态,则应提升状态并

  • 问题内容: 我用这个文章为例(做出反应的方式),但它不是为我工作。请指出我的错误,因为我不明白怎么了。 这是我看到的错误: 未捕获的TypeError:this.props.onClick不是函数 这是我的代码: 提前致谢! 问题答案: 问题在于回调内部不引用React组件,因此是。 您可以通过将第二个参数传递给来显式设置值: 现在,回调 内部 的值与回调 外部 (即实例)的值相同。 这与Reac

  • 我有两个实体使用Spring和Hibernate

  • 问题是要确定子数据的总和是否等于父数据。如果是,返回真,否则返回假。 下面是我的代码,在提交时出现错误。我知道这是一个简单的问题,但在编写了条件之后,我很难通过遍历所有左右节点来递归检查二叉树中每个节点的和条件。 请指导我,因为我哪里做错了。