TypeScript 中的无渲染 Vue 组件 [英] Renderless Vue Component in TypeScript

查看:50
本文介绍了TypeScript 中的无渲染 Vue 组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 JavaScript 中有一个无渲染组件,我正在尝试将其转换为 TypeScript.我在 Vue.extend-ed 组件中声明 render 函数时遇到错误:

I have a renderless component in JavaScript that I am trying to convert to TypeScript. I'm running into errors declaring the render function in a Vue.extend-ed component:

(method) ComponentOptions<Vue, unknown, unknown, unknown, never[], Record<never, any>>.render?(createElement: CreateElement, hack: RenderContext<Record<never, any>>): VNode
  No overload matches this call.
  The last overload gave the following error.
  Argument of type '{ render(): void; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>'.
    Types of property 'render' are incompatible.
      Type '() => void' is not assignable to type '(createElement: CreateElement, hack: RenderContext<Record<string, any>>) => VNode'.
        Type 'void' is not assignable to type 'VNode'.ts(2769)
        vue.d.ts(90, 3): The last overload is declared here.

这是我在 TypeScript 中尝试做的一个例子:

This is an example of what I am trying to do in TypeScript:

import Vue from 'vue'

export default Vue.extend({
  render() { // error happens when I add this. I tried typing the render with :VNode
             // and returning this.$scopedSlots.default({}), but error still occurs
  }
})

我该如何解决这个问题?

How do I fix this?

推荐答案

render() 有这个签名:

render?(createElement: CreateElement, hack: RenderContext<Props>): VNode;

render() 声明的注意事项:

Notes for render() declaration:

  • hack 不需要在你的代码中声明
  • 在无渲染函数中不需要参数声明
  • 返回类型是VNode(即单个根节点),但Vue实际上接受VNode[]作为返回(这就是this.$scopedSlots.default() 返回)
  • hack does not need to be declared in your code
  • argument declarations are unnecessary in a renderless function
  • return type is VNode (i.e., a single root node), but Vue actually accepts VNode[] as a return (which is what this.$scopedSlots.default() returns)

方案一:指定返回类型为VNode,并返回一个包裹this.$scopedSlots.default()的单个节点:

Solution 1: Specify the return type as VNode, and return a single node that wraps this.$scopedSlots.default():

import Vue, { VNode, CreateElement } from 'vue'

export default Vue.extend({
  render(h: CreateElement): VNode {
    return h('div', this.$scopedSlots.default!({}))
  }
})

解决方案 2:this.$scopedSlots.default() 上使用 any 类型断言来解决类型错误:

Solution 2: Use any type assertion on this.$scopedSlots.default() to workaround the type error:

import Vue from 'vue'

export default Vue.extend({
  render() {
    // The container node is expected to provide a single root,
    // so it's okay to return `VNode[]` as any.
    return this.$scopedSlots.default!({}) as any
  }
})

这篇关于TypeScript 中的无渲染 Vue 组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆