vue 函数式组件的使用

本文介绍了函数式组件的概念,它是无状态和无实例的,通过JavaScript函数定义渲染逻辑,适用于复杂页面的组装。文章通过实例展示了如何在Vue中使用和场景应用,以及在大型项目中,尤其是使用jsx时的优势。
摘要由CSDN通过智能技术生成

函数式组件是什么?

官方解释:使组件无状态 (没有 data) 和无实例 (没有 this 上下文)。他们用一个简单的 render 函数返回虚拟节点使它们渲染的代价更小。 简单来说就是,以javaScript函数来定义组件的渲染函数,函数式组件没有模板、组件没有状态(data,存储数据的能力,类似react的无状态组件)、生命周期,它们非常轻量级,并且易于创建和使用。常用于组装复杂页面或组件(深层次组件颗粒化,使用的较好方案之一)。

使用场景

初步使用 函数式组件

<template>
  <div class="VNode">
    <VNode :age='30' @up="up"/>
  </div>
</template>
<script>
export default {
  name: "App",
  components: {
    VNode: {
      functional: true,
      render(h,ctx) {
        console.log(ctx)
        return h("div", {
          on:{
            click:()=>ctx.data.on.up(ctx.props.age+'老了')
          }
        }, ctx.props.age);
      },
    },
  },
  data() {
    return {};
  },
  methods:{
    up(value){
      console.log('父组件接收子组件的值', value);
    }
  }
};
</script>

场景1:
 

全局很多地方需要具备“根据传入的年龄去查询是否需要养老”的组件A:

全局很多地方需要具备“根据传入的身份证号判断是否当前用户是否已缴纳养老保险,未缴纳做出提示”的组件B:
home.vue:

<template>
  <div class="HomeIndex">
    <!-- 传入年龄判断是否需要养老 -->
    <VNode :age="29" :render="ageRender" />
    <!-- 传入身份证号码计算建议缴纳年限,和建议缴纳地等 -->
    <VNode iDCard="3623211" :render="idRender" />
  </div>
</template>
<script>
import { ageRender, idRender } from "./component";
export default {
  name: "HomeIndex",
  components: {
    VNode: {
      functional: true,
      render(h, ctx) {
        console.log(ctx);
        return ctx.props.render(h, ctx);
      },
    },
  },
  data() {
    return {
      ageRender,
      idRender,
    };
  },
};
</script>

component.js

/**
 * 我是一个创建 标签的函数,我支持很多不同样式的标签
 */
export function creatLabelValue(h, { label, value }) {
  return h("div", {}, [h("span", {}, label + ":"), h("span", {}, value)]);
}
/**
 * 我是一个很花哨的组件 我是组件 A
 */
export function ageRender(h, ctx) {
  const age = ctx.props.age;
  const masg = +age > 65 ? "需要养老" : "不需要养老";
  return h("div", {}, creatLabelValue(h,{label:age,vlaue:masg}));
}
/**
 * 我是一个功能很多的组件 我是组件 B
 */
export function idRender(h, ctx) {
  const iDCard = ctx.props.iDCard;
  /** 经过一系列的复杂判断规则得出结果 */
  return h("div", {}, [
    creatLabelValue(h, { label: "身份证", value: iDCard }),
    creatLabelValue(h, { label: "年龄", value: "28" }),
    creatLabelValue(h, { label: "性别", value: "男" }),
    creatLabelValue(h, { label: "建议缴纳年限", value: "30年" }),
    creatLabelValue(h, { label: "距退休还剩", value: "37年" }),
  ]);
}

场景2:

使用jsx,完成上面的案例: HomeJsx.jsx

import { ageRender, idRender } from "./componentJsx";
export default {
    name:"HomeJsx",
    render(){
        return <div class="HomeJsx">
            {ageRender(29)}
            {idRender('3623211')}
        </div>
    }
}

componentJsx.jsx

/**
 * 我是一个创建 标签的函数,我支持很多不同样式的标签
 */
export function creatLabelValue({ label, value }) {
    // return h("div", {}, [h("span", {}, label + ":"), h("span", {}, value)]);

  return (
    <div>
      <span>{label}</span>
      <span>{value}</span>
    </div>
  );
}
/**
 * 我是一个很花哨的组件 我是组件 A
 */
export function ageRender(age) {
  const masg = +age > 65 ? "需要养老" : "不需要养老";
  //   return h("div", {}, creatLabelValue(h, { label: age, vlaue: masg }));
  return creatLabelValue({ label: age, vlaue: masg });
}
/**
 * 我是一个功能很多的组件 我是组件 B
 */
export function idRender(iDCard) {
  /** 经过一系列的复杂判断规则得出结果 */
  //   return h("div", {}, [
  //     creatLabelValue(h, { label: "身份证", value: iDCard }),
  //     creatLabelValue(h, { label: "年龄", value: "28" }),
  //     creatLabelValue(h, { label: "性别", value: "男" }),
  //     creatLabelValue(h, { label: "建议缴纳年限", value: "30年" }),
  //     creatLabelValue(h, { label: "距退休还剩", value: "37年" }),
  //   ]);
  return (
    <div>
      {[
        creatLabelValue({ label: "身份证", value: iDCard }),
        creatLabelValue({ label: "年龄", value: "28" }),
        creatLabelValue({ label: "性别", value: "男" }),
        creatLabelValue({ label: "建议缴纳年限", value: "30年" }),
        creatLabelValue({ label: "距退休还剩", value: "37年" }),
      ]}
    </div>
  );
}

ps:像 componentJsx.jsx 直接这样写会报错。需要下载依赖 "@vue/babel-preset-jsx" 并在babel.config.js 加入

module.exports = {
  presets: [
    [
      "@vue/babel-preset-jsx",
      {
        vModel: false,
        compositionAPI: true,
      },
    ],
  ],
};

总结:

正常定义组件,对于大型项目或颗粒化做的比较好的项目而言其实是很损耗性能的。每个.vue组件都需要通过一系列复杂的运算后得出。而函数式组件渲染代价极小,它仅仅只是返回了渲染逻辑的一个方法而已。对于复杂项目,深度颗粒化都比较友善。使用jsx语法,写函数式组件极其方便,故而大型项目使用jsx会比较好。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值