一 概述

1 现在,在 Vue 3 中,所有的函数式组件都是用普通函数创建的。换句话说,不需要定义 { functional: true } 组件选项。

2 它们将接收两个参数:props 和 contextcontext 参数是一个对象,包含组件的 attrsslots 和 emit等三个属性。

3 此外,h 函数现在是全局导入的,而不是在 render 函数中隐式提供。

4 在 3.x 中,有状态组件和函数式组件之间的性能差异已经大大减少,并且在大多数用例中是微不足道的。

二 语法对比

<!-- MyComponent.vue文件 -->
<script>
/**
 * Vue 2.x 函数式组件
 */
export default {
  functional: true,
  name: "MyComponent",
  props: {
    msg: String,
  },
  render: function (createElement, context) {
    return createElement("button", { class: "btn" }, "按钮");
  },
};
</script>
<!-- MyComponent.vue文件 -->
<script>
import { h } from "vue";
/**
 * Vue 3.x 函数式组件
 */
function MyComponent(props, ctx) {
  return h(
    "div",
    {
      id: "box",
      class: "box",
      style: {
        fontWeight: "bold",
      },
    },
    [props.name]
  );
}

Fruit.props = {
  name: String,
};

export default Fruit;
</script>

三 新特性

1 普通函数既是函数组件的定义,也是函数组件的渲染函数

// renderComponentRoot方法部分源码

const render = Component as FunctionalComponent // 将函数组件的定义,用作函数组件的渲染函数

2 函数式组件有组件实例

但只是在框架内部使用,不会传入渲染函数中。

// renderComponentRoot方法部分源码

// 执行函数组件的渲染函数
  render.length > 1
    ? render( // 有2个形参
        props, 
        __DEV__ 
          ? {
              get attrs() {
                markAttrsAccessed()
                return attrs
              },
              slots,
              emit
            }
          : { attrs, slots, emit }
      )
    : render( // 有1个形参
      props,  
      null as any /* we know it doesn't need it */ 
    ) 

3 不能使用普通生命周期钩子

import { h, onMounted } from "vue";

function MyComponent(props, ctx) {
  // 无效:框架执行injectHook方法注册生命周期钩子时,会在控制台警告只能在setup方法中使用
  onMounted(() => {
    console.log("挂载完成");
  });
  return h(
    "div",
    {
      id: "box",
      class: "box",
      style: {
        fontWeight: "bold",
      },
    },
    [props.name]
  );
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐