做为一名前端开发人员,掌握vue/react/angular等框架已经是必不可少的技能了,我们都知道,vue或react等MVVM框架提倡组件化开发,这样一方面可以提高组件复用性和可扩展性,另一方面也带来了项目开发的灵活性和可维护,方便多人开发协作.接下来文章将介绍如何使用react,开发一个自定义json编辑器组件.我们这里使用了jsoneditor这个第三方库,官方地址: jsoneditor 通过实现一个json在线编辑器,来学习如何一步步封装自己的组件(不限于react,vue,原理类似).
细河ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
你将学到:
在介绍组件设计思路之前,有必要介绍一下著名的SOLID原则.
SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁提出的面向对象编程和面向对象设计的五个基本原则。利用这些原则,程序员能更容易和高效的开发一个可维护和扩展的系统。SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。
掌握好这5个原则将有利于我们开发出更优秀的组件,请默默记住.接下来我们来看看json编辑器的设计思路.
如上所示, 和任何一个输入框一样, 参考antd组件设计方式并兼容antd的form表单, 我们提供了onChange方法.(具体细节下文会详细介绍)
首先利用jsoneditor渲染的基本样式以及API,我们能实现一个基本可用的json编辑器,然后通过对外暴露的json和onChange属性进行数据双向绑定, 通过onError来监控异常或者输入的错误, 通过themeBgColor来修改默认的主题色,通过这几个接口,我们便能完全掌握一个组件的运行情况.
接下来我们就正式开始我们的正文.由于本文的组件是基于react实现的,但是用在vue,angular上,基本模式同样适用.关键就是掌握好不同框架的生命周期.
在学习实现json编辑器组件之前,我们有必要了解一下jsoneditor这个第三方组件的用法与api.
安装
我们先执行npm install安装我们的组件
- npm install jsoneditor
其次手动引入样式文件
这样,我们就能使用它的api了:
所以你可能看到如下界面:
为了能实现实时预览和编辑,光这样还远远不够,我们还需要进行额外的处理.我们需要用到jsoneditor其他的api和技巧.
基于以上谈论,我们很容易将编辑器封装成react组件, 我们只需要在componentDidMount生命周期里初始化实例即可.react代码可能是这样的:
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import 'jsoneditor/dist/jsoneditor.css'
- class JsonEditor extends PureComponent {
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true,
- onChange: this.onChange,
- onValidationError: this.onError
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- }
- componentWillUnmount () {
- if (this.jsoneditor) {
- this.jsoneditor.destroy()
- }
- }
- render() {
- return
this.container = elem} />- }
- }
- export default JsonEditor
至于options里的选项, 我们可以参考jsoneditor的API文档,里面写的很详细, 通过以上代码,我们便可以实现一个基本的react版的json编辑器组件.接下来我们来按照设计思路一步步实现可实时预览的json编辑器组件.
1.实现预览和编辑视图
其实这一点很好实现,我们只需要实例化2个编辑器实例,一个用于预览,一个用于编辑就好了.
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import 'jsoneditor/dist/jsoneditor.css'
- class JsonEditor extends PureComponent {
- onChange = () => {
- let value = this.jsoneditor.get()
- this.viewJsoneditor.set(value)
- }
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- initViewJsonEditor = () => {
- const options = {
- mode: 'view'
- };
- this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
- this.viewJsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- this.initViewJsonEditor()
- }
- componentDidUpdate() {
- if(this.jsoneditor) {
- this.jsoneditor.update(this.props.value)
- this.viewJsoneditor.update(this.props.value)
- }
- }
- render() {
- return (
this.container = elem} /> this.viewContainer = elem} />- );
- }
- }
- export default JsonEditor
这样,我们便能实现一个初步的可实时预览的编辑器.可能效果长这样:
接近于成熟版,但是还有很多细节要处理.
2.对外暴露属性和方法以支持不同场景的需要
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import 'jsoneditor/dist/jsoneditor.css'
- class JsonEditor extends PureComponent {
- // 监听输入值的变化
- onChange = () => {
- let value = this.jsoneditor.get()
- this.props.onChange && this.props.onChange(value)
- this.viewJsoneditor.set(value)
- }
- // 对外暴露获取编辑器的json数据
- getJson = () => {
- this.props.getJson && this.props.getJson(this.jsoneditor.get())
- }
- // 对外提交错误信息
- onError = (errArr) => {
- this.props.onError && this.props.onError(errArr)
- }
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true,
- onChange: this.onChange,
- onValidationError: this.onError
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- initViewJsonEditor = () => {
- const options = {
- mode: 'view'
- };
- this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
- this.viewJsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- this.initViewJsonEditor()
- // 设置主题色
- this.container.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.container.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- this.viewContainer.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.viewContainer.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- }
- componentDidUpdate() {
- if(this.jsoneditor) {
- this.jsoneditor.update(this.props.json)
- this.viewJsoneditor.update(this.props.json)
- }
- }
- render() {
- return (
this.container = elem} /> this.viewContainer = elem} />- );
- }
- }
- export default JsonEditor
通过以上的过程,我们已经完成一大半工作了,剩下的细节和优化工作,比如组件卸载时如何卸载实例, 对组件进行类型检测等,我们继续完成以上问题.
3.使用PropTypes进行类型检测以及在组件卸载时清除实例
类型检测时react内部支持的,安装react的时候会自动帮我们安装PropTypes,具体用法可参考官网地址propTypes文档,其次我们会在react的componentWillUnmount生命周期中清除编辑器的实例以释放内存.完整代码如下:
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import PropTypes from 'prop-types'
- import 'jsoneditor/dist/jsoneditor.css'
- /**
- * JsonEditor
- * @param {object} json 用于绑定的json数据
- * @param {func} onChange 变化时的回调
- * @param {func} getJson 为外部提供回去json的方法
- * @param {func} onError 为外部提供json格式错误的回调
- * @param {string} themeBgColor 为外部暴露修改主题色
- */
- class JsonEditor extends PureComponent {
- onChange = () => {
- let value = this.jsoneditor.get()
- this.props.onChange && this.props.onChange(value)
- this.viewJsoneditor.set(value)
- }
- getJson = () => {
- this.props.getJson && this.props.getJson(this.jsoneditor.get())
- }
- onError = (errArr) => {
- this.props.onError && this.props.onError(errArr)
- }
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true,
- onChange: this.onChange,
- onValidationError: this.onError
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- initViewJsonEditor = () => {
- const options = {
- mode: 'view'
- };
- this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
- this.viewJsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- this.initViewJsonEditor()
- // 设置主题色
- this.container.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.container.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- this.viewContainer.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.viewContainer.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- }
- componentWillUnmount () {
- if (this.jsoneditor) {
- this.jsoneditor.destroy()
- this.viewJsoneditor.destroy()
- }
- }
- componentDidUpdate() {
- if(this.jsoneditor) {
- this.jsoneditor.update(this.props.json)
- this.viewJsoneditor.update(this.props.json)
- }
- }
- render() {
- return (
this.container = elem} /> this.viewContainer = elem} />- );
- }
- }
- JsonEditor.propTypes = {
- json: PropTypes.object,
- onChange: PropTypes.func,
- getJson: PropTypes.func,
- onError: PropTypes.func,
- themeBgColor: PropTypes.string
- }
- export default JsonEditor
由于组件严格遵守开闭原则,所以我们可以提供更加定制的功能在我们的json编辑器中,已实现不同项目的需求.对于组件开发的健壮性探讨,除了使用propTypes外还可以基于typescript开发,这样适合团队开发组件库或者复杂项目组件的追溯和查错.最终效果如下:
笔者已经将实现过的组件发布到npm上了,大家如果感兴趣可以直接用npm安装后使用,方式如下:
- npm i @alex_xu/xui
- // 导入xui
- import {
- Button,
- Skeleton,
- Empty,
- Progress,
- Tag,
- Switch,
- Drawer,
- Badge,
- Alert
- } from '@alex_xu/xui'
该组件库支持按需导入,我们只需要在项目里配置babel-plugin-import即可,具体配置如下:
- // .babelrc
- "plugins": [
- ["import", { "libraryName": "@alex_xu/xui", "style": true }]
- ]
npm库截图如下:
最后
本文转自《趣谈前端》如需转载请联系作者授权。
网站标题:前端进阶:二次封装一个可实时预览的json编辑器
分享URL:http://www.csdahua.cn/qtweb/news25/40475.html网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网
- windows审计日志在哪?(windows审计日志)
- 使用美国服务器进行外贸建站的好处有哪些
- 提醒:请大家谨慎购买LunarPages(lunar需要正版吗)
- 快速配置Redis多数据库(redis配置多数据库)
- 云服务器绑定的域名可以直接解析到上吗
- 什么是大带宽?美国大带宽服务器租赁推荐?(美国大带宽服务器租用)
- 云主机怎么安装系统「云主机怎么安装系统教程」
- 文件服务器有哪些?什么是文件服务器
- :Linux系统:哪一个最适合你?(linux系统那个好)
- 浏览器无法正常打开出现下图提示进入主机控制面板
- Linux下的消息队列:高效数据传输的利器!(linux消息队列)
- vps好用吗?(vps很卡是怎么回事啊)
- php链接传递参数
- vps本地测速的方法是什么
- 什么是vlan