使用h函数渲染transition组件,导致钩子不生效

在vue3的setup语法糖中,使用h函数渲染transition组件,导致钩子不生效.
有大佬知道怎么处理吗?
代码如下:

<template>
  <zy-transiton>
    <slot />
  </zy-transiton>
</template>

<script lang="ts" setup>
import { h } from "vue";

const handleEnter = (el) => {
  console.log(123); // 没有输出,方法没执行
  console.log(el); // 没有输出,方法没执行
};
const handleLeave = (el) => {
  console.log(el); // 没有输出,方法没执行
};

const zyTransiton = () => {
  return h(
    "transition",
    {
      onEnter: handleEnter,
      onLeave: (e) => handleLeave(e),
    }
  );
};
阅读 4.9k
2 个回答

使用渲染函数时,Vue 的内置组件需要直接传入组件对象本身:

import { h, Transition } from 'vue'

h(Transition, { /* ... */ })

多看看 官方文档

—————————————— 2020.05.13 编辑 ——————————————

主要问题是 slots 用法不对,改成下面的即可:

const slots = useSlots();
// const defaultSlot = slots.default(); 去掉

const CollapseTransition = () => {
  return h(
    Transition,
    {
      onBeforeEnter: handleBeforeEnter,
      onEnter: handleEnter,
      onAfterEnter: handleAfterEnter,
      onBeforeLeave: handleBeforeLeave,
      onLeave: handleLeave,
      onAfterLeave: handleAfterLeave,
    },
    {
      // 应该在函数里在进行判断的渲染
      default: () => slots.default && slots.default(),
    }
  );
};

还有你这个项目的几个问题:

  • 你已经安装了 sass,请把 node-sass 清除掉,全面用 sass(这是官方推荐的实现,使用 dart 编写,特性更新和问题修复是最快的)
  • 你没有用 webpack 的话 sass-loader 是不需要的
  • 样式预处理这些依赖应该用 -D 的方式去安装,即应该在 devDependencies 下,而不是 dependencies

我引入了Transition组件本省,但它的钩子函数仍未执行。大佬可以解答一下吗?
是我文档看的不仔细吗?我是在没有找到解决办法。。。

<template>
  <CollapseTransition />
</template>

<script lang="ts" setup>
import { h, useSlots, Transition } from "vue";

const slots = useSlots();
const defaultSlot = slots.default();

const handleBeforeEnter = (el) => {
  if (!el.dataset) el.dataset = {};

  el.dataset.oldPaddingTop = el.style.paddingTop;
  el.dataset.oldPaddingBottom = el.style.paddingBottom;

  el.style.maxHeight = 0;
  el.style.paddingTop = 0;
  el.style.paddingBottom = 0;
};

const handleEnter = (el, done) => {
           ...
};

const handleAfterEnter = (el) => {
           ...
};

const handleBeforeLeave = (el) => {
           ...
};

const handleLeave = (el) => {
           ...
};
const handleAfterLeave = (el) => {
           ...
};

const CollapseTransition = () => {
  return h(
    Transition,
    {
      onBeforeEnter: handleBeforeEnter,
      onEnter: handleEnter,
      onAfterEnter: handleAfterEnter,
      onBeforeLeave: handleBeforeLeave,
      onLeave: handleLeave,
      onAfterLeave: handleAfterLeave,
    },
    {
      default: () => [defaultSlot],
    }
  );
};
</script>

<style scoped>
</style>

我尝试使用element的组件,却可以执行。我不清楚为什么

<template>
  <transition v-on="on">
    <slot />
  </transition>
</template>
<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "ElCollapseTransition",
  setup() {
    return {
      on: {
        beforeEnter(el) {
          if (!el.dataset) el.dataset = {};

          el.dataset.oldPaddingTop = el.style.paddingTop;
          el.dataset.oldPaddingBottom = el.style.paddingBottom;

          el.style.maxHeight = 0;
          el.style.paddingTop = 0;
          el.style.paddingBottom = 0;
        },

        enter(el) {
           ...
        },

        afterEnter(el) {
           ...
        },

        beforeLeave(el) {
           ...
        },

        leave(el) {
           ...
        },

        afterLeave(el) {
           ...
        },
      },
    };
  },
});
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题