wp自定义帖子没标签_如何在 React 里自定义标签和属性?

28a592f0e3cb1e1418c38f9136f7503e.png
日常开发中通常会有一些需求,需要定义一些全局通用的组件,在 Vue 里是有这样的功能,但是在 React 里,没有见过有类似的做法,通常都是在需要的时候引入组件,原则上在 Jsx 里只允许 html 的文本标签以及 function 类型的标签,本文的做法只做参考

背景

最近在考虑做国际化,但是系统构建之初,产品并没有做国际化的计划,系统开发上线以后,又有了国际化的需求,但是系统已经上线,这时候在去用 react-i18n 之类的方案太重了,所有的页面、组件都要引用这个库,需要国际化的地方都需要修改,同时要维护语言的映射文件,工作量太大了,所有考虑一种更好的方案,思考如何能无侵入的实现国际化,这里的构建自定义标签的目的是希望通过标签收集系统文字。

示例代码:

render(){
    return (
        <div>
            <local>需要翻译的文字</local>
            <span translate="yes">需要翻译的文字</span>
        </div>
    )
}

所有 local 标签或者加了 translate="yes" 的标签里的文字都需要被翻译,translate是 HTML5 的新属性,这里借用它。

自定义标签有哪些方案

编译期转换

一般通过编译期转换是可以做到的,但是需要开发相关 webpack loader ,调整生成的代码,这么做比较麻烦。

运行期实现

运行期做的话,可以在 render 里拿到虚拟DOM子节点,遍历,找到自定义的标签,然后特殊处理,返回新的虚拟 DOM,之前做了一个表单的方案,就是用这种方案来做的。

另一种做法,最近想到的,也是本文的重点,就是重写 React.createElement,重写 React.createElement 这个操作在某些场景还是挺有用的,

这些操作在 React 开发下都是非常规操作,让代码看起来有点儿怪,但是用起来还是比较香的。

自定义标签

参考实现:

function createTag(React, tags: ITags = {}) {
    if (!tags) {
        return;
    }
    const createElement = React.createElement;
    React.createElement = function (type, props, ...children) {
        if (tags[type]) {
            return createElement(tags[type], props, ...children);
        }
        return createElement(type, props, ...children);
    }
}

在应用的入口处使用:

import React, { Component } from 'react';

const Local=(props)=>{
    // 各种操作
    return props.children;
}

createTag(React,{
    'local':Local
})

这样,就可以在应用的任何地方使用 local 标签了,比如可以自定义一个 loading 标签。

这里不仅是加了一个文本标签,同时也接管里这个标签的内部实现逻辑,也可以有自己的状态,和下面的代码还是有区别的,下面的代码是动态修改 type 参数。

const Wrap = ({ tagName, content }) => { 
   const Tag = `${tagName}`     // variable name must begin with capital letters
   return <Tag>{content}</Tag>
}

自定义属性

这里是对虚拟DOM做了过滤,如果有对应的属性,那么执行回调,做相关的操作。

function createAttribute(React, attribute, callback) {
    if (!attribute) {
        return;
    }
    const createElement = React.createElement;
    React.createElement = function (type, props, ...children) {
        if (props && typeof props[attribute] !== 'undefined') {
            return callback(type, props, ...children);
        }
        return createElement(type, props, ...children);
    }
}

使用:

import React, { Component } from 'react';

createAttribute(React,'translate',(type,props,children)=>{
    // 各种操作
    return (
        <span>
            {children}
        </span>
    )
})

这样,应用里所有加了 translate 属性标签,都会被收集到,返回的内容就可以自定义了。

看起来挺有意思吧。。。

总结

本文通过重写 React.createElement 实现全局的标签和属性定义,某些场景下是挺有意义的,挺有意思,在这分享一下。


补一条招聘信息,团队正在招人,我们是58集团招聘事业部前端团队,主要是做招聘行业的sass系统,内部也有些有意思的项目,有意向的话可以私信我或发简历到 lihongyin@58.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值