早日暴富1 2024-07-03 15:29 采纳率: 100%
浏览 4
已结题

vue2+ant-design-vue1.7升级vue3+ant-design-vue3遇到渲染函数无法渲染出Vnode


import { render, defineComponent, h } from 'vue'
import './BasicLayout.less'

import PropTypes from 'ant-design-vue/es/_util/vue-types'

import { Layout } from 'ant-design-vue'
import { ContainerQuery } from 'vue-container-query'
import { SiderMenuWrapper, GlobalFooter } from './components'
import { getComponentFromProp, isFun } from './utils/util'
import { SiderMenuProps } from './components/SiderMenu'
import HeaderView, { HeaderViewProps } from './Header'
import WrapContent from './WrapContent'
import ConfigProvider from './components/ConfigProvider'

export const BasicLayoutProps = {
  ...SiderMenuProps,
  ...HeaderViewProps,
  locale: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]).def('en-US'),
  breadcrumbRender: PropTypes.func,
  disableMobile: PropTypes.bool.def(false),
  mediaQuery: PropTypes.object.def({}),
  handleMediaQuery: PropTypes.func,
  footerRender: PropTypes.func
}
console.log('com', ConfigProvider)
const MediaQueryEnum = {
  'screen-xs': {
    maxWidth: 575
  },
  'screen-sm': {
    minWidth: 576,
    maxWidth: 767
  },
  'screen-md': {
    minWidth: 768,
    maxWidth: 991
  },
  'screen-lg': {
    minWidth: 992,
    maxWidth: 1199
  },
  'screen-xl': {
    minWidth: 1200,
    maxWidth: 1599
  },
  'screen-xxl': {
    minWidth: 1600
  }
}

const getPaddingLeft = (hasLeftPadding, collapsed = undefined, siderWidth) => {
  if (hasLeftPadding) {
    return collapsed ? 80 : siderWidth
  }
  return 0
}

const headerRender = (h, props) => {
  console.log('header', props)
  if (props.headerRender === false) {
    return null
  }
  return <HeaderView {...{ props }} />
}

const defaultI18nRender = (key) => key

const BasicLayout = defineComponent({
  name: 'BasicLayout',
  functional: true,
  props: BasicLayoutProps,
  render(content) {
    const { $props, $slots, $attrs } = content
    console.log('content', content)
    const {
      layout,
      // theme,
      isMobile,
      collapsed,
      siderWidth,
      mediaQuery,
      handleMediaQuery,
      handleCollapse,
      contentWidth,
      fixSiderbar,
      i18nRender = defaultI18nRender
    } = $props

    const footerRender = getComponentFromProp(content, 'footerRender')
    const rightContentRender = getComponentFromProp(content, 'rightContentRender')
    const collapsedButtonRender = getComponentFromProp(content, 'collapsedButtonRender')
    const menuHeaderRender = getComponentFromProp(content, 'menuHeaderRender')
    const breadcrumbRender = getComponentFromProp(content, 'breadcrumbRender')
    console.log('footer', footerRender(content))
    const isTopMenu = layout === 'topmenu'
    const hasSiderMenu = !isTopMenu
    // If it is a fix menu, calculate padding
    // don't need padding in phone mode
    const hasLeftPadding = fixSiderbar && !isTopMenu && !isMobile
    const cdProps = {
      ...$props,
      siderWidth,
      hasSiderMenu,
      footerRender,
      menuHeaderRender,
      rightContentRender,
      collapsedButtonRender,
      breadcrumbRender
    }

    return () =>
      h(
        ConfigProvider,
        {
          i18nRender,
          contentWidth,
          breadcrumbRender,
          ...$attrs
        },
        [
          h(ContainerQuery, {
            query: MediaQueryEnum,
            onChange: handleMediaQuery
          }, [
            h(Layout, {
              class: {
                'ant-pro-basicLayout': true,
                'ant-pro-topmenu': isTopMenu,
                ...mediaQuery
              }
            }, [
              // 顶部导航栏
              headerRender({
                ...cdProps,
                mode: 'horizontal'
              }),
              // 左侧菜单栏
              h(SiderMenuWrapper, {
                ...{props: cdProps},
                collapsed:collapsed,
                onCollapse: handleCollapse
              }),
              // 右侧容器
              h(Layout, {
                class: [layout],
                style: {
                  paddingLeft: hasSiderMenu
                    ? `${getPaddingLeft(!!hasLeftPadding, collapsed, siderWidth)}px`
                    : undefined,
                  minHeight: '100vh'
                }
              }, [
                // 内容区
                h(WrapContent, {
                  class: 'ant-pro-basicLayout-content',
                  contentWidth: contentWidth
                }, $slots.default()),
                // 底部栏
                h(Layout.Footer, [
                  // 使用 footerRender 函数
                  footerRender && (
                    isFun(footerRender) && footerRender(content) || footerRender
                  )
                ])
              ])
            ])
          ])
        ]
      );
  }
})
console.log('node',BasicLayout)
export default BasicLayout

content值

img

img

请教上述基于vue3+ant-design-vue2无法渲染,渲染出来是text

  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2024-07-03 15:45
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    在 Vue 3 中,render 函数的用法和 Vue 2 有一些不同。Vue 3 引入了 Composition API,但 render 函数的基本用法仍然相似。下面是针对你提出的问题的一些解释:

    1. h函数和render函数的用法:在 Vue 3 中,h 函数用于创建虚拟 DOM 节点,render 函数是一个返回 VNode 的函数。在 Vue 3 中,render 函数的参数是一个对象,包含 propsslotsattrs 等属性。

    2. BasicLayout组件的props定义和使用BasicLayoutProps 是一个对象,它定义了 BasicLayout 组件可以接受的属性。这些属性包括从 SiderMenuPropsHeaderViewProps 继承的属性,以及其他自定义属性如 localebreadcrumbRender 等。

    3. ConfigProvider组件的配置和使用ConfigProvider 是 ant-design-vue 中的一个组件,用于全局配置国际化、主题等。在 Vue 3 中,你可以通过传递一个对象到 ConfigProvider 来设置这些配置。

    4. ContainerQuery组件的媒体查询功能ContainerQuery 组件用于响应式设计,它允许你根据容器的大小来改变组件的样式或行为。

    5. Layout组件的布局样式和类名设置Layout 是 ant-design-vue 中的一个布局组件,它包含 HeaderSiderContentFooter。你可以通过传递 class 属性来设置布局的样式和类名。

    6. SiderMenuWrapper组件的菜单栏渲染SiderMenuWrapper 组件用于渲染侧边菜单栏。它接收 props,如 collapsedonCollapse,来控制菜单的展开和收起。

    7. WrapContent组件的内容区渲染WrapContent 组件用于包裹主要内容区域,你可以通过传递 classcontentWidth 属性来自定义内容区的样式。

    8. GlobalFooter组件的底部栏渲染GlobalFooter 组件用于渲染页面底部的版权信息或其他内容。在 Vue 3 中,你可以通过 footerRender 函数来自定义底部栏的内容。

    9. 函数getPaddingLeft的逻辑和使用场景:这个函数根据是否有侧边菜单、菜单是否收起以及侧边菜单的宽度来计算左侧的内边距。这通常用于确保内容区域与侧边菜单对齐。

    10. 渲染函数中footerRender函数的使用footerRender 可以是一个函数,用于自定义底部栏的内容。如果 footerRender 是一个函数,你可以在渲染时调用它来获取底部栏的内容。

    关于你提供的两张图片,由于我无法直接查看图片内容,我建议你检查图片中是否包含了组件的状态或属性的错误信息,这可能会帮助你诊断问题。如果图片中包含了错误或警告信息,请将这些信息提供给我,我可以帮你进一步分析问题。

    至于参考链接,由于你的问题主要涉及代码层面的解释,我暂时没有特定的链接推荐。如果你需要关于 Vue 3 或 ant-design-vue 的更多信息,你可以访问它们的官方文档:

    希望这些信息对你有所帮助!如果你有更具体的问题或需要进一步的帮助,请随时告诉我。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月12日
  • 已采纳回答 7月4日
  • 创建了问题 7月3日

悬赏问题

  • ¥100 nuxt、uniapp、ruoyi-vue 相关发布问题
  • ¥30 关于#测试工具#的问题:测试ai翻唱
  • ¥15 浮窗和全屏应用同时存在,全屏应用输入法无法弹出
  • ¥100 matlab2009 32位一直初始化
  • ¥15 Expected type 'str | PathLike[str]…… bytes' instead
  • ¥15 为什么在iis上部署网站,服务器可以访问,但是本地电脑访问不了
  • ¥15 三极管电路求解,已知电阻电压和三级关放大倍数
  • ¥15 ADS时域 连续相位观察方法
  • ¥15 Opencv配置出错
  • ¥15 关于模型导入UNITY的.FBX: Check external application preferences.警告。